From b0c9a2ca7f7cd651bbfbbf97afd3f0141b5285fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Ara=C3=BAjo?= Date: Thu, 6 Aug 2026 13:41:22 -0300 Subject: [PATCH 1/2] doc: document sqlite parameter binding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guilherme Araújo --- doc/api/sqlite.md | 100 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 23 deletions(-) diff --git a/doc/api/sqlite.md b/doc/api/sqlite.md index 40ec877ddde3..5b5d15c50ba5 100644 --- a/doc/api/sqlite.md +++ b/doc/api/sqlite.md @@ -91,13 +91,17 @@ more data types than SQLite, only a subset of JavaScript types are supported. Attempting to write an unsupported data type to SQLite will result in an exception. -| Storage class | JavaScript to SQLite | SQLite to JavaScript | -| ------------- | -------------------------- | ------------------------------------- | -| `NULL` | {null} | {null} | -| `INTEGER` | {number} or {bigint} | {number} or {bigint} _(configurable)_ | -| `REAL` | {number} | {number} | -| `TEXT` | {string} | {string} | -| `BLOB` | {TypedArray} or {DataView} | {Uint8Array} | +| Storage class | JavaScript to SQLite | SQLite to JavaScript | +| ------------- | --------------------------------------------------------------- | ------------------------------------- | +| `NULL` | {null} | {null} | +| `INTEGER` | {number}, {bigint}, or {boolean} | {number} or {bigint} _(configurable)_ | +| `REAL` | {number} | {number} | +| `TEXT` | {string} | {string} | +| `BLOB` | {TypedArray}, {DataView}, {ArrayBuffer}, or {SharedArrayBuffer} | {Uint8Array} | + +Booleans are written as the `INTEGER` values `1` and `0`, and are read back as +numbers. Writing a {bigint} that does not fit in a signed 64-bit integer throws +an `ERR_INVALID_ARG_VALUE` error. APIs that read values from SQLite have a configuration option that determines whether `INTEGER` values are converted to `number` or `bigint` in JavaScript, @@ -972,6 +976,49 @@ times with different bound values. Parameters also offer protection against [SQL injection][] attacks. For these reasons, prepared statements are preferred over hand-crafted SQL strings when handling user input. +### Binding parameters + +The `all()`, `get()`, `iterate()`, and `run()` methods bind their arguments to +the parameters of the prepared statement before executing it. Parameters are +either anonymous or named. + +Anonymous parameters are written as `?` in SQL and are bound in order from the +arguments passed to the method. The `?NNN` form assigns an explicit number to a +placeholder, binding it to the argument at position `NNN`. + +```js +db.prepare('SELECT ? AS a, ? AS b').get('x', 42); +// { a: 'x', b: 42 } +db.prepare('SELECT ?2 AS a, ?1 AS b').get('first', 'second'); +// { a: 'second', b: 'first' } +``` + +Named parameters begin with one of the prefix characters `$`, `:`, or `@` in +SQL. They are bound from an object passed as the first argument. Repeating a +name in the SQL binds the same value to every occurrence. + +```js +db.prepare('SELECT $a AS a, $b AS b').get({ $a: 1, $b: 2 }); +// { a: 1, b: 2 } +db.prepare('SELECT :a AS a').get({ ':a': 1 }); +// { a: 1 } +db.prepare('SELECT @a AS a').get({ '@a': 1 }); +// { a: 1 } +db.prepare('SELECT $k AS a, $k AS b').get({ k: 7 }); +// { a: 7, b: 7 } +``` + +The last example omits the prefix character from the object key. Bare names are +allowed by default; see [`statement.setAllowBareNamedParameters()`][] for their +caveats. + +Binding a key that does not name a parameter of the statement throws an +`ERR_INVALID_STATE` error unless unknown named parameters are ignored. See +[`statement.setAllowUnknownNamedParameters()`][]. + +See [Type conversion between JavaScript and SQLite][] for the values that can be +bound. Binding any other value throws an `ERR_INVALID_ARG_TYPE` error. + ### `statement.all([namedParameters][, ...anonymousParameters])`