注意:此文件於 2004 年撰寫,作為協助程式設計師從 SQLite 版本 2 轉移到 SQLite 版本 3 的指南。此文件中的資訊基本上仍然正確,但多年來已進行許多變更和增強。我們建議改用下列文件
SQLite 版本 3.0 是 SQLite 的新版本,源自 SQLite 2.8.13 程式碼庫,但具有不兼容的檔案格式和 API。SQLite 版本 3.0 是為了滿足對下列功能的需求而建立的
必須轉移到版本 3.0 才能實作這些功能,因為每個功能都需要對資料庫檔案格式進行不兼容的變更。其他不兼容的變更,例如清理 API,則同時在理論上進行,因為最好一次解決所有不兼容的變更。
版本 3.0 的 API 類似於版本 2.X 的 API,但有一些重要的變更。最明顯的是,所有 API 函式和資料結構開頭的「sqlite_」前綴已變更為「sqlite3_」。這可避免兩個 API 之間的混淆,並允許同時連結到 SQLite 2.X 和 SQLite 3.0。
對於 UTF-16 字串的 C 資料類型應該是什麼,目前尚未達成共識。因此,SQLite 使用 void* 的通用類型來參照 UTF-16 字串。用戶端軟體可以將 void* 轉換為適合其系統的任何資料類型。
SQLite 3.0 的 API 包含 83 個獨立函式,以及多個資料結構和 #defines。(完整的 API 參考 以獨立文件提供。)幸運的是,介面的複雜度遠低於其規模所暗示的。簡單的程式仍然可以使用只有 3 個函式:sqlite3_open()、sqlite3_exec() 和 sqlite3_close()。使用 sqlite3_prepare_v2() 將 SQLite 陳述式編譯成位元組碼,以及使用 sqlite3_step() 執行該位元組碼,可以更進一步控制資料庫引擎的執行。函式家族的名稱以 sqlite3_column_ 開頭,用於擷取查詢結果集的資訊。許多介面函式成對出現,同時具有 UTF-8 和 UTF-16 版本。此外,還有一組函式用於實作使用者定義的 SQL 函式和使用者定義的文字校對順序。
typedef struct sqlite3 sqlite3; int sqlite3_open(const char*, sqlite3**); int sqlite3_open16(const void*, sqlite3**); int sqlite3_close(sqlite3*); const char *sqlite3_errmsg(sqlite3*); const void *sqlite3_errmsg16(sqlite3*); int sqlite3_errcode(sqlite3*);
sqlite3_open() 常式會傳回整數錯誤碼,而不是版本 2 介面所傳回的 sqlite3 結構指標。sqlite3_open() 和 sqlite3_open16() 之間的差異在於,sqlite3_open16() 會將 UTF-16(以主機原生位元組順序)作為資料庫檔案的名稱。如果需要建立新的資料庫檔案,則 sqlite3_open16() 會將內部文字表示設定為 UTF-16,而 sqlite3_open() 會將文字表示設定為 UTF-8。
資料庫檔案的開啟和/或建立會延遲到實際需要檔案時才執行。這允許選項和參數(例如原生文字表示和預設頁面大小)使用 PRAGMA 陳述式來設定。
sqlite3_errcode() 常式會傳回最近一次主要 API 呼叫的結果代碼。sqlite3_errmsg() 會傳回最近一次錯誤的英文文字錯誤訊息。錯誤訊息以 UTF-8 表示,而且會是暫時的 - 它可能會在下次呼叫任何 SQLite API 函數時消失。sqlite3_errmsg16() 的運作方式與 sqlite3_errmsg() 相同,但它會傳回以 UTF-16 表示的主機原生位元組順序的錯誤訊息。
SQLite 版本 3 的錯誤代碼與版本 2 相同。如下所示
#define SQLITE_OK 0 /* Successful result */ #define SQLITE_ERROR 1 /* SQL error or missing database */ #define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ #define SQLITE_BUSY 5 /* The database file is locked */ #define SQLITE_LOCKED 6 /* A table in the database is locked */ #define SQLITE_NOMEM 7 /* A malloc() failed */ #define SQLITE_READONLY 8 /* Attempt to write a readonly database */ #define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ #define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ #define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ #define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_ROW 100 /* sqlite_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite_step() has finished executing */
typedef int (*sqlite_callback)(void*,int,char**, char**); int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);
sqlite3_exec() 函數的運作方式與 SQLite 版本 2 中的運作方式非常類似。第二個參數中指定的零個或多個 SQL 陳述式會編譯並執行。查詢結果會傳回呼叫函式。
在 SQLite 版本 3 中,sqlite3_exec 常式只是準備好的陳述式介面的呼叫包裝器。
typedef struct sqlite3_stmt sqlite3_stmt; int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**); int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**); int sqlite3_finalize(sqlite3_stmt*); int sqlite3_reset(sqlite3_stmt*);
sqlite3_prepare 介面會將單一 SQL 陳述式編譯成位元組碼以供稍後執行。此介面現在是存取資料庫的首選方式。
SQL 陳述式是 sqlite3_prepare() 的 UTF-8 字串。sqlite3_prepare16() 的運作方式相同,但它預期 UTF-16 字串作為 SQL 輸入。輸入字串中只會編譯第一個 SQL 陳述式。如果有的話,第五個參數會填入輸入字串中下一個(未編譯)SQLite 陳述式的指標。sqlite3_finalize() 常式會取消配置準備好的 SQL 陳述式。在資料庫可以關閉之前,必須取消配置所有準備好的陳述式。sqlite3_reset() 常式會重設準備好的 SQL 陳述式,以便可以再次執行。
SQL 敘述可以包含 "?" 或 "?nnn" 或 ":aaa" 形式的令牌,其中 "nnn" 是整數,而 "aaa" 是識別碼。此類令牌代表未指定的文字值(或「萬用字元」),稍後會由 sqlite3_bind 介面填入。每個萬用字元都有一個相關聯的數字,它是其在敘述中的順序,或在 "?nnn" 形式中為 "nnn"。允許同一個萬用字元在同一個 SQL 敘述中出現多次,在這種情況下,該萬用字元的每個實例都將填入相同的值。未繫結的萬用字元的值為 NULL。
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_int64(sqlite3_stmt*, int, long long int); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
有一系列 sqlite3_bind 常式可用於將值指定給已準備好 SQL 敘述中的萬用字元。未繫結的萬用字元會解釋為 NULL。sqlite3_reset() 不會重設繫結。但在 sqlite3_reset() 之後,萬用字元可以重新繫結到新的值。
在 SQL 敘述已準備好(且選擇性繫結)之後,使用以下方式執行
int sqlite3_step(sqlite3_stmt*);
如果 sqlite3_step() 常式傳回 SQLITE_ROW,表示它傳回結果集的單一行,或如果執行已完成(正常或由於錯誤),則傳回 SQLITE_DONE。如果它無法開啟資料庫檔案,它也可能會傳回 SQLITE_BUSY。如果傳回值為 SQLITE_ROW,則可以使用以下常式來擷取有關結果集該行的資訊
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); int sqlite3_column_bytes(sqlite3_stmt*, int iCol); int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); int sqlite3_column_count(sqlite3_stmt*); const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol); const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol); double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); long long int sqlite3_column_int64(sqlite3_stmt*, int iCol); const char *sqlite3_column_name(sqlite3_stmt*, int iCol); const void *sqlite3_column_name16(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_column_count() 函數傳回結果集中的欄位數目。sqlite3_column_count() 可以在 sqlite3_prepare_v2() 之後隨時呼叫。sqlite3_data_count() 的作用類似於 sqlite3_column_count(),但它僅在 sqlite3_step() 之後才有效。如果對 sqlite3_step() 的前一次呼叫傳回 SQLITE_DONE 或錯誤碼,則 sqlite3_data_count() 會傳回 0,而 sqlite3_column_count() 會繼續傳回結果集中欄位的數目。
使用其他 sqlite3_column_***() 函數檢查傳回的資料,所有函數都將欄位編號作為其第二個參數。欄位從左到右以 0 為索引。請注意,這與從 1 開始編號的參數不同。
sqlite3_column_type() 函數傳回第 N 個欄位中值的資料類型。傳回值為下列其中之一
#define SQLITE_INTEGER 1 #define SQLITE_FLOAT 2 #define SQLITE_TEXT 3 #define SQLITE_BLOB 4 #define SQLITE_NULL 5
sqlite3_column_decltype() 常式傳回 CREATE TABLE 陳述式中欄位的宣告類型。對於表達式,傳回類型為空字串。sqlite3_column_name() 傳回第 N 個欄位的名稱。sqlite3_column_bytes() 傳回類型為 BLOB 的欄位中的位元組數,或 UTF-8 編碼的 TEXT 字串中的位元組數。sqlite3_column_bytes16() 對 BLOB 傳回相同的值,但對 TEXT 字串傳回 UTF-16 編碼中的位元組數。sqlite3_column_blob() 傳回 BLOB 資料。sqlite3_column_text() 傳回 TEXT 資料作為 UTF-8。sqlite3_column_text16() 傳回 TEXT 資料作為 UTF-16。sqlite3_column_int() 傳回主機電腦原生整數格式中的 INTEGER 資料。sqlite3_column_int64() 傳回 64 位元 INTEGER 資料。最後,sqlite3_column_double() 傳回浮點資料。
不需要以 sqlite3_column_type() 指定的格式擷取資料。如果要求不同的格式,資料會自動轉換。
資料格式轉換會使先前呼叫 sqlite3_column_blob()、sqlite3_column_text() 和/或 sqlite3_column_text16() 傳回的指標失效。指標可能會在以下情況下失效
初始內容為 BLOB,且呼叫 sqlite3_column_text() 或 sqlite3_column_text16()。可能需要將零終結符號新增到字串中。
初始內容為 UTF-8 文字,且呼叫 sqlite3_column_bytes16() 或 sqlite3_column_text16()。必須將內容轉換為 UTF-16。
初始內容是 UTF-16 文字,且呼叫 sqlite3_column_bytes() 或 sqlite3_column_text()。內容必須轉換為 UTF-8。
請注意,UTF-16be 和 UTF-16le 之間的轉換總是就地進行,且不會使先前的指標失效,儘管先前指標指向的緩衝區內容當然會被修改。其他類型的轉換在可能的情況下會就地進行,但有時無法進行,在這些情況下,先前的指標會失效。
最安全且最容易記住的政策是:假設任何結果來自
可以使用下列常式建立使用者定義函式
typedef struct sqlite3_value sqlite3_value; int sqlite3_create_function( sqlite3 *, const char *zFunctionName, int nArg, int eTextRep, void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3*, const void *zFunctionName, int nArg, int eTextRep, void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); #define SQLITE_UTF8 1 #define SQLITE_UTF16 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16LE 4 #define SQLITE_ANY 5
nArg 參數指定函式的引數數量。值 0 表示允許任何數量的引數。eTextRep 參數指定此函式引數預期的文字值表示形式。此參數的值應為上述定義的參數之一。SQLite 版本 3 允許使用不同的文字表示形式來實作相同函式的多個實作。資料庫引擎會選擇需要最少文字轉換的函式。
一般函式只指定 xFunc,並將 xStep 和 xFinal 設定為 NULL。聚合函式指定 xStep 和 xFinal,並將 xFunc 設定為 NULL。沒有單獨的 sqlite3_create_aggregate() API。
函數名稱以 UTF-8 指定。另一個 sqlite3_create_function16() API 的運作方式與 sqlite_create_function() 相同,只不過函數名稱以 UTF-16 主機位元組順序指定。
請注意,函數的參數現在是指向 sqlite3_value 結構的指標,而不是指向字串的指標,如同 SQLite 版本 2.X。下列常式用於從這些「值」中擷取有用的資訊
const void *sqlite3_value_blob(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); long long int sqlite3_value_int64(sqlite3_value*); const unsigned char *sqlite3_value_text(sqlite3_value*); const void *sqlite3_value_text16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*);
函數實作使用下列 API 來取得內容和回報結果
void *sqlite3_aggregate_context(sqlite3_context*, int nbyte); void *sqlite3_user_data(sqlite3_context*); void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, long long int); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*)); void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); void *sqlite3_get_auxdata(sqlite3_context*, int); void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
下列常式用於實作使用者定義的排序規則
sqlite3_create_collation(sqlite3*, const char *zName, int eTextRep, void*, int(*xCompare)(void*,int,const void*,int,const void*)); sqlite3_create_collation16(sqlite3*, const void *zName, int eTextRep, void*, int(*xCompare)(void*,int,const void*,int,const void*)); sqlite3_collation_needed(sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*)); sqlite3_collation_needed16(sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*));
sqlite3_create_collation() 函數指定排序規則名稱和比較函數來實作該排序規則。比較函數僅用於比較文字值。eTextRep 參數是 SQLITE_UTF8、SQLITE_UTF16LE、SQLITE_UTF16BE 或 SQLITE_ANY 之一,用於指定比較函數運作的文字表示法。對於 UTF-8、UTF-16LE 和 UTF-16BE 文字表示法,相同的排序規則可以有不同的比較函數。sqlite3_create_collation16() 的運作方式與 sqlite3_create_collation() 相同,只不過排序規則名稱以 UTF-16 主機位元組順序指定,而不是以 UTF-8 指定。
sqlite3_collation_needed() 常式註冊一個回呼,如果資料庫引擎遇到未知的排序規則,它會呼叫此回呼。回呼可以查詢適當的比較函數,並視需要呼叫 sqlite_3_create_collation()。回呼的第四個參數是 UTF-8 中的排序規則名稱。對於 sqlite3_collation_need16(),回呼會以 UTF-16 主機位元組順序傳送排序規則名稱。
此頁面最後修改於 2022-01-08 05:02:57 UTC