小巧、快速、可靠。
任選三項。

從 SQLite 3.5.9 移轉至 3.6.0

SQLite 3.6.0 版(2008 年 7 月 16 日)包含許多變更。根據 SQLite 專案的慣例,大多數變更完全向下相容。然而,3.6.0 版中的一些變更並不相容,可能需要修改應用程式程式碼和/或 makefile。本文件簡要說明 SQLite 3.6.0 中的變更,特別注意不相容的變更。

重點

1.0 不相容的變更

不相容的變更會先涵蓋,因為它們對維護人員和程式設計師來說最重要。

1.1 不相容變更概觀

  1. sqlite3_vfs 物件的變更

    1. xAccess 方法的簽章已修改為傳回 錯誤碼,並將其輸出儲存在參數所指的整數中,而不是直接傳回輸出。此變更允許 xAccess() 方法報告失敗。與此簽章變更相關聯的是,已新增新的延伸錯誤碼 SQLITE_IOERR_ACCESS

    2. 已從 sqlite3_vfs 中移除 xGetTempname 方法。取而代之的是,當 filename 參數為 NULL 時,xOpen 方法會增強為開啟它自己發明的暫時檔案。

    3. 已將 xGetLastError() 方法新增至 sqlite3_vfs,以將檔案系統特定的錯誤訊息和錯誤碼傳回 SQLite。

  2. 已修改 sqlite3_io_methods 上 xCheckReservedLock 方法的簽章,使其傳回 錯誤碼,並將其布林結果儲存在參數所指的整數中。與此變更相關聯的是,已新增新的延伸錯誤碼 SQLITE_IOERR_CHECKRESERVEDLOCK

  3. 當 SQLite 被移植到新的作業系統(除了 Unix、Windows 和 OS/2 之外,其移植版本與核心一起提供)時,必須提供兩個新函式,sqlite3_os_init()sqlite3_os_end(),作為移植的一部分。

  4. IN 和 NOT IN 運算子處理其右手邊表達式中 NULL 值的方式已符合 SQL 標準和其他 SQL 資料庫引擎。

  5. 在某些情況下,SELECT 陳述式的結果集的欄位名稱已經過調整,以更類似其他 SQL 資料庫引擎。

  6. 編譯時間選項的變更

    1. SQLITE_MUTEX_APPDEF 編譯時間參數不再被辨識。作為替代,可以使用 sqlite3_config() 搭配 SQLITE_CONFIG_MUTEX 運算子,以及 sqlite3_mutex_methods 物件,在執行階段建立替代的 互斥實作

    2. 編譯時間選項 OS_UNIX、OS_WIN、OS_OS2、OS_OTHER 和 TEMP_STORE 已重新命名,以包含「SQLITE_」前綴,以避免與應用程式軟體的命名空間衝突。這些選項的新名稱分別為:SQLITE_OS_UNIX、SQLITE_OS_WIN、SQLITE_OS_OS2、SQLITE_OS_OTHER 和 SQLITE_TEMP_STORE

1.2 VFS 層的變更

SQLite 版本 3.5.0 導入了 新的作業系統介面層,提供了底層作業系統的抽象。這是一項重要的創新,並已證明有助於移植和維護 SQLite。然而,開發人員在版本 3.5.0 中導入的原始「虛擬檔案系統」設計中發現了一些小瑕疵,因此 SQLite 3.6.0 包含了一些小的不相容變更來解決這些瑕疵。

重點:SQLite 3.6.0 版本中作業系統介面的不相容變更只會影響少數應用程式,這些應用程式會使用 虛擬檔案系統 介面,或提供應用程式定義的 互斥鎖實作,或使用其他不常見的編譯時間選項。SQLite 3.6.0 版本所引入的變更對絕大多數使用內建介面連接 Unix、Windows 和 OS/2,並使用標準建置組態的 SQLite 應用程式不會造成任何影響。

1.3 IN 運算子處理 NULL 的方式變更

所有低於或等於 3.5.9 版本的 SQLite,都錯誤處理了 IN 和 NOT IN 運算子右邊的 NULL 值。具體來說,SQLite 過去會忽略 IN 和 NOT IN 右邊的 NULL 值。

假設我們有一個 X1 表格,定義如下

  CREATE TABLE x1(x INTEGER);
  INSERT INTO x1 VALUES(1);
  INSERT INTO x1 VALUES(2);
  INSERT INTO x1 VALUES(NULL);

