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:');

// Execute SQL statements from strings.
database.exec(`
  CREATE TABLE data(
    key INTEGER PRIMARY KEY,
    value TEXT
  ) STRICT
`);
// Create a prepared statement to insert data into the database.
const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
// Execute the prepared statement with bound values.
insert.run(1, 'hello');
insert.run(2, 'world');
// Create a prepared statement to read data from the database.
const query = database.prepare('SELECT * FROM data ORDER BY key');
// Execute the prepared statement and log the result set.
console.log(query.all());
// Prints: [ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ]
'use strict';
const { DatabaseSync } = require('node:sqlite');
const database = new DatabaseSync(':memory:');

// Execute SQL statements from strings.
database.exec(`
  CREATE TABLE data(
    key INTEGER PRIMARY KEY,
    value TEXT
  ) STRICT
`);
// Create a prepared statement to insert data into the database.
const insert = database.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
// Execute the prepared statement with bound values.
insert.run(1, 'hello');
insert.run(2, 'world');
// Create a prepared statement to read data from the database.
const query = database.prepare('SELECT * FROM data ORDER BY key');
// Execute the prepared statement and log the result set.
console.log(query.all());
// Prints: [ { key: 1, value: 'hello' }, { key: 2, value: 'world' } ]

JavaScript 與 SQLite 之間的類型轉換#

當 Node.js 寫入或讀取 SQLite 時,必須在 JavaScript 資料類型與 SQLite 的資料類型之間進行轉換。由於 JavaScript 支援的資料類型比 SQLite 多,因此僅支援 JavaScript 類型的一個子集。嘗試將不支援的資料類型寫入 SQLite 將會導致異常。

儲存類別 JavaScript 轉 SQLite SQLite 轉 JavaScript
NULL <null> <null>
INTEGER <number><bigint> <number><bigint> (可配置)
REAL <number> <number>
TEXT <string> <string>
BLOB <TypedArray><DataView> <Uint8Array>

從 SQLite 讀取值的 API 具有一個配置選項,用於決定 INTEGER 值在 JavaScript 中是轉換為 number 還是 bigint,例如敘述句的 readBigInts 選項和使用者定義函式的 useBigIntArguments 選項。如果 Node.js 從 SQLite 讀取的 INTEGER 值超出了 JavaScript 安全整數範圍,且未啟用讀取 BigInt 的選項,則會拋出 ERR_OUT_OF_RANGE 錯誤。

類別:DatabaseSync#

此類別代表與 SQLite 資料庫的單一連接。此類別公開的所有 API 均以同步方式執行。

