Raw SQL and Parameters
Raw()
Raw wraps a literal string that is emitted into the
generated SQL verbatim — no escaping, no quoting, no validation. Use it for expressions the
builder doesn't model (function calls, dialect-specific syntax, computed columns) anywhere an SQL
element is accepted: columns, from(), where()/on() operands, orderBy(), table names, and
more.
import { Raw, Select } from '@sqb/builder';
Select(Raw("'John''s Bike' f1")).from('table1');
// select 'John''s Bike' f1 from table1
Select().from('table1', Raw('func1()'));
// select * from table1,func1()
Select().from('table1').orderBy(Raw('LOWER(field1) desc'));
// select * from table1 order by LOWER(field1) desc
That last one needs Raw specifically because .orderBy()'s plain-string form only parses a bare
[schema.][table.]field [asc|desc] shape — .orderBy('LOWER(field1)') throws a TypeError
("does not match order column format"). A plain column name doesn't need Raw at all:
.orderBy('field1 desc') already works on its own.
Because Raw content is never escaped, never interpolate untrusted input into it directly — build
the value with Param instead and let the target driver bind it safely.
Param()
Param represents an external bind parameter. It
serializes to :name by default (dialect packages can override the placeholder syntax — ?,
$1, @name, etc. — through a SerializerExtension).
import { Param, Select, Eq } from '@sqb/builder';
Select().from('customers').where(Eq('id', Param('id')));
Param is dual-callable and accepts either positional arguments or a single options object; both
forms accept an optional dataType (a DataType member)
and isArray flag:
Param('id');
Param('id', DataType.INTEGER);
Param('id', DataType.INTEGER, false);
Param({ name: 'id', dataType: DataType.INTEGER, isArray: false });
Supplying values
Bind values are resolved from generate({ params }), or from .values(obj) set directly on the
query — both end up in result.params:
const query = Select().from('customers').where(Eq('id', Param('id')));
query.generate({ params: { id: 1 } });
// { sql: 'select * from customers where id = :id', params: { id: 1 }, ... }
Insert('customers', { id: Param('id'), name: Param('name') })
.values({ id: 1, name: 'Abc' })
.generate();
// sql: insert into customers (id, name) values (:id, :name)
// params: { id: 1, name: 'Abc' }
result.paramOptions mirrors each parameter's dataType/isArray, which database adapters use
to bind values with the correct native type.
strictParams
Passing strictParams: true to .generate() converts every literal value used as the right-hand
side of a comparison into an auto-generated Param (named P$_1, P$_2, ...), so the resulting
SQL never contains inline literals:
Select().from('table1').where({ id: 1 }).generate({ strictParams: true });
// sql: select * from table1 where id = :P$_1
// params: { P$_1: 1 }
This is useful for drivers or caches that key on the SQL text and want literal values kept out of
it entirely. See Generating SQL per dialect for the rest of the
.generate() options.