SQLite
History
SQLite 现在是发布候选版本。
SQLite 不再位于 --experimental-sqlite 之后,但仍处于实验阶段。
稳定性:1.2 - 发布候选版本。
node:sqlite 模块提供了对 SQLite 数据库的便捷访问。
要访问它:
import sqlite from 'node:sqlite';
const sqlite = require('node:sqlite');
此模块仅在 node: 命名空间下可用。
下面的示例演示了 node:sqlite 模块的基本用法,
用于打开一个内存数据库、向其中写入数据,然后再读取出来。
import { DatabaseSync } from 'node:sqlite'; const database = new DatabaseSync(':memory:'); // 从字符串执行 SQL 语句。 database.exec(` CREATE TABLE data( key INTEGER PRIMARY KEY, value TEXT ) STRICT `); // 创建一个预编译语句,用于向数据库插入数据。 const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)'); // 使用绑定值执行预编译语句。 insert.run(1, 'hello'); insert.run(2, 'world'); // 不再需要预编译语句时将其终结。 insert.close(); // 创建一个预编译语句,用于从数据库读取数据。 const query = database.prepare('SELECT * FROM data ORDER BY key'); // 执行预编译语句并输出结果集。 console.log(query.all()); // 输出:[ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ] query.close();
const { DatabaseSync } = require('node:sqlite'); const database = new DatabaseSync(':memory:'); // 从字符串执行 SQL 语句。 database.exec(` CREATE TABLE data( key INTEGER PRIMARY KEY, value TEXT ) STRICT `); // 创建一个预编译语句,用于向数据库插入数据。 const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)'); // 使用绑定值执行预编译语句。 insert.run(1, 'hello'); insert.run(2, 'world'); // 不再需要预编译语句时将其终结。 insert.close(); // 创建一个预编译语句,用于从数据库读取数据。 const query = database.prepare('SELECT * FROM data ORDER BY key'); // 执行预编译语句并输出结果集。 console.log(query.all()); // 输出:[ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ] query.close();
当 Node.js 向 SQLite 写入或从 SQLite 读取时,会在 JavaScript 数据类型和 SQLite 的 数据类型 之间进行转换。 由于 JavaScript 支持的数据类型比 SQLite 更多,因此只支持 JavaScript 类型的一个子集。 尝试将不受支持的数据类型写入 SQLite 将导致异常。
| 存储类 | JavaScript 到 SQLite | SQLite 到 JavaScript |
|---|---|---|
NULL | null | null |
INTEGER | number、bigint 或 boolean | number 或 bigint (可配置) |
REAL | number | number |
TEXT | string | string |
BLOB | TypedArray、DataView、ArrayBuffer 或 SharedArrayBuffer | Uint8Array |
布尔值会被写入为 INTEGER 值 1 和 0。与其他 INTEGER 值一样,读取时默认会将它们作为 number 返回;启用 BigInt 读取后,则会作为 bigint 值(1n 和 0n)返回。写入无法容纳在有符号 64 位整数中的 bigint 时,会抛出 ERR_INVALID_ARG_VALUE 错误。
用于从 SQLite 读取值的 API 提供了一个配置选项,用于决定 INTEGER 值在 JavaScript 中被转换为 number 还是 bigint,例如语句的 readBigInts 选项以及用户定义函数的 useBigIntArguments 选项。
如果 Node.js 从 SQLite 读取的 INTEGER 值超出了 JavaScript 安全整数 范围,并且未启用读取 BigInt 的选项,则会抛出 ERR_OUT_OF_RANGE 错误。
类:DatabaseSync
History
添加了 timeout 选项。
path 参数现在支持 Buffer 和 URL 对象。
此类表示到 SQLite 数据库的一个单一 连接。此类暴露的所有 API 都是同步执行的。
new DatabaseSync(path, options?): void
path
应该是一个文件路径。要使用内存数据库,
path
应该是特殊名称
':memory:'
。Objectbooleantrue
,构造函数会打开数据库。当此值为
false
时,必须通过
open()
方法打开数据库。
默认:
true
。booleantrue
,数据库将以只读模式打开。如果数据库不存在,打开将失败。
默认:
false
。booleanbooleanbooleantrue
,则启用
loadExtension
SQL 函数和
loadExtension()
方法。
之后可以调用
enableLoadExtension(false)
来禁用此功能。
默认:
false
。booleantrue
,整数字段将作为 JavaScript
BigInt
值读取。如果为
false
,整数字段将作为 JavaScript 数字读取。
默认:
false
。booleantrue
,查询结果将以数组而不是对象的形式返回。
默认:
false
。booleantrue
,允许绑定不带前缀字符的命名参数(例如使用
foo
而不是
:foo
)。
默认:
true
。booleantrue
,绑定时会忽略未知命名参数。如果为
false
,遇到未知命名参数时会抛出异常。
默认:
false
。booleantrue
,则启用防御性标志。启用防御性标志后,允许普通 SQL 有意损坏数据库文件的语言特性将被禁用。
也可以使用
enableDefensive()
设置该标志。
默认:
true
。Objectnumbernumbernumbernumbernumbernumbernumbernumbernumbernumbernumber构造一个新的 DatabaseSync 实例。
database.aggregate(name, options): void
向 SQLite 数据库注册一个新的聚合函数。此方法是对 sqlite3_create_window_function() 的封装。
stringObjectbooleanbooleanbooleantrue
,则
options.step
和
options.inverse
的整数参数会转换为
BigInt
。如果为
false
,整数参数将作为 JavaScript 数字传递。
默认:
false
。booleantrue
,则
options.step
和
options.inverse
可以使用任意数量的参数调用(介于零和
SQLITE_MAX_FUNCTION_ARG
之间)。如果为
false
,
inverse
和
step
必须使用恰好
length
个参数调用。
默认:
false
。Function
时,初始值将为其返回值。FunctionFunctionFunctionaggregate
方法将作为窗口函数工作。该函数接收当前状态和要丢弃的行值。此函数的返回值应为新状态。当作为窗口函数使用时,result 函数将被多次调用。
const { DatabaseSync } = require('node:sqlite'); const db = new DatabaseSync(':memory:'); db.exec(` CREATE TABLE t3(x, y); INSERT INTO t3 VALUES ('a', 4), ('b', 5), ('c', 3), ('d', 8), ('e', 1); `); db.aggregate('sumint', { start: 0, step: (acc, value) => acc + value, }); using query = db.prepare('SELECT sumint(y) as total FROM t3'); query.get(); // { total: 21 }
import { DatabaseSync } from 'node:sqlite'; const db = new DatabaseSync(':memory:'); db.exec(` CREATE TABLE t3(x, y); INSERT INTO t3 VALUES ('a', 4), ('b', 5), ('c', 3), ('d', 8), ('e', 1); `); db.aggregate('sumint', { start: 0, step: (acc, value) => acc + value, }); using query = db.prepare('SELECT sumint(y) as total FROM t3'); query.get(); // { total: 21 }
database.close(): void
关闭数据库连接。如果数据库未打开,则会抛出异常。如果在语句正在执行时调用该方法,例如在用户定义函数、聚合函数或授权器回调中调用,则会抛出 ERR_INVALID_STATE 错误。此方法是对 sqlite3_close_v2() 的封装。
database.loadExtension(path, entryPoint?): void
将共享库加载到数据库连接中。此方法是对 sqlite3_load_extension() 的封装。构造 DatabaseSync 实例时必须启用 allowExtension 选项。
import { DatabaseSync } from 'node:sqlite'; const database = new DatabaseSync(':memory:', { allowExtension: true }); // 使用从文件名推导出的入口点进行加载。 database.loadExtension('./decimal.dylib'); // 当推导出的名称不匹配时覆盖入口点。 database.loadExtension('./base64.dylib', 'sqlite3_base64_init');
const { DatabaseSync } = require('node:sqlite'); const database = new DatabaseSync(':memory:', { allowExtension: true }); // 使用从文件名推导出的入口点进行加载。 database.loadExtension('./decimal.dylib'); // 当推导出的名称不匹配时覆盖入口点。 database.loadExtension('./base64.dylib', 'sqlite3_base64_init');
database.enableLoadExtension(allow): void
boolean启用或禁用 loadExtension SQL 函数和 loadExtension() 方法。出于安全原因,如果构造时 allowExtension 为 false,则无法启用扩展加载。
database.enableDefensive(active): void
boolean启用或禁用防御性标志。当防御性标志处于活动状态时,允许普通 SQL 有意损坏数据库文件的语言特性将被禁用。
有关更多信息,请参阅 SQLite 文档中的 SQLITE_DBCONFIG_DEFENSIVE。
database.location(dbName?): void
string此方法是对 sqlite3_db_filename() 的封装。
database.exec(sql): void
string此方法允许执行一个或多个 SQL 语句而不返回任何结果。当执行从文件读取的 SQL 语句时,此方法很有用。此方法是对 sqlite3_exec() 的封装。
database.function(name, options?, fn): void
stringObjectbooleanbooleanbooleantrue
,则
function
的整数参数会转换为
BigInt
。如果为
false
,整数参数将作为 JavaScript 数字传递。
默认:
false
。booleantrue
,则
function
可以使用任意数量的参数调用(介于零和
SQLITE_MAX_FUNCTION_ARG
之间)。如果为
false
,
function
必须使用恰好
function.length
个参数调用。
默认:
false
。Functionundefined
,则结果默认为
NULL
。此方法用于创建 SQLite 用户定义函数。此方法是对 sqlite3_create_function_v2() 的封装。
database.setAuthorizer(callback): void
设置一个授权器回调,当 SQLite 试图通过预编译语句访问数据或修改数据库模式时会调用它。
这可用于强制执行安全策略、审计访问,或限制某些操作。此方法是对 sqlite3_set_authorizer() 的封装。
调用时,回调会接收五个参数:
回调必须返回以下常量之一:
SQLITE_OK- 允许该操作。SQLITE_DENY- 拒绝该操作(会导致错误)。SQLITE_IGNORE- 忽略该操作(静默跳过)。
const { DatabaseSync, constants } = require('node:sqlite'); const db = new DatabaseSync(':memory:'); // 设置一个拒绝所有建表操作的授权器 db.setAuthorizer((actionCode) => { if (actionCode === constants.SQLITE_CREATE_TABLE) { return constants.SQLITE_DENY; } return constants.SQLITE_OK; }); // 这将正常运行 using query = db.prepare('SELECT 1'); query.get(); // 由于授权被拒绝,这里会抛出错误 try { db.exec('CREATE TABLE blocked (id INTEGER)'); } catch (err) { console.log('操作被阻止:', err.message); }
import { DatabaseSync, constants } from 'node:sqlite'; const db = new DatabaseSync(':memory:'); // 设置一个拒绝所有建表操作的授权器 db.setAuthorizer((actionCode) => { if (actionCode === constants.SQLITE_CREATE_TABLE) { return constants.SQLITE_DENY; } return constants.SQLITE_OK; }); // 这将正常运行 using query = db.prepare('SELECT 1'); query.get(); // 由于授权被拒绝,这里会抛出错误 try { db.exec('CREATE TABLE blocked (id INTEGER)'); } catch (err) { console.log('操作被阻止:', err.message); }
- 类型:
boolean数据库当前是否已打开。
- 类型:
boolean数据库当前是否处于事务中。此方法是对sqlite3_get_autocommit()的封装。
- 类型:
Object
一个用于在运行时获取和设置 SQLite 数据库限制的对象。 每个属性对应一个 SQLite 限制,都可以读取或写入。
const db = new DatabaseSync(':memory:'); // 读取当前限制 console.log(db.limits.length); // 设置新的限制 db.limits.sqlLength = 100000; // 将限制重置为其编译时最大值 db.limits.sqlLength = Infinity;
可用属性:length、sqlLength、column、exprDepth、
compoundSelect、vdbeOp、functionArg、attach、likePatternLength、
variableNumber、triggerDepth。
将某个属性设置为 Infinity 会将该限制重置为其编译时最大值。
database.open(): void
打开 DatabaseSync 构造函数中 path 参数指定的数据库。此方法仅应在数据库未由构造函数打开时使用。如果数据库已经打开,则会抛出异常。
database.serialize(dbName?): void
string将数据库序列化为二进制表示,并以 Uint8Array 形式返回。
这对于保存、克隆或传输内存数据库很有用。此方法是对 sqlite3_serialize() 的封装。
import { DatabaseSync } from 'node:sqlite'; const db = new DatabaseSync(':memory:'); db.exec('CREATE TABLE t(key INTEGER PRIMARY KEY, value TEXT)'); db.exec("INSERT INTO t VALUES (1, 'hello')"); const buffer = db.serialize(); console.log(buffer.length); // 打印数据库的字节长度
const { DatabaseSync } = require('node:sqlite'); const db = new DatabaseSync(':memory:'); db.exec('CREATE TABLE t(key INTEGER PRIMARY KEY, value TEXT)'); db.exec("INSERT INTO t VALUES (1, 'hello')"); const buffer = db.serialize(); console.log(buffer.length); // 打印数据库的字节长度
database.deserialize(buffer, options?): void
Uint8Arraydatabase.serialize()
的输出。将序列化的数据库加载到此连接中,替换当前数据库。反序列化后的数据库可写。即使后续操作失败,也会在尝试反序列化之前完成现有预准备语句。如果在数据库回调位于调用堆栈中时调用此方法,例如用户定义的函数、聚合函数、授权器,或变更集筛选器或冲突处理程序,则会抛出 ERR_INVALID_STATE 错误。此方法是 sqlite3_deserialize() 的包装器。
import { DatabaseSync } from 'node:sqlite'; const original = new DatabaseSync(':memory:'); original.exec('CREATE TABLE t(key INTEGER PRIMARY KEY, value TEXT)'); original.exec("INSERT INTO t VALUES (1, 'hello')"); const buffer = original.serialize(); original.close(); const clone = new DatabaseSync(':memory:'); clone.deserialize(buffer); using query = clone.prepare('SELECT value FROM t'); console.log(query.get()); // 输出:{ value: 'hello' }
const { DatabaseSync } = require('node:sqlite'); const original = new DatabaseSync(':memory:'); original.exec('CREATE TABLE t(key INTEGER PRIMARY KEY, value TEXT)'); original.exec("INSERT INTO t VALUES (1, 'hello')"); const buffer = original.serialize(); original.close(); const clone = new DatabaseSync(':memory:'); clone.deserialize(buffer); using query = clone.prepare('SELECT value FROM t'); console.log(query.get()); // 输出:{ value: 'hello' }
database.prepare
History
Throw ERR_INVALID_ARG_VALUE if sql contains no statements.
database.prepare(sql, options?): void
stringObjectbooleantrue
,则将整数字段读取为
BigInt
。
**默认值:**继承自数据库选项或
false
。booleantrue
,则将结果作为数组返回。
**默认值:**继承自数据库选项或
false
。booleantrue
,则允许绑定不带前缀字符的命名参数。**默认值:**继承自数据库选项或
true
。booleantrue
,则忽略未知的命名参数。
**默认值:**继承自数据库选项或
false
。将 SQL 语句编译为[预准备语句][]. 此方法是对
sqlite3_prepare_v2() 的封装。
database.createTagStore(maxSize?): void
integer1000
。创建一个新的 SQLTagStore{},它是预编译语句的最近最少使用(LRU)缓存。
这使得通过唯一标识符对它们进行标记后,可以高效复用预编译语句。
当执行带标签的 SQL 字面量时,SQLTagStore 会检查缓存中是否已存在对应 SQL 查询字符串的预编译语句。
如果存在,则使用缓存的语句。如果不存在,则创建新的预编译语句,执行它,然后存入缓存以供将来使用。
这种机制有助于避免反复解析和准备相同 SQL 语句的开销。
带标签语句会将模板字面量中的占位值作为参数绑定到底层预编译语句中。例如:
sqlTagStore.get`SELECT ${value}`;
等同于:
using statement = db.prepare('SELECT ?'); statement.get(value);
不过在第一个示例中,标签存储会缓存底层预编译语句以供将来使用。
注意: 带标签语句中的
${value}语法会将参数 绑定 到预编译语句。 这不同于 未加标签 的模板字面量行为,后者会执行字符串插值。// 这是一个将参数绑定到带标签语句的安全示例。 sqlTagStore.run`INSERT INTO t1 (id) VALUES (${id})`; // 这是一个未加标签的模板字符串,属于 *不安全* 示例。 // `id` 会作为字符串插值到查询文本中。 // 这可能导致 SQL 注入和数据损坏。 db.run(`INSERT INTO t1 (id) VALUES (${id})`);
如果查询字符串相同(包括任何已绑定占位符的位置),标签存储会从缓存中匹配语句。
// 以下语句会在缓存中匹配: sqlTagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`; sqlTagStore.get`SELECT * FROM t1 WHERE id = ${12345} AND active = 1`; // 以下语句不会匹配,因为查询字符串 // 和绑定的占位符不同: sqlTagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`; sqlTagStore.get`SELECT * FROM t1 WHERE id = 12345 AND active = 1`; // 以下语句不会匹配,因为匹配区分大小写: sqlTagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`; sqlTagStore.get`select * from t1 where id = ${id} and active = 1`;
在带标签语句中绑定参数的唯一方式是使用 ${value} 语法。不要在 SQL 查询字符串本身中添加参数绑定占位符(例如 ?)。
import { DatabaseSync } from 'node:sqlite'; const db = new DatabaseSync(':memory:'); const sql = db.createTagStore(); db.exec('CREATE TABLE users (id INT, name TEXT)'); // 使用 'run' 方法插入数据。 // 带标签字面量用于标识预编译语句。 sql.run`INSERT INTO users VALUES (1, 'Alice')`; sql.run`INSERT INTO users VALUES (2, 'Bob')`; // 使用 'get' 方法检索单行。 const name = 'Alice'; const user = sql.get`SELECT * FROM users WHERE name = ${name}`; console.log(user); // { id: 1, name: 'Alice' } // 使用 'all' 方法检索所有行。 const allUsers = sql.all`SELECT * FROM users ORDER BY id`; console.log(allUsers); // [ // { id: 1, name: 'Alice' }, // { id: 2, name: 'Bob' } // ]
const { DatabaseSync } = require('node:sqlite'); const db = new DatabaseSync(':memory:'); const sql = db.createTagStore(); db.exec('CREATE TABLE users (id INT, name TEXT)'); // 使用 'run' 方法插入数据。 // 带标签字面量用于标识预编译语句。 sql.run`INSERT INTO users VALUES (1, 'Alice')`; sql.run`INSERT INTO users VALUES (2, 'Bob')`; // 使用 'get' 方法检索单行。 const name = 'Alice'; const user = sql.get`SELECT * FROM users WHERE name = ${name}`; console.log(user); // { id: 1, name: 'Alice' } // 使用 'all' 方法检索所有行。 const allUsers = sql.all`SELECT * FROM users ORDER BY id`; console.log(allUsers); // [ // { id: 1, name: 'Alice' }, // { id: 2, name: 'Bob' } // ]
database.createSession(options?): void
ObjectstringstringATTACH DATABASE
添加了多个数据库时,这很有用。
默认:
'main'
。创建并将会话附加到数据库。此方法是对 sqlite3session_create() 和 sqlite3session_attach() 的封装。
database.applyChangeset(changeset, options?): void
Uint8ArrayObjectFunctionfilter
回调,并将表名作为第一个参数传入。如果返回值为假值,则不会尝试对该表应用任何更改。否则,如果返回值为真值或未提供
filter
回调,则会尝试应用与该表相关的所有更改。FunctionDELETE
或
UPDATE
更改不包含预期的“之前”值。DELETE
或
UPDATE
更改的主键匹配的行。INSERT
更改导致主键重复。UNIQUE
、
CHECK
或
NOT NULL
约束。如果数据库未打开,则会抛出异常。此方法是对 sqlite3changeset_apply() 的封装。
import { DatabaseSync } from 'node:sqlite'; const sourceDb = new DatabaseSync(':memory:'); const targetDb = new DatabaseSync(':memory:'); sourceDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)'); targetDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)'); const session = sourceDb.createSession(); using insert = sourceDb.prepare('INSERT INTO data (key, value) VALUES (?, ?)'); insert.run(1, 'hello'); insert.run(2, 'world'); const changeset = session.changeset(); targetDb.applyChangeset(changeset); // changeset 现在已被应用,targetDb 中包含与 sourceDb 相同的数据。
const { DatabaseSync } = require('node:sqlite'); const sourceDb = new DatabaseSync(':memory:'); const targetDb = new DatabaseSync(':memory:'); sourceDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)'); targetDb.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)'); const session = sourceDb.createSession(); using insert = sourceDb.prepare('INSERT INTO data (key, value) VALUES (?, ?)'); insert.run(1, 'hello'); insert.run(2, 'world'); const changeset = session.changeset(); targetDb.applyChangeset(changeset); // changeset 现在已被应用,targetDb 中包含与 sourceDb 相同的数据。
database[Symbol.dispose](): void
关闭数据库连接。如果数据库连接已经关闭,则此操作不执行任何操作。
类:Session
History
session.changeset(): void
- 返回值:
Uint8Array可应用于其他数据库的二进制变更集。
检索自变更集创建以来包含所有变更的变更集。可以被多次调用。
如果数据库或会话未打开,则抛出异常。此方法是对 sqlite3session_changeset() 的封装。
session.patchset(): void
- 返回值:
Uint8Array可应用于其他数据库的二进制补丁集。
与上述方法类似,但生成更紧凑的补丁集。请参阅 SQLite 文档中的 变更集和补丁集。
如果数据库或会话未打开,则抛出异常。此方法是
对 sqlite3session_patchset() 的封装。
session.close(): void
关闭会话。如果数据库或会话未打开,则抛出异常。此方法是
对 sqlite3session_delete() 的封装。
session[Symbol.dispose](): void
关闭会话。如果会话已关闭,则不执行任何操作。
类:StatementSync
History
此类表示单个 [预准备语句][]。此类不能
通过其构造函数实例化。相反,实例是通过
database.prepare() 方法创建的。此类暴露的所有 API 均执行
同步。
预准备语句是用于创建它的 SQL 的高效二进制表示。预准备语句是可参数化的, 并且可以使用不同的绑定值多次调用。参数还提供针对 SQL 注入 攻击的保护。出于这些原因,在处理用户输入时,预准备语句优于 手工编写的 SQL 字符串。
all()、get()、iterate() 和 run() 方法会在执行预处理语句之前,将它们的参数绑定到预处理语句的参数上。参数可以是匿名参数或命名参数。
匿名参数在 SQL 中写作 ?,并按照传递给方法的参数顺序进行绑定。?NNN 形式会将 SQLite 参数索引 NNN 分配给占位符。避免混用编号参数和命名参数,因为它们共享参数索引。
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' }
命名参数在 SQL 中以 $、: 或 @ 之一作为前缀。它们从作为第一个参数传入的对象中绑定。如果在 SQL 中重复使用某个名称,则每次出现都会绑定相同的值。
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 }
上一个示例省略了对象键中的前缀字符。默认情况下允许使用不带前缀的名称;其注意事项请参见 statement.setAllowBareNamedParameters()。
如果绑定的键不是该语句的参数名称,则会抛出 ERR_INVALID_STATE 错误,除非忽略未知的命名参数。请参见 statement.setAllowUnknownNamedParameters()。
有关可以绑定的值,请参见 JavaScript 与 SQLite 之间的类型转换。绑定任何其他值都会抛出 ERR_INVALID_ARG_TYPE 错误。
statement.all(namedParameters?, ...anonymousParameters?): void
Objectnull | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer此方法执行预处理语句,并以对象数组的形式返回所有结果。如果预处理语句不返回任何结果,此方法将返回一个空数组。预处理语句的[参数将使用][] namedParameters 和 anonymousParameters 中的值进行绑定。参见绑定参数。
statement.close(): void
完成预准备语句。如果语句已经完成,则会抛出异常。此方法是
sqlite3_finalize() 的封装。
statement.columns(): void
- 返回:
Array对象数组。每个对象对应于预准备语句中的一列,并包含以下属性:Attributes源表中未使用别名的列名;如果该列是表达式或子查询的结果,则为null。此属性是sqlite3_column_origin_name()的结果。源数据库中未使用别名的名称;如果该列是表达式或子查询的结果,则为null。此属性是sqlite3_column_database_name()的结果。name:string在SELECT语句结果集中的列名。此属性是sqlite3_column_name()的结果。源表中未使用别名的名称;如果该列是表达式或子查询的结果,则为null。此属性是sqlite3_column_table_name()的结果。列声明的数据类型;如果该列是表达式或子查询的结果,则为null。此属性是sqlite3_column_decltype()的结果。
此方法用于检索有关预准备语句返回的列的信息。
- 类型:
string扩展为包含参数值的源 SQL。
预准备语句的源 SQL 文本,其中参数
占位符已被此预准备语句最近一次执行期间使用的值替换。此属性是
对 sqlite3_expanded_sql() 的封装。
statement.get(namedParameters?, ...anonymousParameters?): void
Objectnull | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer此方法执行准备好的语句,并将第一个结果作为对象返回。如果准备好的语句不返回任何结果,则此方法返回 undefined。准备好的语句的[参数使用][] namedParameters 和 anonymousParameters 中的值进行绑定。参见绑定参数。
statement.iterate
History
添加对绑定参数中布尔值的支持。
添加对绑定参数中 ArrayBuffer 和 SharedArrayBuffer 对象的支持。
为 anonymousParameters 添加对 DataView 和类型化数组对象的支持。
statement.iterate(namedParameters?, ...anonymousParameters?): void
Objectnull | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer此方法执行预准备语句,并返回一个由对象组成的迭代器。如果预准备语句不返回任何结果,此方法将返回一个空迭代器。预准备语句的[参数将使用 namedParameters 和 anonymousParameters 中的值进行绑定][Binding parameters][]。参见
绑定参数。
statement.run(namedParameters?, ...anonymousParameters?): void
Objectnull | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBufferINSERT
、
UPDATE
或
DELETE
语句
修改、插入或删除的行数。
此字段的类型取决于预处理语句的配置,可以是 number 或
BigInt
。
此属性是
sqlite3_changes64()
的结果。BigInt
。此属性是
sqlite3_last_insert_rowid()
的结果。此方法执行预处理语句,并返回一个概述所产生更改的对象。预处理语句的[参数使用绑定],绑定时使用 namedParameters 和 anonymousParameters 中的值。请参阅绑定参数。
statement.setAllowBareNamedParameters(enabled): void
booleanSQLite 参数的名称以一个前缀字符开头。不过,除了美元符号之外, 这些前缀字符在用作对象键时还需要额外的引号。
为了提升易用性,node:sqlite 默认允许使用裸命名参数,即在
JavaScript 代码中不需要前缀字符。可以使用此方法禁用该行为,
要求绑定时使用前缀字符。允许使用裸命名参数时,需要注意以下几点:
- SQL 中仍然需要前缀字符。
- JavaScript 中仍然允许前缀字符。事实上,前缀名称 将具有稍好的绑定性能。
- 在同一预准备语句中使用歧义的命名参数,例如
$k和@k, 将导致异常,因为无法确定如何绑定 裸名称。
statement.setAllowUnknownNamedParameters(enabled): void
boolean默认情况下,如果在绑定参数时遇到未知名称,则 抛出异常。此方法允许忽略未知的命名参数。
statement.setReturnArrays(enabled): void
boolean启用时,all()、get() 和 iterate() 方法返回的查询结果将作为数组返回,而不是
对象。
statement.setReadBigInts(enabled): void
booleanINTEGER
字段时使用
BigInt
。从数据库读取时,SQLite INTEGER 默认映射到 JavaScript
数字。但是,SQLite INTEGER 可以存储比
JavaScript 数字能够表示的值更大的值。在这种情况下,此方法可用于
使用 JavaScript BigInt 读取 INTEGER 数据。此方法对数据库写入操作
没有影响,其中数字和 BigInt 始终都受支持。
- 类型:
string用于创建此预准备语句的源 SQL。
预准备语句的源 SQL 文本。此属性是
对 sqlite3_sql() 的封装。
statement[Symbol.dispose](): void
完成预准备语句。如果预准备语句已经完成,则此操作不执行任何操作。
类:SQLTagStore
History
此类表示一个用于存储预编译语句的单 LRU(最近最少使用)缓存。
此类的实例是通过 database.createTagStore() 方法创建的,而不是使用构造函数。该存储基于提供的 SQL 查询字符串缓存预编译语句。当再次看到相同的查询时,存储会检索缓存的语句并通过参数绑定安全地应用新值,从而防止 SQL 注入等攻击。
缓存有一个默认为 1000 条语句的 maxSize,但可以提供自定义大小(例如,database.createTagStore(100))。此类暴露的所有 API 均同步执行。
sqlTagStore.all
History
添加对绑定参数中布尔值的支持。
添加对绑定参数中 ArrayBuffer 和 SharedArrayBuffer 对象的支持。
sqlTagStore.all(stringElements, ...boundParameters?): void
string[]null | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer执行给定的 SQL 查询并将所有结果行作为对象数组返回。
此函数旨在用作模板字面量标签,而不是直接调用。
sqlTagStore.get
History
添加对绑定参数中布尔值的支持。
添加对绑定参数中 ArrayBuffer 和 SharedArrayBuffer 对象的支持。
sqlTagStore.get(stringElements, ...boundParameters?): void
string[]null | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer执行给定的 SQL 查询并将第一行结果作为对象返回。
此函数旨在用作模板字面量标签,而不是直接调用。
sqlTagStore.iterate
History
添加对绑定参数中布尔值的支持。
添加对绑定参数中 ArrayBuffer 和 SharedArrayBuffer 对象的支持。
sqlTagStore.iterate(stringElements, ...boundParameters?): void
string[]null | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer执行给定的 SQL 查询并返回结果行的迭代器。
此函数旨在用作模板字面量标签,而不是直接调用。
sqlTagStore.run
History
添加对绑定参数中布尔值的支持。
添加对绑定参数中 ArrayBuffer 和 SharedArrayBuffer 对象的支持。
sqlTagStore.run(stringElements, ...boundParameters?): void
string[]null | number | bigint | boolean | string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer执行给定的 SQL 查询,预期不返回任何行(例如,INSERT、UPDATE、DELETE)。
此函数旨在用作模板字面量标签,而不是直接调用。
- 类型:
integer
一个只读属性,返回缓存中当前预编译语句的数量。
- 类型:
integer
一个只读属性,返回缓存可以容纳的最大预编译语句数量。
- 类型:
DatabaseSync
一个只读属性,返回与此 SQLTagStore 关联的 DatabaseSync 对象。
sqlTagStore.clear(): void
重置 LRU 缓存,清除所有存储的预编译语句。
sqlite.backup
History
path 参数现在支持 Buffer 和 URL 对象。
sqlite.backup(sourceDb, path, options?): void
DatabaseSync此方法进行数据库备份。此方法抽象了 sqlite3_backup_init()、sqlite3_backup_step() 和 sqlite3_backup_finish() 函数。
备份的数据库在备份过程中可以正常使用。来自同一连接(同一 DatabaseSync 对象)的变更会立即反映在备份中。但是,来自其他连接的变更会导致备份过程重新启动。
const { backup, DatabaseSync } = require('node:sqlite'); (async () => { const sourceDb = new DatabaseSync('source.db'); const totalPagesTransferred = await backup(sourceDb, 'backup.db', { rate: 1, // 一次复制一页。 progress: ({ totalPages, remainingPages }) => { console.log('Backup in progress', { totalPages, remainingPages }); }, }); console.log('Backup completed', totalPagesTransferred); })();
import { backup, DatabaseSync } from 'node:sqlite'; const sourceDb = new DatabaseSync('source.db'); const totalPagesTransferred = await backup(sourceDb, 'backup.db', { rate: 1, // 一次复制一页。 progress: ({ totalPages, remainingPages }) => { console.log('Backup in progress', { totalPages, remainingPages }); }, }); console.log('Backup completed', totalPagesTransferred);
- 类型:
Object
一个包含 SQLite 操作常用常量的对象。
以下常量由 sqlite.constants 对象导出。
以下常量之一可作为传递给 database.applyChangeset() 的 onConflict 冲突解决处理程序的参数。另请参阅 SQLite 文档中的 传递给冲突处理程序的常量。
| 常量 | 描述 |
|---|---|
SQLITE_CHANGESET_DATA |
当处理 DELETE 或 UPDATE 变更时,如果数据库中存在具有所需主键字段的行,但更新修改的一个或多个其他(非主键)字段不包含预期的“之前”值,则使用此常量调用冲突处理程序。 |
SQLITE_CHANGESET_NOTFOUND |
当处理 DELETE 或 UPDATE 变更时,如果数据库中不存在具有所需主键字段的行,则使用此常量调用冲突处理程序。 |
SQLITE_CHANGESET_CONFLICT |
在处理 INSERT 变更时,如果操作会导致主键值重复,则将此常量传递给冲突处理程序。 |
SQLITE_CHANGESET_CONSTRAINT |
如果启用了外键处理,并且应用变更集使数据库处于包含外键违规的状态,则在提交变更集之前恰好一次使用此常量调用冲突处理程序。如果冲突处理程序返回 SQLITE_CHANGESET_OMIT,则提交更改,包括导致外键约束违规的更改。或者,如果它返回 SQLITE_CHANGESET_ABORT,则回滚变更集。 |
SQLITE_CHANGESET_FOREIGN_KEY |
如果在应用变更时发生任何其他约束违规(即 UNIQUE、CHECK 或 NOT NULL 约束),则使用此常量调用冲突处理程序。 |
以下常量之一必须从传递给 database.applyChangeset() 的 onConflict 冲突解决处理程序返回。另请参阅 SQLite 文档中的 从冲突处理程序返回的常量。
| 常量 | 描述 |
|---|---|
SQLITE_CHANGESET_OMIT |
省略冲突的更改。 |
SQLITE_CHANGESET_REPLACE |
冲突的更改替换现有值。请注意,仅当冲突类型为 SQLITE_CHANGESET_DATA 或 SQLITE_CHANGESET_CONFLICT 时,才能返回此值。 |
SQLITE_CHANGESET_ABORT |
当更改遇到冲突时中止并回滚数据库。 |
以下常量与 database.setAuthorizer() 方法一起使用。
以下常量之一必须从传递给 database.setAuthorizer() 的授权回调函数返回。
| 常量 | 描述 |
|---|---|
SQLITE_OK |
允许操作正常进行。 |
SQLITE_DENY |
拒绝操作并导致返回错误。 |
SQLITE_IGNORE |
忽略操作并继续,就好像从未请求过它一样。 |
以下常量作为第一个参数传递给授权回调函数,以指示正在授权的操作类型。
| 常量 | 描述 |
|---|---|
SQLITE_CREATE_INDEX |
创建索引 |
SQLITE_CREATE_TABLE |
创建表 |
SQLITE_CREATE_TEMP_INDEX |
创建临时索引 |
SQLITE_CREATE_TEMP_TABLE |
创建临时表 |
SQLITE_CREATE_TEMP_TRIGGER |
创建临时触发器 |
SQLITE_CREATE_TEMP_VIEW |
创建临时视图 |
SQLITE_CREATE_TRIGGER |
创建触发器 |
SQLITE_CREATE_VIEW |
创建视图 |
SQLITE_DELETE |
从表中删除 |
SQLITE_DROP_INDEX |
删除索引 |
SQLITE_DROP_TABLE |
删除表 |
SQLITE_DROP_TEMP_INDEX |
删除临时索引 |
SQLITE_DROP_TEMP_TABLE |
删除临时表 |
SQLITE_DROP_TEMP_TRIGGER |
删除临时触发器 |
SQLITE_DROP_TEMP_VIEW |
删除临时视图 |
SQLITE_DROP_TRIGGER |
删除触发器 |
SQLITE_DROP_VIEW |
删除视图 |
SQLITE_INSERT |
插入到表中 |
SQLITE_PRAGMA |
执行 PRAGMA 语句 |
SQLITE_READ |
从表中读取 |
SQLITE_SELECT |
执行 SELECT 语句 |
SQLITE_TRANSACTION |
开始、提交或回滚事务 |
SQLITE_UPDATE |
更新表 |
SQLITE_ATTACH |
附加数据库 |
SQLITE_DETACH |
分离数据库 |
SQLITE_ALTER_TABLE |
修改表 |
SQLITE_REINDEX |
重新索引 |
SQLITE_ANALYZE |
分析数据库 |
SQLITE_CREATE_VTABLE |
创建虚拟表 |
SQLITE_DROP_VTABLE |
删除虚拟表 |
SQLITE_FUNCTION |
使用函数 |
SQLITE_SAVEPOINT |
创建、释放或回滚保存点 |
SQLITE_COPY |
复制数据(旧版) |
SQLITE_RECURSIVE |
递归查询 |