new DatabaseSync(path[, options])#

  • path <string> | <Buffer> | <URL> 資料庫的路徑。SQLite 資料庫可以儲存在檔案中,也可以完全儲存在 記憶體內。若要使用檔案資料庫,路徑應為檔案路徑。若要使用記憶體內資料庫,路徑應為特殊名稱 ':memory:'
  • options <Object> 資料庫連接的配置選項。支援以下選項
    • open <boolean> 若為 true,則由建構函式開啟資料庫。當此值為 false 時,必須透過 open() 方法開啟資料庫。預設值: true
    • readOnly <boolean> 若為 true,則以唯讀模式開啟資料庫。如果資料庫不存在,開啟將失敗。預設值: false
    • enableForeignKeyConstraints <boolean> 若為 true,則啟用外鍵約束。建議啟用此項,但為了與舊版資料庫結構相容,也可以將其停用。開啟資料庫後,可以使用 PRAGMA foreign_keys 啟用或停用外鍵約束的強制執行。預設值: true
    • enableDoubleQuotedStringLiterals <boolean> 若為 true,SQLite 將接受雙引號字串常值。不建議這樣做,但為了與舊版資料庫結構相容,可以啟用。預設值: false
    • allowExtension <boolean> 若為 true,則啟用 loadExtension SQL 函式與 loadExtension() 方法。稍後可以呼叫 enableLoadExtension(false) 來停用此功能。預設值: false
    • timeout <number> 以毫秒為單位的忙碌逾時 (busy timeout)。這是 SQLite 在返回錯誤之前等待資料庫鎖定釋放的最長時間。預設值: 0
    • readBigInts <boolean> 若為 true,整數欄位將讀取為 JavaScript BigInt 值。若為 false,整數欄位將讀取為 JavaScript 數字。預設值: false
    • returnArrays <boolean> 若為 true,查詢結果將以陣列而非物件的形式返回。預設值: false
    • allowBareNamedParameters <boolean> 若為 true,允許綁定不含前綴字元(例如 foo 而非 :foo)的具名參數。預設值: true
    • allowUnknownNamedParameters <boolean> 若為 true,綁定時將忽略未知的具名參數。若為 false,則會針對未知的具名參數拋出異常。預設值: false
    • defensive <boolean> 若為 true,則啟用防禦旗標 (defensive flag)。啟用時,會禁用允許普通 SQL 故意損壞資料庫檔案的語言功能。防禦旗標也可以使用 enableDefensive() 來設定。預設值: true
    • limits <Object> 各種 SQLite 限制的配置。這些限制可用於防止在處理潛在惡意輸入時消耗過多資源。詳情請參閱 SQLite 說明文件中的執行階段限制 (Run-Time Limits)限制常數 (Limit Constants)。預設值由 SQLite 的編譯時預設值決定,並可能根據 SQLite 的構建方式而有所不同。支援以下屬性
      • length <number> 字串或 BLOB 的最大長度。
      • sqlLength <number> SQL 敘述句的最大長度。
      • column <number> 欄位的最大數量。
      • exprDepth <number> 表達式樹的最大深度。
      • compoundSelect <number> 複合 SELECT 中項目的最大數量。
      • vdbeOp <number> VDBE 指令的最大數量。
      • functionArg <number> 函式參數的最大數量。
      • attach <number> 附加資料庫的最大數量。
      • likePatternLength <number> LIKE 模式的最大長度。
      • variableNumber <number> SQL 變數的最大數量。
      • triggerDepth <number> 觸發器遞迴的最大深度。

建構一個新的 DatabaseSync 實例。

database.aggregate(name, options)#

向 SQLite 資料庫註冊一個新的聚合函式 (aggregate function)。此方法是對 sqlite3_create_window_function() 的封裝。

  • name <string> 要建立的 SQLite 函式名稱。
  • options <Object> 函式配置設定。
    • deterministic <boolean> 若為 true,則在建立的函式上設定 SQLITE_DETERMINISTIC 旗標。預設值: false
    • directOnly <boolean> 若為 true,則在建立的函式上設定 SQLITE_DIRECTONLY 旗標。預設值: false
    • useBigIntArguments <boolean> 若為 true,傳入 options.stepoptions.inverse 的整數參數將轉換為 BigInt。若為 false,則作為 JavaScript 數字傳遞。預設值: false
    • varargs <boolean> 若為 trueoptions.stepoptions.inverse 可以使用任意數量的參數(介於 0 與 SQLITE_MAX_FUNCTION_ARG 之間)呼叫。若為 false,則必須使用與 length 完全相同的參數數量呼叫。預設值: false
    • start <number> | <string> | <null> | <Array> | <Object> | <Function> 聚合函式的初始值。此值在聚合函式初始化時使用。當傳遞一個 <Function> 時,初始值將是其返回值。
    • step <Function> 對聚合中的每一列呼叫的函式。該函式接收當前狀態和列的值。此函式的返回值應為新的狀態。
    • result <Function> 獲取聚合結果時呼叫的函式。該函式接收最終狀態,並應返回聚合的結果。
    • inverse <Function> 提供此函式時,aggregate 方法將作為視窗函式 (window function) 運作。該函式接收當前狀態和移除列的值。此函式的返回值應為新的狀態。

當作為視窗函式使用時,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,
});

db.prepare('SELECT sumint(y) as total FROM t3').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,
});

db.prepare('SELECT sumint(y) as total FROM t3').get(); // { total: 21 }

database.close()#

關閉資料庫連接。如果資料庫未開啟,則會拋出異常。此方法是對 sqlite3_close_v2() 的封裝。

