注意:本文档于 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 个独立的函数,以及几个数据结构和 #define。(完整的 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 语句编译成字节码以供以后执行。此接口现在是访问数据库的首选方式。
对于 sqlite3_prepare(),SQL 语句是 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_prepare_v2() 之后随时调用 sqlite3_column_count()。 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() 以 UTF-8 返回 TEXT 数据。sqlite3_column_text16() 以 UTF-16 返回 TEXT 数据。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