method

bun.SQL.unsafe

unsafe<T = any>(
string: string,
values?: any[] | Record<string, any>
): Query<T>;

Executes any query string as-is. This can lead to SQL injection if the string contains untrusted input.

The string takes the database's own placeholders: $1 on PostgreSQL, ? on MySQL, either on SQLite. Pass values as an array, which Bun copies in the call. Without values, the string can hold several statements.

sql.unsafe can be nested inside a safe sql expression, for example when only part of the query is unsafe. Bun adds the nested text as written. On PostgreSQL, a nested sql.unsafe that has values cannot follow other parameters, because $1 in its text is the first parameter of the whole query: such a query rejects with a SyntaxError.

With the SQLite adapter, values may also be an object of named parameters (:name, $name, or @name placeholders). A key works with or without the prefix. This form does not work in a nested sql.unsafe.

const result = await sql.unsafe(`select ${danger} from users where id = ${dragons}`)
const row = await sql.unsafe("select * from users where id = :id", { id: 1 })