database.loadExtension(path)#

  • path <string> 要載入的共用程式庫路徑。

將共用程式庫載入資料庫連接。此方法是對 sqlite3_load_extension() 的封裝。建構 DatabaseSync 實例時必須啟用 allowExtension 選項。

database.enableLoadExtension(allow)#

  • allow <boolean> 是否允許載入擴充功能。

啟用或停用 loadExtension SQL 函式以及 loadExtension() 方法。出於安全考慮,如果建構時 allowExtensionfalse,則無法啟用載入擴充功能。

database.enableDefensive(active)#

  • active <boolean> 是否設定防禦旗標。

啟用或停用防禦旗標。防禦旗標啟用時,會禁用允許普通 SQL 故意損壞資料庫檔案的語言功能。詳情請參閱 SQLite 說明文件中的 SQLITE_DBCONFIG_DEFENSIVE

database.location([dbName])#

  • dbName <string> 資料庫名稱。可以是 'main' (預設的主要資料庫) 或任何其他透過 ATTACH DATABASE 新增的資料庫。預設值: 'main'
  • 返回:<string> | <null> 資料庫檔案的位置。使用記憶體內資料庫時,此方法返回 null。

此方法是對 sqlite3_db_filename() 的封裝。

database.exec(sql)#

  • sql <string> 要執行的 SQL 字串。

此方法允許執行一或多個 SQL 敘述句而不返回任何結果。在執行從檔案讀取的 SQL 敘述句時非常有用。此方法是對 sqlite3_exec() 的封裝。

database.function(name[, options], fn)#

  • name <string> 要建立的 SQLite 函式名稱。
  • options <Object> 函式的選用配置設定。支援以下屬性
    • deterministic <boolean> 若為 true,則在建立的函式上設定 SQLITE_DETERMINISTIC 旗標。預設值: false
    • directOnly <boolean> 若為 true,則在建立的函式上設定 SQLITE_DIRECTONLY 旗標。預設值: false
    • useBigIntArguments <boolean> 若為 true,傳入 function 的整數參數將轉換為 BigInt。若為 false,則作為 JavaScript 數字傳遞。預設值: false
    • varargs <boolean> 若為 truefunction 可以使用任意數量的參數(介於 0 與 SQLITE_MAX_FUNCTION_ARG 之間)呼叫。若為 false,則必須使用與 function.length 完全相同的參數數量呼叫。預設值: false
  • fn <Function> 呼叫 SQLite 函式時要執行的 JavaScript 函式。此函式的返回值應為有效的 SQLite 資料類型:請參閱 JavaScript 與 SQLite 之間的類型轉換。如果返回值為 undefined,則結果預設為 NULL

此方法用於建立 SQLite 使用者定義函式。此方法是對 sqlite3_create_function_v2() 的封裝。

database.setAuthorizer(callback)#

  • callback <Function> | <null> 要設定的授權器函式,或設為 null 以清除當前授權器。

設定一個授權器回呼函式,每當 SQLite 嘗試透過預處理敘述句存取資料或修改資料庫結構時,都會呼叫該函式。這可用於實施安全策略、稽核存取或限制特定操作。此方法是對 sqlite3_set_authorizer() 的封裝。

呼叫時,回呼函式接收五個參數

  • actionCode <number> 正在執行的操作類型(例如 SQLITE_INSERT, SQLITE_UPDATE, SQLITE_SELECT)。
  • arg1 <string> | <null> 第一個參數(取決於上下文,通常是資料表名稱)。
  • arg2 <string> | <null> 第二個參數(取決於上下文,通常是欄位名稱)。
  • dbName <string> | <null> 資料庫名稱。
  • triggerOrView <string> | <null> 導致存取的觸發器或檢視表的名稱。

回呼函式必須返回以下常數之一

  • SQLITE_OK - 允許操作。
  • SQLITE_DENY - 拒絕操作(導致錯誤)。
  • SQLITE_IGNORE - 忽略操作(靜默跳過)。
const { DatabaseSync, constants } = require('node:sqlite');
const db = new DatabaseSync(':memory:');