根據上面 X1 的定義,以下表達式在 SQLite 中過去會評估為 FALSE,儘管正確的答案實際上是 NULL

  3 IN (1,2,NULL)
  3 IN (SELECT * FROM x1)

類似地,以下表達式過去會評估為 TRUE,但事實上 NULL 也是正確的答案

  3 NOT IN (1,2,NULL)
  3 NOT IN (SELECT * FROM x1)

SQLite 過去的行為根據 SQL:1999 標準是不正確的,而且與 MySQL 和 PostgreSQL 的行為不一致。3.6.0 版本將 IN 和 NOT IN 運算子的行為變更為符合標準,並與其他 SQL 資料庫引擎提供相同的結果。

重點:IN 和 NOT IN 運算子處理 NULL 值的方式變更在技術上是錯誤修正,而非設計變更。然而,維護人員在升級到版本 3.6.0 之前,應檢查以確保應用程式不依賴於較舊的錯誤行為。

1.4 變更欄位命名規則

聯結子查詢所回報的欄位名稱已稍作修改,以更像其他資料庫引擎。考量下列查詢

  CREATE TABLE t1(a);
  CREATE TABLE t2(x);
  SELECT * FROM (SELECT t1.a FROM t1 JOIN t2 ORDER BY t2.x LIMIT 1) ORDER BY 1;

在版本 3.5.9 中,上述查詢會回傳一個名為「t1.a」的單一欄位。在版本 3.6.0 中,欄位名稱僅為「a」。

除非欄位包含 AS 子句,否則 SQLite 從未對 SELECT 陳述式的結果集中欄位的名稱做出任何承諾。因此,欄位名稱的此變更在技術上並非不相容。SQLite 僅從一個未定義的行為變更為另一個。儘管如此,許多應用程式依賴於 SQLite 未指定的欄位命名行為,因此此變更會在不相容變更的子標題下進行討論。

1.5 變更編譯時間選項

SQLite 的編譯時間選項由 C 預處理器巨集控制。SQLite 版本 3.6.0 變更其中一些巨集的名稱,以便所有特定於 SQLite 的 C 預處理器巨集都以「SQLITE_」前綴開頭。這樣做是為了降低與其他軟體模組名稱衝突的風險。

重點:編譯時間選項的變更可能會影響在專案中自訂建置 SQLite 的 makefile。對於使用 SQLite 的標準預設建置的大多數專案,這些變更應不會對應用程式程式碼產生任何影響。

2.0 完全向後相容的增強功能

除了上面列出的不相容變更之外,SQLite 版本 3.6.0 還新增了以下向後相容的變更和增強功能

  1. 新的 sqlite3_config() 介面允許應用程式在執行時期自訂 SQLite 的行為。使用 sqlite3_config() 可以進行的自訂包括以下內容

    1. 使用 SQLITE_CONFIG_MUTEX 動詞與 sqlite3_mutex_methods 物件指定替代的 mutex 實作。

    2. 使用 SQLITE_CONFIG_MALLOC 動詞與 sqlite3_mem_methods 物件指定替代的 malloc 實作。

    3. 使用 SQLITE_CONFIG_SINGLETHREADSQLITE_CONFIG_MULTITHREADSQLITE_CONFIG_SERIALIZED 部分或完全停用 mutex 的使用。

  2. 新的旗標 SQLITE_OPEN_NOMUTEX 可供 sqlite3_open_v2() 介面使用。

  3. 新的 sqlite3_status() 介面允許應用程式在執行時期查詢 SQLite 的效能狀態。

  4. 介面 sqlite3_memory_used()sqlite3_memory_highwater() 已標示為不建議使用。等效的功能現在可透過 sqlite3_status() 取得。

  5. 可以呼叫介面 sqlite3_initialize() 來明確初始化 SQLite 子系統。呼叫某些介面時會自動呼叫介面 sqlite3_initialize(),因此不需要使用 sqlite3_initialize(),但建議使用。

  6. 介面 sqlite3_shutdown() 會導致 SQLite 釋放任何系統資源(記憶體配置、mutex、開啟的檔案控制代碼),這些資源可能是由 sqlite3_initialize() 配置的。

  7. 介面 sqlite3_next_stmt() 允許應用程式找出與 資料庫連線 關聯的所有 已準備好的陳述式

  8. 新增 page_count PRAGMA 以回傳基礎資料庫檔案大小(以頁面為單位)。

  9. 新增 R*Tree 索引擴充功能

此頁面最後修改於 2022-01-08 05:02:57 UTC