// Set up an authorizer that denies all table creation
db.setAuthorizer((actionCode) => {
  if (actionCode === constants.SQLITE_CREATE_TABLE) {
    return constants.SQLITE_DENY;
  }
  return constants.SQLITE_OK;
});

// This will work
db.prepare('SELECT 1').get();

// This will throw an error due to authorization denial
try {
  db.exec('CREATE TABLE blocked (id INTEGER)');
} catch (err) {
  console.log('Operation blocked:', err.message);
}
import { DatabaseSync, constants } from 'node:sqlite';
const db = new DatabaseSync(':memory:');

// Set up an authorizer that denies all table creation
db.setAuthorizer((actionCode) => {
  if (actionCode === constants.SQLITE_CREATE_TABLE) {
    return constants.SQLITE_DENY;
  }
  return constants.SQLITE_OK;
});

// This will work
db.prepare('SELECT 1').get();

// This will throw an error due to authorization denial
try {
  db.exec('CREATE TABLE blocked (id INTEGER)');
} catch (err) {
  console.log('Operation blocked:', err.message);
}

database.isOpen#

  • 類型:<boolean> 資料庫目前是否處於開啟狀態。

database.isTransaction#

database.limits#

一個用於在執行階段獲取與設定 SQLite 資料庫限制的物件。每個屬性對應一個 SQLite 限制,且可以讀取或寫入。

const db = new DatabaseSync(':memory:');

// Read current limit
console.log(db.limits.length);

// Set a new limit
db.limits.sqlLength = 100000;

// Reset a limit to its compile-time maximum
db.limits.sqlLength = Infinity;

可用屬性:length, sqlLength, column, exprDepth, compoundSelect, vdbeOp, functionArg, attach, likePatternLength, variableNumber, triggerDepth

將屬性設定為 Infinity 會將限制重設為其編譯時的最大值。

database.open()#

開啟 DatabaseSync 建構函式中 path 參數指定的資料庫。此方法僅應在資料庫未透過建構函式開啟時使用。如果資料庫已開啟,則會拋出異常。

database.prepare(sql[, options])#

  • sql <string> 要編譯成預處理敘述句的 SQL 字串。
  • options <Object> 預處理敘述句的選用配置。
    • readBigInts <boolean> 若為 true,整數欄位將讀取為 BigInt預設值:繼承自資料庫選項,或為 false
    • returnArrays <boolean> 若為 true,結果將以陣列形式返回。預設值:繼承自資料庫選項,或為 false
    • allowBareNamedParameters <boolean> 若為 true,允許綁定不含前綴字元的具名參數。預設值:繼承自資料庫選項,或為 true
    • allowUnknownNamedParameters <boolean> 若為 true,則忽略未知的具名參數。預設值:繼承自資料庫選項,或為 false
  • 返回:<StatementSync> 預處理敘述句。

將 SQL 敘述句編譯為預處理敘述句 (prepared statement)。此方法是對 sqlite3_prepare_v2() 的封裝。

database.createTagStore([maxSize])#

  • maxSize <integer> 快取預處理敘述句的最大數量。預設值: 1000
  • 返回:{SQLTagStore} 用於快取預處理敘述句的新 SQL 標籤儲存區。

建立一個新的 SQLTagStore,這是一個用於儲存預處理敘述句的最近最少使用 (LRU) 快取。這允許透過為預處理敘述句加上唯一識別碼來實現高效的重複使用。

執行帶有標籤的 SQL 常值時,SQLTagStore 會檢查快取中是否已存在對應 SQL 查詢字串的預處理敘述句。如果存在,則使用快取的敘述句;如果不存在,則建立一個新的預處理敘述句並執行,然後儲存在快取中供未來使用。此機制有助於避免重複解析與準備相同 SQL 敘述句的開銷。

標籤化敘述句會將模板常值中的占位符值綁定為底層預處理敘述句的參數。例如:

sqlTagStore.get`SELECT ${value}`;

等同於:

db.prepare('SELECT ?').get(value);

然而,在第一個範例中,標籤儲存區會將底層預處理敘述句快取起來以供後續使用。

注意:標籤化敘述句中的 ${value} 語法會將參數綁定到預處理敘述句。這與其在非標籤化模板常值中的行為不同,後者執行的是字串內插 (string interpolation)。

// This a safe example of binding a parameter to a tagged statement.
sqlTagStore.run`INSERT INTO t1 (id) VALUES (${id})`;

// This is an *unsafe* example of an untagged template string.
// `id` is interpolated into the query text as a string.
// This can lead to SQL injection and data corruption.
db.run(`INSERT INTO t1 (id) VALUES (${id})`);

如果查詢字串(包括任何綁定占位符的位置)完全相同,標籤儲存區將從快取中匹配敘述句。

// The following statements will match in the cache:
sqlTagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`;
sqlTagStore.get`SELECT * FROM t1 WHERE id = ${12345} AND active = 1`;

// The following statements will not match, as the query strings
// and bound placeholders differ:
sqlTagStore.get`SELECT * FROM t1 WHERE id = ${id} AND active = 1`;
sqlTagStore.get`SELECT * FROM t1 WHERE id = 12345 AND active = 1`;

// The following statements will not match, as matches are case-sensitive:
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)');

// Using the 'run' method to insert data.
// The tagged literal is used to identify the prepared statement.
sql.run`INSERT INTO users VALUES (1, 'Alice')`;
sql.run`INSERT INTO users VALUES (2, 'Bob')`;

// Using the 'get' method to retrieve a single row.
const name = 'Alice';
const user = sql.get`SELECT * FROM users WHERE name = ${name}`;
console.log(user); // { id: 1, name: 'Alice' }

// Using the 'all' method to retrieve all rows.
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)');

// Using the 'run' method to insert data.
// The tagged literal is used to identify the prepared statement.
sql.run`INSERT INTO users VALUES (1, 'Alice')`;
sql.run`INSERT INTO users VALUES (2, 'Bob')`;

// Using the 'get' method to retrieve a single row.
const name = 'Alice';
const user = sql.get`SELECT * FROM users WHERE name = ${name}`;
console.log(user); // { id: 1, name: 'Alice' }

// Using the 'all' method to retrieve all rows.
const allUsers = sql.all`SELECT * FROM users ORDER BY id`;
console.log(allUsers);
// [
//   { id: 1, name: 'Alice' },
//   { id: 2, name: 'Bob' }
// ]

database.createSession([options])#

  • options <Object> Session 的配置選項。
    • table <string> 要追蹤變更的特定資料表。預設會追蹤所有資料表的變更。
    • db <string> 要追蹤的資料庫名稱。當使用 ATTACH DATABASE 新增多個資料庫時非常有用。預設值'main'
  • 返回:<Session> Session 控制代碼。

建立一個 Session 並將其附加到資料庫。此方法是對 sqlite3session_create()sqlite3session_attach() 的封裝。

database.applyChangeset(changeset[, options])#

  • changeset <Uint8Array> 二進制變更集 (changeset) 或修補集 (patchset)。
  • options <Object> 套用變更方式的配置選項。
    • filter <Function> 當目標資料表名稱傳遞給此函式並返回真值 (truthy) 時,跳過該變更。預設會嘗試套用所有變更。

    • onConflict <Function> 決定如何處理衝突的函式。該函式接收一個參數,可以是以下值之一:

      • SQLITE_CHANGESET_DATADELETEUPDATE 變更不包含預期的「前值 (before values)」。
      • SQLITE_CHANGESET_NOTFOUND:不存在符合 DELETEUPDATE 變更之主鍵的列。
      • SQLITE_CHANGESET_CONFLICTINSERT 變更導致主鍵重複。
      • SQLITE_CHANGESET_FOREIGN_KEY:套用變更會導致外鍵約束違規。
      • SQLITE_CHANGESET_CONSTRAINT:套用變更導致 UNIQUE, CHECK, 或 NOT NULL 約束違規。

      該函式應返回以下值之一:

      • SQLITE_CHANGESET_OMIT:省略衝突的變更。
      • SQLITE_CHANGESET_REPLACE:以衝突的變更替換現有值(僅對 SQLITE_CHANGESET_DATASQLITE_CHANGESET_CONFLICT 衝突有效)。
      • SQLITE_CHANGESET_ABORT:發生衝突時中止並回滾 (roll back) 資料庫。

      當衝突處理器拋出錯誤或返回任何其他值時,套用變更集將會中止且資料庫會被回滾。

      預設值:一個返回 SQLITE_CHANGESET_ABORT 的函式。

  • 返回:<boolean> 變更集是否成功套用且未中止。

如果資料庫未開啟,則會拋出異常。此方法是對 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();

const insert = sourceDb.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
insert.run(1, 'hello');
insert.run(2, 'world');

const changeset = session.changeset();
targetDb.applyChangeset(changeset);
// Now that the changeset has been applied, targetDb contains the same data as 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();

const insert = sourceDb.prepare('INSERT INTO data (key, value) VALUES (?, ?)');
insert.run(1, 'hello');
insert.run(2, 'world');

const changeset = session.changeset();
targetDb.applyChangeset(changeset);
// Now that the changeset has been applied, targetDb contains the same data as sourceDb.

database[Symbol.dispose]()#

關閉資料庫連接。如果資料庫連接已關閉,則不執行任何操作。

類別:Session#

session.changeset()#

  • 返回:<Uint8Array> 可套用於其他資料庫的二進制變更集。

獲取包含自變更集建立以來所有變更的變更集。可以呼叫多次。如果資料庫或 Session 未開啟,則會拋出異常。此方法是對 sqlite3session_changeset() 的封裝。

session.patchset()#

  • 返回:<Uint8Array> 可套用於其他資料庫的二進制修補集。

類似於上述方法,但產生的是更精簡的修補集。請參閱 SQLite 說明文件中的變更集與修補集。如果資料庫或 Session 未開啟,則會拋出異常。此方法是對 sqlite3session_patchset() 的封裝。

session.close()#

關閉 Session。如果資料庫或 Session 未開啟,則會拋出異常。此方法是對 sqlite3session_delete() 的封裝。

session[Symbol.dispose]()#

關閉 Session。如果 Session 已關閉,則不執行任何操作。

類別:StatementSync#

此類別代表單一預處理敘述句 (prepared statement)。此類別無法透過建構函式直接實例化,而是透過 database.prepare() 方法建立。此類別公開的所有 API 均以同步方式執行。

預處理敘述句是建立它的 SQL 語句的高效二進制表示。預處理敘述句是參數化的,可以使用不同的綁定值呼叫多次。參數還能防止 SQL 注入 (SQL injection) 攻擊。基於這些原因,處理使用者輸入時,預處理敘述句優於手寫的 SQL 字串。

statement.all([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> 用於綁定具名參數的選用物件。此物件的鍵用於配置對照。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零個或多個要綁定到匿名參數的值。
  • 返回:<Array> 物件陣列。每個物件對應於執行預處理敘述句後返回的一列。每個物件的鍵與值對應於該列的欄位名稱與值。

此方法執行預處理敘述句並以物件陣列的形式返回所有結果。如果預處理敘述句不返回任何結果,則此方法返回一個空陣列。預處理敘述句的參數使用 namedParametersanonymousParameters 中的值進行綁定。

statement.columns()#

此方法用於獲取有關預處理敘述句返回欄位的資訊。

statement.expandedSQL#

  • 類型:<string> 展開後的原始 SQL,包含參數值。

預處理敘述句的原始 SQL 文字,其中參數占位符已替換為該預處理敘述句最近一次執行時使用的值。此屬性是對 sqlite3_expanded_sql() 的封裝。

statement.get([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> 用於綁定具名參數的選用物件。此物件的鍵用於配置對照。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零個或多個要綁定到匿名參數的值。
  • 返回:<Object> | <undefined> 對應於執行預處理敘述句後返回之第一列的物件。物件的鍵與值對應於該列的欄位名稱與值。如果資料庫未返回任何列,則此方法返回 undefined

此方法執行預處理敘述句並以物件的形式返回第一個結果。如果預處理敘述句不返回任何結果,則此方法返回 undefined。預處理敘述句的參數使用 namedParametersanonymousParameters 中的值進行綁定。

statement.iterate([namedParameters][, ...anonymousParameters])#

  • namedParameters <Object> 用於綁定具名參數的選用物件。此物件的鍵用於配置對照。
  • ...anonymousParameters <null> | <number> | <bigint> | <string> | <Buffer> | <TypedArray> | <DataView> 零個或多個要綁定到匿名參數的值。
  • 返回:<Iterator> 物件的可迭代疊代器 (iterable iterator)。每個物件對應於執行預處理敘述句後返回的一列。每個物件的鍵與值對應於該列的欄位名稱與值。

此方法執行預處理敘述句並返回物件的疊代器。如果預處理敘述句不返回任何結果,則此方法返回一個空疊代器。預處理敘述句的參數使用 namedParametersanonymousParameters 中的值進行綁定。

statement.run([namedParameters][, ...anonymousParameters])#

此方法執行預處理敘述句並返回一個總結變更結果的物件。預處理敘述句的參數使用 namedParametersanonymousParameters 中的值進行綁定。

statement.setAllowBareNamedParameters(enabled)#

  • enabled <boolean> 啟用或停用對不含前綴字元的具名參數綁定的支援。

SQLite 參數的名稱以一個前綴字元開始。預設情況下,node:sqlite 要求在綁定參數時必須存在此前綴字元。然而,除了錢字號 ($) 以外,這些前綴字元在作為物件鍵使用時還需要額外的引號。

為了提升易用性,此方法可用於允許裸名參數 (bare named parameters),即在 JavaScript 程式碼中不需要前綴字元。啟用裸名參數時有幾點注意事項:

  • SQL 中仍需要前綴字元。
  • JavaScript 中仍允許使用前綴字元。事實上,使用前綴名稱的綁定效能會稍微好一點。
  • 在同一個預處理敘述句中使用歧義的具名參數(例如 $k@k)將導致異常,因為無法確定如何綁定裸名。

statement.setAllowUnknownNamedParameters(enabled)#

  • enabled <boolean> 啟用或停用對未知具名參數的支援。

預設情況下,如果在綁定參數時遇到未知的名稱,會拋出異常。此方法允許忽略未知的具名參數。

statement.setReturnArrays(enabled)#

  • enabled <boolean> 啟用或停用以陣列形式返回查詢結果。

啟用時,all(), get(), 和 iterate() 方法返回的查詢結果將以陣列而非物件的形式呈現。

statement.setReadBigInts(enabled)#

  • enabled <boolean> 啟用或停用在從資料庫讀取 INTEGER 欄位時使用 BigInt

從資料庫讀取時,SQLite 的 INTEGER 預設對照到 JavaScript 數字。然而,SQLite INTEGER 可以儲存比 JavaScript 數字所能表示的更大的值。在這種情況下,此方法可用於使用 JavaScript BigInt 讀取 INTEGER 資料。此方法不影響資料庫寫入操作,寫入時一向支援數字和 BigInt

statement.sourceSQL#

  • 類型:<string> 用於建立此預處理敘述句的原始 SQL。

預處理敘述句的原始 SQL 文字。此屬性是對 sqlite3_sql() 的封裝。

類別:SQLTagStore#

此類別代表單一最近最少使用 (LRU) 快取,用於儲存預處理敘述句。

此類別的實例是透過 database.createTagStore() 方法建立的,而非使用建構函式。儲存區根據提供的 SQL 查詢字串快取預處理敘述句。當再次看到相同的查詢時,儲存區會檢索快取的敘述句,並透過參數綁定安全地套用新值,從而防止 SQL 注入等攻擊。

快取的 maxSize 預設為 1000 個敘述句,但也可以提供自定義大小(例如 database.createTagStore(100))。此類別公開的所有 API 均以同步方式執行。

sqlTagStore.all(stringElements[, ...boundParameters])#

執行給定的 SQL 查詢並以物件陣列的形式返回所有結果列。

此函式旨在作為模板常值標籤 (template literal tag) 使用,而非直接呼叫。

sqlTagStore.get(stringElements[, ...boundParameters])#

執行給定的 SQL 查詢並以物件的形式返回第一列結果。

此函式旨在作為模板常值標籤 (template literal tag) 使用,而非直接呼叫。

sqlTagStore.iterate(stringElements[, ...boundParameters])#

執行給定的 SQL 查詢並返回結果列的疊代器。

此函式旨在作為模板常值標籤 (template literal tag) 使用,而非直接呼叫。

sqlTagStore.run(stringElements[, ...boundParameters])#

執行給定的 SQL 查詢,預期不會返回任何列(例如 INSERT, UPDATE, DELETE)。

此函式旨在作為模板常值標籤 (template literal tag) 使用,而非直接呼叫。

sqlTagStore.size#

一個唯讀屬性,返回目前快取中的預處理敘述句數量。

sqlTagStore.capacity#

一個唯讀屬性,返回快取可容納的預處理敘述句最大數量。

sqlTagStore.db#

一個唯讀屬性,返回與此 SQLTagStore 關聯的 DatabaseSync 物件。

sqlTagStore.clear()#

重設 LRU 快取,清除所有儲存的預處理敘述句。

sqlite.backup(sourceDb, path[, options])#

  • sourceDb <DatabaseSync> 要備份的資料庫。來源資料庫必須處於開啟狀態。
  • path <string> | <Buffer> | <URL> 備份檔案建立的路徑。如果檔案已存在,內容將被覆寫。
  • options <Object> 備份的選用配置。支援以下屬性
    • source <string> 來源資料庫名稱。可以是 'main' (預設主要資料庫) 或任何透過 ATTACH DATABASE 新增的資料庫。預設值: 'main'
    • target <string> 目標資料庫名稱。可以是 'main' (預設主要資料庫) 或任何透過 ATTACH DATABASE 新增的資料庫。預設值: 'main'
    • rate <number> 每次備份批次傳輸的頁面數。預設值: 100
    • progress <Function> 選用的回呼函式,在每個備份步驟後呼叫。傳遞給此回呼的參數是一個具有 remainingPagestotalPages 屬性的 <Object>,用於描述備份操作的當前進度。
  • 返回:<Promise> 一個 Promise,在完成時履行並返回總備份頁數,若發生錯誤則拒絕。

此方法執行資料庫備份。此方法抽象化了 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, // Copy one page at a time.
    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, // Copy one page at a time.
  progress: ({ totalPages, remainingPages }) => {
    console.log('Backup in progress', { totalPages, remainingPages });
  },
});

console.log('Backup completed', totalPagesTransferred);

sqlite.constants#

一個包含 SQLite 操作常用常數的物件。

SQLite 常數#

sqlite.constants 物件導出以下常數。

衝突解決常數#

以下常數之一可用作傳遞給 database.applyChangeset()onConflict 衝突解決處理器的參數。另請參閱 SQLite 說明文件中的傳遞給衝突處理器的常數

常數 說明
SQLITE_CHANGESET_DATA 在處理 DELETE 或 UPDATE 變更時,如果資料庫中存在具有所需 PRIMARY KEY 欄位的列,但由該更新修改的一或多個其他(非主鍵)欄位不包含預期的「前值」,則使用此常數呼叫衝突處理器。
SQLITE_CHANGESET_NOTFOUND 在處理 DELETE 或 UPDATE 變更時,如果資料庫中不存在具有所需 PRIMARY KEY 欄位的列,則使用此常數呼叫衝突處理器。
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_DATASQLITE_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 修改資料表結構 (Alter table)
SQLITE_REINDEX 重建索引 (Reindex)
SQLITE_ANALYZE 分析資料庫
SQLITE_CREATE_VTABLE 建立虛擬資料表
SQLITE_DROP_VTABLE 刪除虛擬資料表
SQLITE_FUNCTION 使用函式
SQLITE_SAVEPOINT 建立、釋放或回滾儲存點 (savepoint)
SQLITE_COPY 複製資料(舊版)
SQLITE_RECURSIVE 遞迴查詢