SQLite 的 C 语言接口规范

此页面旨在提供精确而详细的规范。有关教程介绍,请参阅:

同样的内容也可以拆分成 许多小页面


实验性和弃用的接口

SQLite接口可以细分为三类:

  1. 稳定的
  2. 实验性的
  3. 弃用

稳定的接口将以向后兼容的方式无限期维护。仅使用稳定接口的应用程序应该始终能够重新链接到更新版本的 SQLite,而无需进行任何更改。

实验界面可能会发生变化。使用实验性接口的应用程序在升级到较新的 SQLite 版本时可能需要进行修改,尽管这种情况很少见。当新接口添加到 SQLite 时,它​​们通常以实验接口开始。当一个接口使用了一段时间后,开发人员确信接口的设计是合理的,值得长期支持,这个接口就被标记为稳定的。

已弃用的接口已被更好的方法所取代,可以完成相同的事情,在新的应用程序中应该避免使用。为了向后兼容,继续支持已弃用的接口。在将来的某个时候,可能会删除已弃用的接口。

关键点:


对象列表:


常量列表:

也可用:错误代码列表


功能列表:

注意:标有“ (exp) ”的函数是实验性的,名称中带有 删除线的函数已弃用


虚拟表扫描标志

#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */

允许虚拟表实现将 sqlite3_index_info .idxFlags 字段设置为这些位的某种组合。


sqlite3_serialize 的标志

#define SQLITE_SERIALIZE_NOCOPY 0x001   /* Do no memory allocations */

对于sqlite3_serialize(D,S,P,F) 的 F 参数,可以对以下零个或多个常量进行“或”运算

SQLITE_SERIALIZE_NOCOPY 意味着sqlite3_serialize()将返回一个指向它当前正在使用的连续内存数据库的指针,而不制作数据库的副本。如果 SQLite 当前未使用连续的内存数据库,则此选项会导致 sqlite3_serialize()返回 NULL 指针。如果 SQLite 已通过先前调用sqlite3_deserialize()进行了初始化,则它只会使用连续的内存数据库


最大 xShmLock 索引

#define SQLITE_SHM_NLOCK        8

sqlite3_io_methods 上的 xShmLock 方法可以使用 0 和此上限之间的值作为其“偏移量”参数。SQLite 核心永远不会尝试获取或释放此范围之外的锁


可加载扩展 Thunk

typedef struct sqlite3_api_routines sqlite3_api_routines;

指向不透明 sqlite3_api_routines 结构的指针作为第三个参数传递给可加载扩展的入口点。必须对该结构进行类型定义,以解决某些平台上的编译器警告。


在线备份对象

typedef struct sqlite3_backup sqlite3_backup;

sqlite3_backup 对象记录有关正在进行的在线备份操作的状态信息。sqlite3_backup 对象通过调用 sqlite3_backup_init() 创建,并通过调用sqlite3_backup_finish ()销毁

另请参阅:使用 SQLite 在线备份 API


SQL 函数上下文对象

typedef struct sqlite3_context sqlite3_context;

SQL 函数执行的上下文存储在 sqlite3_context 对象中。指向 sqlite3_context 对象的指针始终是应用程序定义的 SQL 函数的第一个参数。应用程序定义的 SQL 函数实现会将此指针传递给对sqlite3_result()sqlite3_aggregate_context()sqlite3_user_data()sqlite3_context_db_handle()sqlite3_get_auxdata()和/或sqlite3_set_auxdata()的调用。

26种方法:


保存数据库文件的文件夹的名称

SQLITE_EXTERN char *sqlite3_data_directory;

如果这个全局变量指向一个字符串,它是一个文件夹(又名目录)的名称,那么所有使用相对路径名指定并在使用内置 Windows VFS时由 SQLite 创建或访问的数据库文件将被假定为相对于该目录。如果此变量是 NULL 指针,则 SQLite 假定所有使用相对路径名指定的数据库文件都相对于进程的当前目录。只有 Windows VFS 使用这个全局变量;它被 unix VFS 忽略。

在数据库连接打开时更改此变量的值可能会导致数据库损坏。

一次在多个线程中读取或修改此变量是不安全的。如果在单独的线程中同时使用数据库连接,则读取或修改此变量是不安全的。旨在将此变量设置为进程初始化的一部分,并在调用任何 SQLite 接口例程之前设置一次,此后此变量保持不变。

data_store_directory pragma可能会修改此变量并使其指向从sqlite3_malloc获得的内存。此外,data_store_directory pragma始终假定此变量指向的任何字符串都保存在从 sqlite3_malloc获得的内存中,并且 pragma 可能会尝试使用sqlite3_free释放该内存。因此,如果直接修改此变量,则应将其设置为 NULL 或指向从sqlite3_malloc获得的内存, 否则应避免 使用data_store_directory pragma 。


操作系统接口打开文件句柄

typedef struct sqlite3_file sqlite3_file;
struct sqlite3_file {
  const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
};

sqlite3_file对象表示 操作系统接口层中打开 的文件各个 OS 接口实现将希望通过附加其他字段来子类化该对象以供自己使用。pMethods 条目是一个指向 sqlite3_io_methods对象的指针,该对象定义了对打开的文件执行 I/O 操作的方法。


虚拟表索引信息

struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column constrained.  -1 for ROWID */
     unsigned char op;         /* Constraint operator */
     unsigned char usable;     /* True if this constraint is usable */
     int iTermOffset;          /* Used internally - xBestIndex should ignore */
  } *aConstraint;            /* Table of WHERE clause constraints */
  int nOrderBy;              /* Number of terms in the ORDER BY clause */
  struct sqlite3_index_orderby {
     int iColumn;              /* Column number */
     unsigned char desc;       /* True for DESC.  False for ASC. */
  } *aOrderBy;               /* The ORDER BY clause */
  /* Outputs */
  struct sqlite3_index_constraint_usage {
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;           /* Estimated cost of using this index */
  /* Fields below are only available in SQLite 3.8.2 and later */
  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
  /* Fields below are only available in SQLite 3.9.0 and later */
  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
  /* Fields below are only available in SQLite 3.10.0 and later */
  sqlite3_uint64 colUsed;    /* Input: Mask of columns used by statement */
};

sqlite3_index_info 结构及其子结构用作虚拟表接口的一部分,用于将信息传递到虚拟表模块的xBestIndex 方法并从中接收回复**Inputs** 下的字段是 xBestIndex 的输入并且是只读的。xBestIndex 将其结果插入 **Outputs** 字段。

aConstraint[] 数组记录以下形式的 WHERE 子句约束:

列 OP 表达式

其中 OP 是 =、<、<=、> 或 >=。特定运算符使用SQLITE_INDEX_CONSTRAINT_ 值之一存储在 aConstraint[].op 中 列的索引存储在 aConstraint[].iColumn 中。aConstraint[].usable 如果可以计算右侧的 expr(因此约束可用),则为 TRUE,如果不能,则为 false。

优化器自动反转“expr OP column”形式的术语并对 WHERE 子句进行其他简化,以尝试将尽可能多的 WHERE 子句术语放入上面显示的形式中。aConstraint[] 数组仅报告与正在查询的特定虚拟表相关的 WHERE 子句术语。

有关 ORDER BY 子句的信息存储在 aOrderBy[] 中。aOrderBy 的每一项记录 ORDER BY 子句的一列。

colUsed 字段指示当前扫描可能需要虚拟表的哪些列。虚拟表列按照它们在传递给 sqlite3_declare_vtab() 的 CREATE TABLE 语句中出现的顺序从零开始编号。对于前 63 列(0-62 列),如果 SQLite 可能需要该列,则在 colUsed 掩码中设置相应的位。如果该表至少有 64 列,并且需要前 63 列右侧的任何列,则还会设置 colUsed 的第 63 位。换句话说,如果表达式 (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) 计算结果为非零,则可能需要列 iCol。

xBestIndex方法必须使用有关要传递给 xFilter 的参数的信息填充 aConstraintUsage[]。如果 argvIndex>0,则评估相应 aConstraint[] 的右侧并成为 argv 中的第 argvIndex 项。如果 aConstraintUsage[].omit 为 true,则假定约束完全由虚拟表处理,字节代码可能不会再次检查。aConstraintUsage[].omit 标志是一个优化提示。当 omit 标志保留其默认设置 false 时,将始终在字节代码中单独检查约束。如果 omit 标志更改为 true,则可能会或可能不会在字节代码中检查约束。换句话说,当 omit 标志为真时,不能保证不会使用字节代码再次检查约束。

idxNum 和 idxPtr 值被记录并传递给 xFilter方法。 当且仅当 needToFreeIdxPtr 为真时, sqlite3_free()用于释放 idxPtr。

orderByConsumed 意味着xFilter / xNext的输出将以正确的顺序出现以满足 ORDER BY 子句,因此不需要单独的排序步骤。

estimatedCost 值是对特定策略成本的估计。成本 N 表示该策略的成本类似于具有 N 行的 SQLite 表的线性扫描。log(N) 的成本表示该操作的开销类似于对具有 N 行的 SQLite 表的唯一索引字段进行二进制搜索的开销。

estimatedRows 值是策略将返回的行数的估计值。

xBestIndex 方法可以选择使用 SQLITE_INDEX_SCAN_* 标志的掩码填充 idxFlags 字段。目前只有一个这样的标志——SQLITE_INDEX_SCAN_UNIQUE。如果 xBestIndex 方法设置了这个标志,SQLite 假定该策略最多可以访问一行。

此外,如果 xBestIndex 设置了 SQLITE_INDEX_SCAN_UNIQUE 标志,则 SQLite 还假设如果调用 xUpdate() 方法作为删除或更新虚拟表行的同一语句的一部分并且实现返回 SQLITE_CONSTRAINT,则不需要回滚任何数据库更改。换句话说,如果 xUpdate() 返回 SQLITE_CONSTRAINT,则数据库内容必须与调用 xUpdate 之前完全相同。相反,如果未设置 SQLITE_INDEX_SCAN_UNIQUE 并且 xUpdate 返回 SQLITE_CONSTRAINT,则 xUpdate 方法所做的任何数据库更改都会由 SQLite 自动回滚。

重要提示:已将 estimatedRows 字段添加到 SQLite版本 3.8.2 (2013-12-06)的 sqlite3_index_info 结构中。如果虚拟表扩展与 3.8.2 之前的 SQLite 版本一起使用,则尝试读取或写入 estimatedRows 字段的结果是未定义的(但可能包括使应用程序崩溃)。因此,只有当sqlite3_libversion_number()返回的值大于或等于 3008002 时,才应使用 estimatedRows 字段。同样,idxFlags 字段是为版本 3.9.0 (2015-10-14) 添加的。因此,它只能在 sqlite3_libversion_number() 返回大于或等于 3009000 的值时使用。

3 个方法: sqlite3_vtab_collat​​ion()sqlite3_vtab_distinct()sqlite3_vtab_rhs_value()


操作系统接口文件虚拟方法对象

typedef struct sqlite3_io_methods sqlite3_io_methods;
struct sqlite3_io_methods {
  int iVersion;
  int (*xClose)(sqlite3_file*);
  int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
  int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
  int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
  int (*xSync)(sqlite3_file*, int flags);
  int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
  int (*xLock)(sqlite3_file*, int);
  int (*xUnlock)(sqlite3_file*, int);
  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
  int (*xFileControl)(sqlite3_file*, int op, void *pArg);
  int (*xSectorSize)(sqlite3_file*);
  int (*xDeviceCharacteristics)(sqlite3_file*);
  /* Methods above are valid for version 1 */
  int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
  int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
  void (*xShmBarrier)(sqlite3_file*);
  int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
  /* Methods above are valid for version 2 */
  int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
  int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p);
  /* Methods above are valid for version 3 */
  /* Additional methods may be added in future releases */
};

sqlite3_vfs.xOpen方法 打开的每个文件都会填充一个 sqlite3_file对象(或者,更常见的是, sqlite3_file对象的子类),并带有指向该对象实例的指针。该对象定义了用于对sqlite3_file对象表示的打开文件执行各种操作的方法。

如果sqlite3_vfs.xOpen方法将 sqlite3_file.pMethods 元素设置为非 NULL 指针,则即使sqlite3_vfs.xOpen报告失败,也可以调用 sqlite3_io_methods.xClose 方法。阻止在sqlite3_vfs.xOpen失败后调用 xClose 的唯一方法 是让sqlite3_vfs.xOpen将 sqlite3_file.pMethods 元素设置为 NULL。

xSync 的标志参数可以是SQLITE_SYNC_NORMALSQLITE_SYNC_FULL 之一第一个选择是普通的 fsync()。第二个选择是 Mac OS X 风格的全同步。SQLITE_SYNC_DATAONLY标志可以进行ORed ,以指示只需要同步文件的数据而不是其 inode。

xLock() 和 xUnlock() 的整数值是其中之一

xLock() 增加锁。xUnlock() 减少锁定。xCheckReservedLock() 方法检查此进程或其他进程中的任何数据库连接是否持有文件上的 RESERVED、PENDING 或 EXCLUSIVE 锁。如果存在这样的锁,则返回 true,否则返回 false。

xFileControl() 方法是一个通用接口,允许自定义 VFS 实现使用 sqlite3_file_control()接口直接控制打开的文件。第二个“op”参数是一个整数操作码。第三个参数是一个通用指针,旨在指向一个结构,该结构可能包含参数或用于写入返回值的空间。xFileControl() 的潜在用途可能是启用超时阻塞锁、更改锁定策略(例如使用点文件锁)、查询锁的状态或打破陈旧锁的功能。SQLite 核心保留所有小于 100 的操作码供自己使用。操作码列表少于 100 个可用。定义自定义 xFileControl 方法的应用程序应使用大于 100 的操作码以避免冲突。VFS 实现应该为它们不识别的文件控制操作码返回SQLITE_NOTFOUND 。

xSectorSize() 方法返回作为文件基础的设备的扇区大小。扇区大小是在不影响文件中其他字节的情况下可以执行的最小写入。xDeviceCharacteristics() 方法返回一个描述底层设备行为的位向量:

SQLITE_IOCAP_ATOMIC 属性意味着任何大小的所有写入都是原子的。SQLITE_IOCAP_ATOMICnnn 值意味着写入大小为 nnn 字节且与 nnn 的整数倍地址对齐的块是原子的。SQLITE_IOCAP_SAFE_APPEND 值意味着当数据附加到文件时,首先附加数据,然后扩展文件的大小,而不是相反。SQLITE_IOCAP_SEQUENTIAL 属性意味着信息写入磁盘的顺序与调用 xWrite() 的顺序相同。

如果 xRead() 返回 SQLITE_IOERR_SHORT_READ,它还必须用零填充缓冲区的未读部分。无法对短读取进行零填充的 VFS 似乎可以工作。但是,未能对短读取进行零填充最终会导致数据库损坏。


内存分配例程

typedef struct sqlite3_mem_methods sqlite3_mem_methods;
struct sqlite3_mem_methods {
  void *(*xMalloc)(int);         /* Memory allocation function */
  void (*xFree)(void*);          /* Free a prior allocation */
  void *(*xRealloc)(void*,int);  /* Resize an allocation */
  int (*xSize)(void*);           /* Return the size of an allocation */
  int (*xRoundup)(int);          /* Round up request size to allocation size */
  int (*xInit)(void*);           /* Initialize the memory allocator */
  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
  void *pAppData;                /* Argument to xInit() and xShutdown() */
};

该对象的实例定义了 SQLite 和低级内存分配例程之间的接口。

该对象仅在 SQLite 界面中的一个地方使用。当配置选项为 SQLITE_CONFIG_MALLOCSQLITE_CONFIG_GETMALLOC时,指向该对象实例的指针是 sqlite3_config()的参数。通过创建该对象的一个​​实例并在配置期间将其传递给sqlite3_config ( SQLITE_CONFIG_MALLOC ),应用程序可以为 SQLite 指定一个替代内存分配子系统以用于其所有动态内存需求。

请注意,SQLite 带有几个内置的内存分配器 ,这些内存分配器完全适合绝大多数应用程序,并且该对象仅对极少数具有专门内存分配要求的应用程序有用。在测试 SQLite 期间也使用此对象,以指定模拟内存耗尽情况的替代内存分配器,以验证 SQLite 是否从此类情况中正常恢复。

xMalloc、xRealloc 和 xFree 方法必须像标准 C 库中的 malloc()、realloc() 和 free() 函数一样工作。SQLite 保证 xRealloc 的第二个参数始终是先前调用 xRoundup 返回的值。

xSize 应返回先前从 xMalloc 或 xRealloc 获得的内存分配的分配大小。分配的大小始终至少与请求的大小一样大,但也可能更大。

xRoundup 方法返回给定特定请求大小的内存分配的分配大小。大多数内存分配器将内存分配至少舍入到 8 的下一个倍数。一些分配器舍入到更大的倍数或 2 的幂。通过sqlite3_malloc()sqlite3_realloc()进入的每个内存分配请求首先调用 xRoundup。如果 xRoundup 返回 0,则会导致相应的内存分配失败。

xInit 方法初始化内存分配器。例如,它可能会分配任何所需的互斥体或初始化内部数据结构。xShutdown 方法由 sqlite3_shutdown()调用(间接)并且应该释放 xInit 获取的任何资源。pAppData 指针用作 xInit 和 xShutdown 的唯一参数。

SQLite 在调用 xInit 方法时持有SQLITE_MUTEX_STATIC_MAIN互斥量,因此 xInit 方法不需要是线程安全的。xShutdown 方法仅从sqlite3_shutdown()调用,因此它也不需要是线程安全的。对于所有其他方法,只要 打开SQLITE_CONFIG_MEMSTATUS配置选项(默认情况下),SQLite 就会持有SQLITE_MUTEX_STATIC_MEM互斥体,因此这些方法会自动序列化。但是,如果SQLITE_CONFIG_MEMSTATUS被禁用,那么其他方法必须是线程安全的,否则会自行安排序列化。

如果没有对 xShutdown() 的干预调用,SQLite 将永远不会多次调用 xInit()。


互斥句柄

typedef struct sqlite3_mutex sqlite3_mutex;

SQLite 中的互斥模块将sqlite3_mutex定义为互斥对象的抽象类型。SQLite 核心从不查看sqlite3_mutex的内部表示它只处理指向sqlite3_mutex对象的指针。

互斥量是使用sqlite3_mutex_alloc()创建的。


互斥方法对象

typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
struct sqlite3_mutex_methods {
  int (*xMutexInit)(void);
  int (*xMutexEnd)(void);
  sqlite3_mutex *(*xMutexAlloc)(int);
  void (*xMutexFree)(sqlite3_mutex *);
  void (*xMutexEnter)(sqlite3_mutex *);
  int (*xMutexTry)(sqlite3_mutex *);
  void (*xMutexLeave)(sqlite3_mutex *);
  int (*xMutexHeld)(sqlite3_mutex *);
  int (*xMutexNotheld)(sqlite3_mutex *);
};

该结构的一个实例定义了用于分配和使用互斥量的低级例程。

通常,SQLite 提供的默认互斥锁实现就足够了,但是应用程序可以选择用自定义实现替换 SQLite 未提供合适实现的专用部署或系统。在这种情况下,应用程序创建并填充此结构的实例以传递给 sqlite3_config() 以及SQLITE_CONFIG_MUTEX选项。此外,在使用SQLITE_CONFIG_GETMUTEX选项查询系统当前互斥锁实现时,此结构的实例可用作输出变量。

此结构定义的 xMutexInit 方法作为系统初始化的一部分由 sqlite3_initialize() 函数调用。每次有效调用sqlite3_initialize()时,SQLite 只调用一次 xMutexInit 例程

此结构定义的 xMutexEnd 方法作为系统关闭的一部分由 sqlite3_shutdown() 函数调用。此方法的实现预计会释放所有由互斥方法实现获得的未完成资源,尤其是那些由 xMutexInit 方法获得的资源。每次调用sqlite3_shutdown()时,xMutexEnd() 接口只被调用一次

该结构定义的其余七个方法(xMutexAlloc、xMutexFree、xMutexEnter、xMutexTry、xMutexLeave、xMutexHeld和xMutexNotheld)实现了以下接口(分别):

唯一的区别是上面列举的公共 sqlite3_XXX 函数默默地忽略任何传递 NULL 指针而不是有效互斥句柄的调用。此结构定义的方法的实现不需要处理这种情况。传递一个 NULL 指针而不是一个有效的互斥句柄的结果是未定义的(即,如果它被传递一个 NULL 指针,则提供一个段错误的实现是可以接受的)。

xMutexInit() 方法必须是线程安全的。在同一个进程中多次调用 xMutexInit() 并且不干预对 xMutexEnd() 的调用一定是无害的。对 xMutexInit() 的第二次和后续调用必须是空操作。

xMutexInit() 不得使用 SQLite 内存分配(sqlite3_malloc() 及其关联)。同样,xMutexAlloc() 不得将 SQLite 内存分配用于静态互斥锁。但是 xMutexAlloc() 可以使用 SQLite 内存分配来实现快速或递归互斥锁。

SQLite 将在调用sqlite3_shutdown()时调用 xMutexEnd() 方法,但前提是先前对 xMutexInit 的调用返回了 SQLITE_OK。如果 xMutexInit 以任何方式失败,它应该在返回之前自行清理。


自定义页面缓存对象

typedef struct sqlite3_pcache sqlite3_pcache;

sqlite3_pcache 类型是不透明的。它由可插拔模块实现。SQLite 核心不知道它的大小或内部结构,除了保存和传递指向对象的指针外,从不处理 sqlite3_pcache 对象。

有关其他信息,请参阅sqlite3_pcache_methods2


自定义页面缓存对象

typedef struct sqlite3_pcache_page sqlite3_pcache_page;
struct sqlite3_pcache_page {
  void *pBuf;        /* The content of the page */
  void *pExtra;      /* Extra information associated with the page */
};

sqlite3_pcache_page 对象表示页面缓存中的单个页面。页面缓存将分配该对象的实例。页面缓存的各种方法使用指向该对象实例的指针作为参数或作为它们的返回值。

有关其他信息,请参阅sqlite3_pcache_methods2


存放临时文件的文件夹名称

SQLITE_EXTERN char *sqlite3_temp_directory;

如果这个全局变量指向一个字符串,它是一个文件夹(又名目录)的名称,那么 SQLite 在使用内置VFS时创建的所有临时文件 都将放在该目录中。如果这个变量是一个 NULL 指针,那么 SQLite 会搜索一个合适的临时文件目录。

强烈建议不要使用此全局变量。需要在 Windows 运行时 (WinRT) 上设置一个临时文件夹。但对于所有其他平台,强烈建议应用程序既不读取也不写入此变量。这个全局变量是为了遗留应用程序的向后兼容性而存在的遗物,在新项目中应该避免使用。

一次在多个线程中读取或修改此变量是不安全的。如果在单独的线程中同时使用数据库连接,则读取或修改此变量是不安全的。旨在将此变量设置为进程初始化的一部分,并在调用任何 SQLite 接口例程之前设置一次,此后此变量保持不变。

temp_store_directory pragma可能会修改此变量并使其指向从sqlite3_malloc获得的内存此外,temp_store_directory pragma始终假定此变量指向的任何字符串都保存在从 sqlite3_malloc获得的内存中,并且 pragma 可能会尝试使用sqlite3_free释放该内存。因此,如果直接修改此变量,则应将其设置为 NULL 或指向从sqlite3_malloc获得的内存, 否则应避免使用temp_store_directory pragma 。除非temp_store_directory pragma请求, SQLite 不会释放 sqlite3_temp_directory 指向的内存。如果应用程序想要释放该内存,它必须自己这样做,注意只有在所有数据库连接 对象都被销毁后才这样做。

Windows 运行时用户请注意: 必须在调用sqlite3_opensqlite3_open_v2之前设置临时目录。否则,需要使用临时文件的各种功能可能会失败。以下是如何使用 C++ 和 Windows 运行时执行此操作的示例:

LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
      TemporaryFolder->Path->Data();
char zPathBuf[MAX_PATH + 1];
memset(zPathBuf, 0, sizeof(zPathBuf));
WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
      NULL, NULL);
sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);


操作系统接口对象

typedef struct sqlite3_vfs sqlite3_vfs;
typedef void (*sqlite3_syscall_ptr)(void);
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 3) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
  const char *zName;       /* Name of this virtual file system */
  void *pAppData;          /* Pointer to application-specific data */
  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
               int flags, int *pOutFlags);
  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
  int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
  void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
  void (*xDlClose)(sqlite3_vfs*, void*);
  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** Those below are for version 3 and greater.
  */
  int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
  sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  /*
  ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  ** New fields may be appended in future versions.  The iVersion
  ** value will increment whenever this happens.
  */
};

sqlite3_vfs 对象的实例定义了 SQLite 核心和底层操作系统之间的接口。对象名称中的“vfs”代表“虚拟文件系统”。有关详细信息,请参阅VFS 文档

VFS 接口有时会通过在末尾添加新方法来扩展。每次发生这样的扩展时,iVersion 字段都会递增。iVersion 值在 2007-09-04 的 SQLite版本 3.5.0中开始为 1 ,然后在 2010-07-21 的 SQLite版本 3.7.0中增加到 2,然后在 2011 年的 SQLite版本 3.7.6中增加到 3 -04-12。附加字段可能会附加到 sqlite3_vfs 对象,并且 iVersion 值可能会在 SQLite 的未来版本中再次增加。请注意,由于疏忽,sqlite3_vfs 对象的结构在 2008 年 7 月 16 日从 SQLite 3.5.9版过渡到3.6.0版时发生了变化,但 iVersion 字段没有增加。

szOsFile 字段是 此 VFS 使用的子类sqlite3_file结构的大小。mxPathname 是此 VFS 中路径名的最大长度。

已注册的 sqlite3_vfs 对象保存在由 pNext 指针形成的链表中。sqlite3_vfs_register()sqlite3_vfs_unregister()接口以线程安全的方式管理这个列表。sqlite3_vfs_find()接口搜索列表。应用程序代码和 VFS 实现都不应该使用 pNext 指针。

pNext 字段是 SQLite 将永远修改的 sqlite3_vfs 结构中的唯一字段。SQLite 将仅在持有特定静态互斥锁时访问或修改此字段。对象注册后,应用程序永远不应修改 sqlite3_vfs 对象中的任何内容。

zName 字段包含 VFS 模块的名称。该名称在所有 VFS 模块中必须是唯一的。

SQLite 保证 xOpen 的 zFilename 参数是 NULL 指针或从 xFullPathname() 获得的字符串,并添加了可选的后缀。如果将后缀添加到 zFilename 参数,它将由一个“-”字符后跟不超过 11 个字母数字和/或“-”字符组成。SQLite 进一步保证在调用 xClose() 之前字符串有效且不变。由于前面的句子,如果出于某种原因需要记住文件名, sqlite3_file可以安全地存储指向文件名的指针。如果 xOpen 的 zFilename 参数是 NULL 指针,则 xOpen 必须为该文件创建自己的临时名称。.

xOpen() 的标志参数包括在sqlite3_open_v2()的标志参数中设置的所有位。或者,如果使用sqlite3_open()sqlite3_open16(),则标志至少包括 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE如果 xOpen() 以只读方式打开文件,则它会将 *pOutFlags 设置为包含SQLITE_OPEN_READONLY*pOutFlags 中的其他位可能会被设置。

SQLite 还会将以下标志之一添加到 xOpen() 调用中,具体取决于正在打开的对象:

文件 I/O 实现可以使用对象类型标志来改变它处理文件的方式。例如,不关心崩溃恢复或回滚的应用程序可能会使打开日志文件成为空操作。写入该日志也将是空操作,任何读取该日志的尝试都将返回 SQLITE_IOERR。或者实现可能会识别出数据库文件将以随机顺序进行页面对齐的扇区读取和写入,并相应地设置其 I/O 子系统。

SQLite 还可能将以下标志之一添加到 xOpen 方法中:

SQLITE_OPEN_DELETEONCLOSE标志意味着文件在关闭时应该被删除。SQLITE_OPEN_DELETEONCLOSE将为 TEMP 数据库及其日志、临时数据库和子日志设置。

SQLITE_OPEN_EXCLUSIVE标志总是与 SQLITE_OPEN_CREATE 标志结合使用它们都直接类似于 POSIX open() API 的 O_EXCL 和 O_CREAT 标志。SQLITE_OPEN_EXCLUSIVE 标志与 SQLITE_OPEN_CREATE 配对时,用于指示应始终创建文件,如果文件已经存在则为错误。用于指示文件应该以独占访问方式打开。

SQLite 至少分配了 szOsFile 字节的内存来保存作为第三个参数传递给 xOpen的sqlite3_file结构。xOpen 方法不必分配结构;它应该只是填写它。请注意,xOpen 方法必须将 sqlite3_file.pMethods 设置为有效的sqlite3_io_methods对象或 NULL。即使打开失败,xOpen 也必须这样做。SQLite 期望 sqlite3_file.pMethods 元素在 xOpen 返回后有效,而不管 xOpen 调用成功或失败。

xAccess() 的 flags 参数可以是SQLITE_ACCESS_EXISTS 来测试文件是否存在,或者是SQLITE_ACCESS_READWRITE来测试文件是否可读和可写,或者是SQLITE_ACCESS_READ 来测试文件是否至少可读。SQLITE_ACCESS_READ 标志从未实际使用过,也没有在 SQLite 的内置 VFS 中实现。该文件由第二个参数命名,可以是一个目录。xAccess 方法在成功时返回SQLITE_OK,如果出现 I/O 错误或第二个参数中给出的文件名非法,则返回一些非零错误代码。如果返回 SQLITE_OK,则将非零或零写入 *pResOut 以指示文件是否可访问。

SQLite 将始终为输出缓冲区 xFullPathname 分配至少 mxPathname+1 个字节。输出缓冲区的确切大小也作为参数传递给这两种方法。如果输出缓冲区不够大,则应返回SQLITE_CANTOPEN 。由于 SQLite 将此作为致命错误处理,因此 vfs 实现应努力通过将 mxPathname 设置为足够大的值来防止这种情况发生。

xRandomness()、xSleep()、xCurrentTime() 和 xCurrentTimeInt64() 接口严格来说并不是文件系统的一部分,但为了完整性,它们包含在 VFS 结构中。xRandomness() 函数尝试将 nBytes 字节的高质量随机性返回到 zOut。返回值是实际得到的随机字节数。xSleep() 方法使调用线程至少休眠指定的微秒数。xCurrentTime() 方法返回当前日期和时间的 Julian Day Number 作为浮点值。xCurrentTimeInt64() 方法以整数形式返回儒略日数乘以 86400000(一天 24 小时的毫秒数)。

SQLite 核心不使用 xSetSystemCall()、xGetSystemCall() 和 xNestSystemCall() 接口。这些可选接口由一些 VFS 提供,以方便测试 VFS 代码。通过用其控制下的功能覆盖系统调用,测试程序可以模拟故障和错误条件,否则很难或不可能诱发。可以覆盖的系统调用集因一个 VFS 而异,也因同一 VFS 的一个版本而异。使用这些接口的应用程序必须为任何或所有这些接口为 NULL 或它们的行为从一个版本更改为下一个版本做好准备。如果 VFS 的 iVersion 小于 3,应用程序不得尝试访问这些方法中的任何一个。


虚拟表实例对象

struct sqlite3_vtab {
  const sqlite3_module *pModule;  /* The module for this virtual table */
  int nRef;                       /* Number of open cursors */
  char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
  /* Virtual table implementations will typically add additional fields */
};

每个虚拟表模块实现都使用此对象的子类来描述虚拟表的特定实例每个子类都将根据模块实现的特定需求进行定制。这个超类的目的是定义所有模块实现共有的某些字段。

虚拟表方法可以通过将从sqlite3_mprintf()获得的字符串分配给 zErrMsg来设置错误消息。该方法应注意 在将新字符串分配给 zErrMsg 之前调用sqlite3_free()释放任何先前的字符串。错误消息传递到客户端应用程序后,字符串将由 sqlite3_free() 自动释放,并且 zErrMsg 字段将清零。


获取聚合函数上下文

void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);

聚合 SQL 函数的实现使用此例程来分配内存来存储它们的状态。

第一次为特定聚合函数调用 sqlite3_aggregate_context(C,N) 例程时,SQLite 分配 N 字节内存,将该内存清零,并返回指向新内存的指针。在为同一聚合函数实例第二次和后续调用 sqlite3_aggregate_context() 时,将返回相同的缓冲区。Sqlite3_aggregate_context() 通常在每次调用 xStep 回调时调用一次,然后在调用 xFinal 回调时调用最后一次。当没有行与聚合查询匹配时,永远不会调用聚合函数实现的 xStep() 回调,并且只调用一次 xFinal()。在这些情况下,可能会在 xFinal() 中首次调用 sqlite3_aggregate_context()。

如果 N 小于或等于零,或者发生内存分配错误,则 sqlite3_aggregate_context(C,N) 例程在首次调用时返回 NULL 指针。

sqlite3_aggregate_context(C,N) 分配的空间量由第一次成功调用时的 N 参数决定。在同一聚合函数实例中对 sqlite3_aggregate_context() 的任何后续调用中更改 N 的值将不会调整内存分配的大小。在 xFinal 回调中,通常在调用 sqlite3_aggregate_context(C,N) 时设置 N=0,这样就不会发生无意义的内存分配。

当聚合查询结束时,SQLite 自动释放由 sqlite3_aggregate_context() 分配的内存。

第一个参数必须是 SQL 函数上下文的副本,它是实现聚合函数的 xStep 或 xFinal 回调例程的第一个参数。

必须从运行聚合 SQL 函数的同一线程调用此例程。


自动加载静态链接扩展

int sqlite3_auto_extension(void(*xEntryPoint)(void));

该接口导致为每个创建的新数据库连接调用 xEntryPoint() 函数。这里的想法是 xEntryPoint() 是静态链接的SQLite 扩展的入口点, 它将自动加载到所有新的数据库连接中。

尽管函数原型显示 xEntryPoint() 不带任何参数并返回 void,SQLite 调用带有三个参数的 xEntryPoint() 并期望一个整数结果,就像入口点的签名一样,如下所示:

   int xEntryPoint(
     sqlite3 *db,
     const char **pzErrMsg,
     const struct sqlite3_api_routines *pThunk
   );

如果 xEntryPoint 例程遇到错误,它应该使 *pzErrMsg 指向适当的错误消息(从sqlite3_mprintf()获得)并返回适当的错误代码SQLite 在调用 xEntryPoint() 之前确保 *pzErrMsg 为 NULL。SQLite 将 在 xEntryPoint() 返回后在 *pzErrMsg 上调用sqlite3_free() 。如果任何 xEntryPoint() 返回错误,则引发 xEntryPoint() 的sqlite3_open()sqlite3_open16()sqlite3_open_v2()调用将失败。

使用已经在自动扩展列表中的入口点 X 调用 sqlite3_auto_extension(X) 是无害的空操作。对于打开的每个数据库连接,不会多次调用入口点。

另见:sqlite3_reset_auto_extension()sqlite3_cancel_auto_extension()


Autovacuum 压实量回调

int sqlite3_autovacuum_pages(
  sqlite3 *db,
  unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
  void*,
  void(*)(void*)
);

sqlite3_autovacuum_pages(D,C,P,X) 接口注册了一个回调函数 C,它在数据库文件的每个自​​动清理之前被调用。向回调传递通用数据指针 (P) 的副本、正在自动清理的附加数据库的模式名称、数据库文件的页面大小、空闲页面数和每个字节数页,分别。回调应返回应由 autovacuum 删除的空闲页面数。如果回调返回零,则不会发生 autovacuum。如果返回的值大于或等于空闲页面的数量,则会发生完整的 autovacuum。

如果有多个 ATTACH-ed 数据库文件作为事务提交的一部分被修改,那么将为每个文件单独调用 autovacuum 页面回调。

回调不可重入。回调函数不应尝试调用任何其他 SQLite 接口。如果是这样,可能会发生不好的事情,包括分段错误和损坏的数据库文件。回调函数应该是一个简单的函数,它对其输入参数进行一些运算并返回结果。

sqlite3_autovacuum_pages(D,C,P,X) 的 X 参数是 P 参数的可选析构函数。如果 X 不为 NULL,则每当数据库连接关闭或回调被 sqlite3_autovacuum_pages() 的另一次调用覆盖时,都会调用 X(P)。

每个数据库连接只有一个 autovacuum 页面回调。对 sqlite3_autovacuum_pages() 接口的每次调用都会覆盖该数据库连接的所有先前调用。如果 sqlite3_autovacuum_pages(D,C,P,X) 的回调参数 (C) 是 NULL 指针,那么 autovacuum 步骤回调将被取消。sqlite3_autovacuum_pages() 的返回值通常是 SQLITE_OK,但如果出现问题,可能是其他错误代码。当前的实现只会返回 SQLITE_OK 或 SQLITE_MISUSE,但在未来的版本中可能会添加其他返回码。

如果未指定 autovacuum 页面回调(通常情况)或为回调提供 NULL 指针,则默认行为是清理所有空闲页面。所以,换句话说,默认行为就像回调函数是这样的一样:

    unsigned int demonstration_autovac_pages_callback(
      void *pClientData,
      const char *zSchema,
      unsigned int nDbPage,
      unsigned int nFreePage,
      unsigned int nBytePerPage
    ){
      return nFreePage;
    }


SQL 参数的数量

int sqlite3_bind_parameter_count(sqlite3_stmt*);

该例程可用于查找准备好的语句中SQL 参数 的数量SQL 参数是“?”、“?NNN”、“:AAA”、“$AAA”或“@AAA”形​​式的标记,用作稍后绑定 到参数的值的占位符。

该例程实际上返回最大(最右边)参数的索引。对于除 ?NNN 之外的所有形式,这将对应于唯一参数的数量。如果使用 ?NNN 形式的参数,列表中可能会有间隙。

另请参阅:sqlite3_bind()sqlite3_bind_parameter_name()sqlite3_bind_parameter_index()


具有给定名称的参数的索引

int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

返回给定名称的 SQL 参数的索引。返回的索引值适合用作sqlite3_bind()的第二个参数。如果未找到匹配参数,则返回零。即使原始语句是使用sqlite3_prepare16_v2()sqlite3_prepare16_v3()从 UTF-16 文本准备的,参数名称也必须以 UTF-8 格式给出。

另请参阅:sqlite3_bind()sqlite3_bind_parameter_count()sqlite3_bind_parameter_name()


主机参数名称

const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);

sqlite3_bind_parameter_name(P,N)接口返回预处理语句P中 第N个SQL参数的名称。形如“?NNN”或“:AAA”或“@AAA”或“$AAA”的SQL参数有一个name 分别是字符串“?NNN”或“:AAA”或“@AAA”或“$AAA”。换句话说,首字母“:”或“$”或“@”或“?” 作为名称的一部分包含在内。“?”形式的参数 没有后面的整数就没有名字,被称为“无名”或“匿名参数”。

第一个主机参数的索引为 1,而不是 0。

如果值 N 超出范围或第 N 个参数是无名的,则返回 NULL。返回的字符串始终采用 UTF-8 编码,即使命名参数最初在sqlite3_prepare16()sqlite3_prepare16_v2()sqlite3_prepare16_v3()中指定为 UTF-16 。

另请参阅:sqlite3_bind()sqlite3_bind_parameter_count()sqlite3_bind_parameter_index()


返回打开的 BLOB 的大小

int sqlite3_blob_bytes(sqlite3_blob *);

返回可通过其唯一参数中成功打开的BLOB 句柄 访问的 BLOB 的字节大小。增量 blob I/O 例程只能读取或覆盖现有的 blob 内容;他们不能改变 blob 的大小。

此例程仅适用于由先前成功调用sqlite3_blob_open()创建且未被sqlite3_blob_close()关闭的BLOB 句柄将任何其他指针传递给此例程会导致未定义且可能不受欢迎的行为。


关闭 BLOB 句柄

int sqlite3_blob_close(sqlite3_blob *);

此函数关闭打开的BLOB 句柄BLOB 句柄无条件关闭。即使此例程返回错误代码,句柄仍处于关闭状态。

如果正在关闭的 blob 句柄已打开以进行读写访问,并且如果数据库处于自动提交模式并且没有其他打开的读写 blob 句柄或活动的写入语句,则提交当前事务。如果在提交事务时发生错误,则返回错误代码并回滚事务。

使用不是 NULL 指针或打开的 blob 句柄的参数调用此函数会导致未定义的行为。使用空指针调用此例程(例如调用 sqlite3_blob_open()失败时返回的指针)是无害的空操作。否则,如果此函数传递了一个有效的打开的 blob 句柄,则 sqlite3_errcode() 和 sqlite3_errmsg() 函数返回的值在返回之前设置。


为增量 I/O 打开一个 BLOB

int sqlite3_blob_open(
  sqlite3*,
  const char *zDb,
  const char *zTable,
  const char *zColumn,
  sqlite3_int64 iRow,
  int flags,
  sqlite3_blob **ppBlob
);

该接口打开位于数据库 zDb 中行 iRow、列 zColumn、表 zTable 中的 BLOB的句柄;换句话说,相同的 BLOB 将由以下人员选择:

SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;

参数 zDb 不是包含数据库的文件名,而是数据库的符号名称。对于附加数据库,这是出现在ATTACH语句中 AS 关键字之后的名称。对于主数据库文件,数据库名称是“main”。对于 TEMP 表,数据库名称是“temp”。

如果标志参数不为零,则打开 BLOB 以进行读写访问。如果标志参数为零,则打开 BLOB 以进行只读访问。

成功时,将返回SQLITE_OK并将新的BLOB 句柄存储在 *ppBlob 中。否则返回一个错误代码,除非错误代码是 SQLITE_MISUSE,*ppBlob 被设置为 NULL。这意味着,只要 API 未被滥用, 在该函数返回后调用 *ppBlob 上的sqlite3_blob_close()总是安全的。

如果以下任一情况为真,此函数将失败并返回 SQLITE_ERROR:

除非返回 SQLITE_MISUSE,否则此函数设置 数据库连接错误代码和消息,可通过 sqlite3_errcode()sqlite3_errmsg()及相关函数访问。

sqlite3_blob_open() 引用的 BLOB 可以使用 sqlite3_blob_read()接口读取并 使用sqlite3_blob_write () 修改。可以使用sqlite3_blob_reopen() 接口BLOB 句柄移动到同一表的不同行。但是,打开BLOB 句柄 后,不能更改BLOB 句柄的列、表或数据库

如果 BLOB 句柄指向的行被 UPDATEDELETEON CONFLICT副作用修改,则 BLOB 句柄被标记为“已过期”。如果行的任何列发生更改,即使是打开 BLOB 句柄的列以外的列,也是如此。为过期的 BLOB 句柄调用sqlite3_blob_read()sqlite3_blob_write()失败,返回代码为SQLITE_ABORT在 BLOB 到期之前写入 BLOB 的更改不会在 BLOB 到期时回滚。如果事务继续完成,此类更改最终将提交。

使用sqlite3_blob_bytes()接口来确定打开的 blob 的大小。此接口不能更改 blob 的大小。使用UPDATE SQL 命令更改 blob 的大小。

sqlite3_bind_zeroblob()sqlite3_result_zeroblob()接口以及内置的zeroblob SQL函数可用于创建零填充的 blob,以使用增量 blob 接口进行读取或写入。

为了避免资源泄漏,每个打开的BLOB 句柄最终都应该通过调用sqlite3_blob_close()来释放。

另见:sqlite3_blob_close()sqlite3_blob_reopen()sqlite3_blob_read()sqlite3_blob_bytes()sqlite3_blob_write()


从 BLOB 中增量读取数据

int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);

此函数用于将数据从打开的BLOB 句柄读取到调用者提供的缓冲区中。N 个字节的数据从打开的 BLOB 复制到缓冲区 Z,从偏移量 iOffset 开始。

如果偏移量 iOffset 小于 BLOB 末尾的 N 个字节, 则返回SQLITE_ERROR并且不读取任何数据。如果 N 或 iOffset 小于零,则返回SQLITE_ERROR并且不读取任何数据。可以使用sqlite3_blob_bytes()接口确定 blob 的大小(以及 N+iOffset 的最大值)。

尝试读取过期的BLOB 句柄失败,错误代码为SQLITE_ABORT

成功时,sqlite3_blob_read() 返回 SQLITE_OK。否则,返回错误代码扩展错误代码

此例程仅适用于由先前成功调用sqlite3_blob_open()创建且未被sqlite3_blob_close()关闭的BLOB 句柄将任何其他指针传递给此例程会导致未定义且可能不受欢迎的行为。

另见:sqlite3_blob_write()


将 BLOB 句柄移动到新行

int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);

此函数用于移动现有的BLOB 句柄,使其指向同一数据库表的不同行。新行由作为第二个参数传递的 rowid 值标识。只能更改行。打开 blob 句柄的数据库、表和列保持不变。将现有BLOB 句柄移动到新行比关闭现有句柄并打开新句柄更快。

新行必须满足与sqlite3_blob_open()相同的条件——它必须存在,并且必须有一个 blob 或文本值存储在指定的列中。如果表中不存在新行,或者它不包含 blob 或文本值,或者发生另一个错误,则返回 SQLite 错误代码并且 blob 句柄被视为中止。在中止的 blob 句柄上对sqlite3_blob_read()sqlite3_blob_write()sqlite3_blob_reopen()的所有后续调用立即返回 SQLITE_ABORT。在中止的 blob 句柄上调用sqlite3_blob_bytes()总是返回零。

此函数设置数据库句柄错误代码和消息。


将数据增量写入 BLOB

int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);

此函数用于将数据从调用者提供的缓冲区写入打开的BLOB 句柄。N 个字节的数据从缓冲区 Z 复制到打开的 BLOB,从偏移量 iOffset 开始。

成功时,sqlite3_blob_write() 返回 SQLITE_OK。否则, 返回错误代码扩展错误代码除非返回 SQLITE_MISUSE,否则此函数设置 数据库连接错误代码和消息,可通过 sqlite3_errcode()sqlite3_errmsg()及相关函数访问。

如果作为第一个参数传递的BLOB 句柄未打开以进行写入(sqlite3_blob_open()的标志参数为零),则此函数返回SQLITE_READONLY

该函数只能修改 BLOB 的内容;无法使用此 API 增加 BLOB 的大小。如果偏移量 iOffset 小于 BLOB 末尾的 N 个字节, 则返回SQLITE_ERROR并且不写入任何数据。BLOB 的大小(以及 N+iOffset 的最大值)可以使用sqlite3_blob_bytes()接口来确定。如果 N 或 iOffset 小于零,则返回SQLITE_ERROR并且不写入任何数据。

尝试写入过期的BLOB 句柄失败,错误代码为SQLITE_ABORT在BLOB 句柄过期之前发生的对 BLOB 的写入不会因句柄过期而回滚,尽管这些更改当然可能已被使 BLOB 句柄过期的语句或其他独立语句覆盖。

此例程仅适用于由先前成功调用sqlite3_blob_open()创建且未被sqlite3_blob_close()关闭的BLOB 句柄将任何其他指针传递给此例程会导致未定义且可能不受欢迎的行为。

另见:sqlite3_blob_read()


设置忙碌超时

int sqlite3_busy_timeout(sqlite3*, int ms);

此例程设置一个繁忙的处理程序,当表被锁定时,它会休眠一段指定的时间。处理程序将睡眠多次,直到至少累积了“ms”毫秒的睡眠时间。在睡眠至少“ms”毫秒后,处理程序返回 0,这导致sqlite3_step()返回 SQLITE_BUSY

使用小于或等于零的参数调用此例程将关闭所有繁忙的处理程序。

在任何给定时刻,特定数据库连接只能有一个繁忙的处理程序 。如果在调用此例程之前定义了另一个繁忙的处理程序(使用sqlite3_busy_handler() ),则该其他繁忙的处理程序将被清除。

另见: PRAGMA busy_timeout


取消自动扩展加载

int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));

sqlite3_cancel_auto_extension(X)接口注销使用先前调用 sqlite3_auto_extension(X ) 注册 的初始化例程X。如果初始化例程 X 成功取消注册,sqlite3_cancel_auto_extension(X) 例程返回 1,如果 X 不在初始化例程列表中,则返回 0。


重置准备好的语句上的所有绑定

int sqlite3_clear_bindings(sqlite3_stmt*);

与许多人的直觉相反,sqlite3_reset()不会重置准备好的语句上的绑定使用此例程将所有主机参数重置为 NULL。


结果集中的列数

int sqlite3_column_count(sqlite3_stmt *pStmt);

返回准备语句 返回的结果集中的列数 如果此例程返回 0,则意味着 准备好的语句不返回任何数据(例如UPDATE)。但是,仅仅因为此例程返回一个正数并不意味着将返回一行或多行数据。SELECT 语句将始终具有正数 sqlite3_column_count() 但取决于 WHERE 子句约束和表内容,它可能不返回任何行。

另见:sqlite3_data_count()


配置 SQLite 库

int sqlite3_config(int, ...);

sqlite3_config() 接口用于对 SQLite 进行全局配置更改,以便根据应用程序的特定需求调整 SQLite。对于大多数应用,建议使用默认配置,因此通常不需要此例程。提供它是为了支持具有特殊需求的罕见应用程序。

sqlite3_config() 接口不是线程安全的。应用程序必须确保在运行 sqlite3_config() 时没有其他 SQLite 接口被其他线程调用。

sqlite3_config() 接口只能在使用 sqlite3_initialize()进行库初始化之前或通过sqlite3_shutdown()关闭之后调用如果在 sqlite3_initialize() 之后和sqlite3_shutdown()之前 调用sqlite3_config( ) ,那么它将返回 SQLITE_MISUSE。但是请注意,可以调用 sqlite3_config() 作为应用程序定义的sqlite3_os_init()实现的一部分。

sqlite3_config() 的第一个参数是一个整数 配置选项,用于确定要配置的 SQLite 属性。后续参数因第一个参数中的配置选项而异 。

设置配置选项后,sqlite3_config() 返回SQLITE_OK如果该选项未知或 SQLite 无法设置该选项,则此例程返回一个非零错误代码


函数的数据库连接

sqlite3 *sqlite3_context_db_handle(sqlite3_context*);

sqlite3_context_db_handle() 接口返回指向最初注册应用程序定义函数 的sqlite3_create_function()sqlite3_create_function16()例程的数据库连接(第一个参数)的 指针副本。


结果集中的列数

int sqlite3_data_count(sqlite3_stmt *pStmt);

sqlite3_data_count(P) 接口返回预处理语句P 结果集当前行中的列数。如果预处理语句 P 没有准备好返回的结果(通过调用sqlite3_column()系列接口),则 sqlite3_data_count( P) 返回 0。如果 P 是 NULL 指针,sqlite3_data_count(P) 例程也返回 0。如果先前对 sqlite3_step (P) 的调用返回SQLITE_DONE ,则 sqlite3_data_count(P) 例程返回 0 。如果之前对sqlite3_step (P) 的调用返回 了 SQLITE_ROW ,则 sqlite3_data_count(P) 将返回非零值, PRAGMA incremental_vacuum的情况除外 它总是返回零,因为该多步编译指示的每一步都返回 0 列数据。

另见:sqlite3_column_count()


一个日志对应的数据库文件

sqlite3_file *sqlite3_database_file_object(const char*);

如果 X 是传递给 sqlite3_vfs 的 xOpen 方法的回滚或 WAL 模式日志文件的名称则 sqlite3_database_file_object(X) 返回一个指向代表主数据库文件的sqlite3_file 对象的指针。

此例程仅用于自定义VFS实现。它不是通用接口。参数 sqlite3_file_object(X) 必须是已传递到sqlite3_vfs .xOpen 方法的文件名指针,其中 xOpen 的标志参数包含 SQLITE_OPEN_MAIN_JOURNALSQLITE_OPEN_WAL位之一。此例程的任何其他使用都会导致未定义的和可能不受欢迎的行为。


在事务中将缓存刷新到磁盘

int sqlite3_db_cacheflush(sqlite3*);

如果在调用sqlite3_db_cacheflush(D)接口时在数据库连接D 上打开写事务,则页面缓存中当前未使用的任何脏页都将写出到磁盘。如果活动 SQL 语句创建的数据库游标正在读取脏页,或者如果它是数据库文件的第 1 页(第 1 页始终“正在使用”),则脏页可能正在使用中。sqlite3_db_cacheflush(D)接口刷新所有模式的 缓存——“main”、“temp”和任何附加的数据库。

如果此函数需要在脏页刷新到磁盘之前获得额外的数据库锁,它会这样做。如果无法立即获得这些锁,并且配置了忙处理程序回调,则会以通常的方式调用它。如果仍然无法获得所需的锁,则跳过该数据库并尝试刷新属于下一个(如果有)数据库的任何脏页。如果因为无法获得锁而跳过任何数据库,但没有发生其他错误,则此函数返回 SQLITE_BUSY。

如果在将脏页刷新到磁盘时发生任何其他错误(例如 IO 错误或内存不足情况),则处理将被放弃并立即将 SQLite错误代码返回给调用者。

否则,如果没有错误发生,sqlite3_db_cacheflush()返回 SQLITE_OK。

此函数不设置数据库句柄错误代码或由sqlite3_errcode()sqlite3_errmsg()函数返回的消息。


配置数据库连接

int sqlite3_db_config(sqlite3*, int op, ...);

sqlite3_db_config() 接口用于对数据库连接进行配置更改。该接口类似于 sqlite3_config(),不同之处在于更改适用于单个 数据库连接(在第一个参数中指定)。

sqlite3_db_config(D,V,...) 的第二个参数是 配置动词- 一个整数代码,指示正在配置数据库连接的哪个方面。后续参数因配置动词而异。

当且仅当调用被认为成功时,调用 sqlite3_db_config() 返回 SQLITE_OK。


返回数据库连接的文件名

const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);

sqlite3_db_filename(D,N) 接口返回一个指向与连接 D 的数据库 N 关联的文件名的指针。如果数据库连接 D 上没有附加的数据库 N,或者如果数据库 N 是一个临时或内存数据库,那么这个函数将返回 NULL 指针或空字符串。

此例程返回的字符串值由数据库连接拥有和管理。该值将有效,直到数据库 N 被DETACH编辑或直到数据库连接关闭。

此函数返回的文件名是VFS的 xFullPathname 方法的输出换句话说,文件名将是一个绝对路径名,即使最初用于打开数据库的文件名是一个 URI 或相对路径名。

如果此例程返回的文件名指针不为 NULL,则它可用作这些例程的文件名输入参数:


查找准备好的语句的数据库句柄

sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

sqlite3_db_handle 接口返回准备好的语句所属的数据库连接句柄。 sqlite3_db_handle 返回的数据库连接与最初用于创建语句的sqlite3_prepare_v2()调用(或其变体) 的第一个参数相同。


检索数据库连接的互斥锁

sqlite3_mutex *sqlite3_db_mutex(sqlite3*);

线程模式为序列化时,该接口返回一个sqlite3_mutex对象 的指针,该对象序列化对参数中给定的数据库连接的访问​​。如果线程模式是单线程或多线程,则此例程返回 NULL 指针。


返回数据库连接的架构名称

const char *sqlite3_db_name(sqlite3 *db, int N);

sqlite3_db_name(D,N) 接口返回一个指向数据库连接 D 上第 N 个数据库的模式名称的指针,或者 N 的 NULL 指针超出范围。N 值为 0 表示主数据库文件。N 为 1 是“temp”架构。较大的 N 值对应于各种 ATTACH-ed 数据库。

存放 sqlite3_db_name() 返回的字符串的空间由 SQLite 本身管理。该字符串可能会被任何更改模式的操作释放,包括ATTACHDETACH或调用 sqlite3_serialize()sqlite3_deserialize(),甚至发生在不同线程上的操作。需要长期记住字符串的应用程序应该制作自己的副本。在多个线程上同时访问同一数据库连接的应用程序应该互斥保护调用此 API,并且应该在释放互斥锁之前制作自己的结果私有副本。


确定数据库是否为只读

int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);

如果连接 D 的数据库 N 是只读的,则 sqlite3_db_readonly(D,N) 接口返回 1,如果是读/写则返回 0,如果 N 不是连接 D 上的数据库名称则返回 -1。


数据库连接使用的空闲内存

int sqlite3_db_release_memory(sqlite3*);

sqlite3_db_release_memory(D) 接口尝试从数据库连接 D 释放尽可能多的堆内存。与 sqlite3_release_memory()接口不同,即使省略了SQLITE_ENABLE_MEMORY_MANAGEMENT编译时选项,该接口仍然有效。

另见:sqlite3_release_memory()


数据库连接状态

int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);

此接口用于检索有关单个数据库连接的运行时状态信息。第一个参数是要查询的数据库连接对象。第二个参数是一个整数常量,取自 SQLITE_DBSTATUS options的集合,它决定了要查询的参数。SQLITE_DBSTATUS 选项可能会在 SQLite 的未来版本中增加。

请求参数的当前值写入*pCur,最高瞬时值写入*pHiwtr。如果 resetFlg 为真,则最高瞬时值将重置回当前值。

sqlite3_db_status() 例程在成功时返回 SQLITE_OK,在失败时返回非零错误代码

另见:sqlite3_status()sqlite3_stmt_status()


声明虚拟表的架构

int sqlite3_declare_vtab(sqlite3*, const char *zSQL);

虚拟表模块xCreatexConnect方法 调用此接口来声明它们实现的虚拟表的格式(列的名称和数据类型)。


反序列化数据库

int sqlite3_deserialize(
  sqlite3 *db,            /* The database connection */
  const char *zSchema,    /* Which DB to reopen with the deserialization */
  unsigned char *pData,   /* The serialized database content */
  sqlite3_int64 szDb,     /* Number bytes in the deserialization */
  sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
  unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
);

sqlite3_deserialize(D,S,P,N,M,F)接口导致 数据库连接D断开与数据库S的连接,然后根据P中包含的序列化重新打开S作为内存数据库。序列化后的数据库P为N字节大小。M 是缓冲区 P 的大小,它可能大于 N。如果 M 大于 N,并且 F 中没有设置 SQLITE_DESERIALIZE_READONLY 位,那么 SQLite 允许向内存数据库添加内容,只要总大小不超过 M 字节。

如果在 F 中设置了 SQLITE_DESERIALIZE_FREEONCLOSE 位,则当数据库连接关闭时,SQLite 将在序列化缓冲区上调用 sqlite3_free()。如果设置了 SQLITE_DESERIALIZE_RESIZEABLE 位,则如果对数据库的写入导致其增长超过 M 字节,则 SQLite 将尝试使用 sqlite3_realloc64() 增加缓冲区大小。

如果数据库当前处于读取事务或涉及备份操作,则 sqlite3_deserialize() 接口将失败并返回 SQLITE_BUSY。

无法反序列化到 TEMP 数据库中。如果 sqlite3_deserialize(D,S,P,N,M,F) 的 S 参数是“temp”,则该函数返回 SQLITE_ERROR。

如果 sqlite3_deserialize(D,S,P,N,M,F) 由于任何原因失败,并且如果在参数 F 中设置了 SQLITE_DESERIALIZE_FREEONCLOSE 位,则 在返回之前对参数 P 调用sqlite3_free() 。

如果使用SQLITE_OMIT_DESERIALIZE选项 编译 SQLite,则省略此接口 。


删除不必要的虚拟表实现

int sqlite3_drop_modules(
  sqlite3 *db,                /* Remove modules from this connection */
  const char **azKeep         /* Except, do not remove the ones named here */
);

sqlite3_drop_modules(D,L) 接口从数据库连接 D 中删除所有虚拟表模块,列表 L 中命名的除外。L 参数必须为 NULL 或指向字符串指针数组的指针,其中数组由单个 NULL 终止指针。如果 L 参数为 NULL,则删除所有虚拟表模块。

另见:sqlite3_create_module()


启用或禁用扩展加载

int sqlite3_enable_load_extension(sqlite3 *db, int onoff);

为了不在未准备好处理扩展加载的旧应用程序中打开安全漏洞,并且作为在评估用户输入的 SQL 时禁用 扩展加载的一种方法,提供了以下 API 来打开和关闭sqlite3_load_extension()机制。

扩展加载默认关闭。使用 onoff==1 调用 sqlite3_enable_load_extension() 例程以打开扩展加载并使用 onoff==0 调用它以再次关闭它。

此接口启用或禁用 C-API sqlite3_load_extension()和 SQL 函数load_extension()使用sqlite3_db_config (db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION ,..) 仅启用或禁用 C-API。

安全警告:建议使用SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION方法而非此接口启用扩展加载,因此load_extension() SQL 函数保持禁用状态。这将防止 SQL 注入使攻击者能够访问扩展加载功能。


启用或禁用共享寻呼机缓存

int sqlite3_enable_shared_cache(int);

此例程启用或禁用在同一个数据库的连接 之间共享数据库缓存和模式数据结构如果参数为真,则启用共享;如果参数为假,则禁用共享。

为整个进程启用和禁用缓存共享。这是 SQLite版本 3.5.0 (2007-09-04) 的更改。在以前的 SQLite 版本中,每个线程分别启用或禁用共享。

此接口设置的缓存共享模式会影响对sqlite3_open()sqlite3_open_v2()sqlite3_open16()的所有后续调用现有数据库连接继续使用在打开它们时有效的共享模式。

如果成功启用或禁用共享缓存,此例程返回SQLITE_OK 。否则返回错误代码

默认情况下禁用共享缓存。建议保持这种状态。换句话说,不要使用这个例程。继续提供此接口以实现历史兼容性,但不鼓励使用它。不鼓励使用共享缓存。如果必须使用共享缓存,建议仅使用带有SQLITE_OPEN_SHAREDCACHE标志的sqlite3_open_v2()接口为单个数据库连接启用共享缓存。

注意:此方法在 MacOS X 10.7 和 iOS 5.0 版中被禁用,并且将始终返回 SQLITE_MISUSE。在这些系统上,应该通过 带有SQLITE_OPEN_SHAREDCACHE的sqlite3_open_v2()为每个数据库连接启用共享缓存模式。

此接口在写入 32 位整数是原子的处理器上是线程安全的。

另见: SQLite 共享缓存模式


一步查询执行接口

int sqlite3_exec(
  sqlite3*,                                  /* An open database */
  const char *sql,                           /* SQL to be evaluated */
  int (*callback)(void*,int,char**,char**),  /* Callback function */
  void *,                                    /* 1st argument to callback */
  char **errmsg                              /* Error msg written here */
);

sqlite3_exec() 接口是sqlite3_prepare_v2()sqlite3_step()sqlite3_finalize() 的便利包装器 ,它允许应用程序运行多个 SQL 语句而无需使用大量 C 代码。

sqlite3_exec() 接口在作为第一个参数传入的数据库连接的上下文中运行零个或多个 UTF-8 编码的、以分号分隔的 SQL 语句并传入其第二个参数。如果 sqlite3_exec() 的第 3 个参数的回调函数不为 NULL,那么它会为来自评估 SQL 语句的每个结果行调用。sqlite3_exec() 的第四个参数被传递到每个回调调用的第一个参数。如果指向 sqlite3_exec() 的回调指针为 NULL,则不会调用回调并且忽略结果行。

如果在评估传递给 sqlite3_exec() 的 SQL 语句时发生错误,则当前语句的执行将停止并跳过后续语句。如果 sqlite3_exec() 的第 5 个参数不是 NULL,那么任何错误消息都会写入从sqlite3_malloc()获得的内存中,并通过第 5 个参数传回。为避免内存泄漏,应用程序应 在不再需要错误消息字符串后,对通过 sqlite3_exec() 的第 5 个参数返回的错误消息字符串调用sqlite3_free() 。如果 sqlite3_exec() 的第 5 个参数不是 NULL 并且没有发生错误,则 sqlite3_exec() 在返回之前将其第 5 个参数中的指针设置为 NULL。

如果 sqlite3_exec() 回调返回非零值,则 sqlite3_exec() 例程返回 SQLITE_ABORT 而无需再次调用回调且不运行任何后续 SQL 语句。

sqlite3_exec() 回调函数的第二个参数是结果中的列数。sqlite3_exec() 回调的第三个参数是一个指向字符串的指针数组,就像从 sqlite3_column_text()中获得的一样,每列一个。如果结果行的元素为 NULL,则 sqlite3_exec() 回调的相应字符串指针为 NULL 指针。sqlite3_exec() 回调的第四个参数是指向字符串的指针数组,其中每个条目代表从sqlite3_column_name()获得的相应结果列的名称。

如果 sqlite3_exec() 的第二个参数是 NULL 指针、指向空字符串的指针或仅包含空格和/或 SQL 注释的指针,则不会评估任何 SQL 语句并且不会更改数据库。

限制:


启用或禁用扩展结果代码

int sqlite3_extended_result_codes(sqlite3*, int onoff);

sqlite3_extended_result_codes() 例程启用或禁用 SQLite 的 扩展结果代码功能。为了历史兼容性,默认情况下禁用扩展结果代码。


销毁准备好的语句对象

int sqlite3_finalize(sqlite3_stmt *pStmt);

调用 sqlite3_finalize() 函数来删除准备好的语句如果语句的最近评估没有遇到错误,或者从未评估过语句,则 sqlite3_finalize() 返回 SQLITE_OK。如果语句 S 的最新评估失败,则 sqlite3_finalize(S) 返回适当的错误代码扩展错误代码

sqlite3_finalize(S) 例程可以在准备语句S 的生命周期中的任何时候调用:在对语句 S 进行评估之前,在对sqlite3_reset()进行一次或多次调用之后,或者在对sqlite3_step()的任何调用之后,无论是否或不是语句已经执行完毕。

在 NULL 指针上调用 sqlite3_finalize() 是无害的空操作。

应用程序必须完成每个准备好的语句以避免资源泄漏。应用程序在完成后尝试使用准备好的语句是一个严重的错误。准备好的语句在完成后的任何使用都可能导致未定义和不良行为,例如段错误和堆损坏。


中断长时间运行的查询

void sqlite3_interrupt(sqlite3*);

此函数会导致任何挂起的数据库操作中止并尽早返回。此例程通常被调用以响应用户操作,例如在用户希望长时间查询操作立即停止时按下“取消”或 Ctrl-C。

从与当前运行数据库操作的线程不同的线程调用此例程是安全的。但是使用已关闭或可能在 sqlite3_interrupt() 返回之前关闭的数据库连接调用此例程是不安全的。

如果在调用 sqlite3_interrupt() 时 SQL 操作非常接近完成,那么它可能没有机会被中断,可能会继续完成。

被中断的 SQL 操作将返回SQLITE_INTERRUPT如果中断的 SQL 操作是显式事务内的 INSERT、UPDATE 或 DELETE,则整个事务将自动回滚。

sqlite3_interrupt(D) 调用一直有效,直到数据库连接D 上所有当前运行的 SQL 语句完成。在 sqlite3_interrupt() 调用之后和运行语句计数达到零之前启动的任何新 SQL 语句都会被中断,就好像它们在 sqlite3_interrupt() 调用之前已经运行一样。在运行语句计数为零后启动的新 SQL 语句不受 sqlite3_interrupt() 的影响。在没有正在运行的 SQL 语句时发生的对 sqlite3_interrupt(D) 的调用是空操作,并且对在 sqlite3_interrupt() 调用返回后启动的 SQL 语句没有影响。


最后插入行号

sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);

大多数 SQLite 表(WITHOUT ROWID表除外)中的每个条目都有一个唯一的 64 位带符号整数键,称为“rowid”rowid 始终可用作名为 ROWID、OID 或 _ROWID_ 的未声明列,只要这些名称未被显式声明的列也使用。如果表有一个INTEGER PRIMARY KEY类型的列,那么该列是 rowid 的另一个别名。

sqlite3_last_insert_rowid(D) 接口通常返回最近一次成功插入数据库连接 D 上的rowid表或虚拟表的 rowid 。插入WITHOUT ROWID表不被记录。如果在数据库连接 D 上没有成功插入rowid 表,则 sqlite3_last_insert_rowid(D) 返回零。

除了在将行插入数据库表时自动设置外,此函数返回的值还可以由 sqlite3_set_last_insert_rowid()显式设置

一些虚拟表实现可能将行插入 rowid 表作为提交事务的一部分(例如,将内存中累积的数据刷新到磁盘)。在这种情况下,对该函数的后续调用返回与这些内部 INSERT 操作关联的 rowid,这会导致不直观的结果。以这种方式写入 rowid 表的虚拟表实现可以通过在将控制权返回给用户之前使用sqlite3_set_last_insert_rowid()恢复原始 rowid 值来避免此问题。

如果INSERT发生在触发器中,那么只要触发器正在运行,此例程就会返回插入行的rowid 。触发器程序结束后,此例程返回的值将恢复为触发触发器之前的值。

由于违反约束而失败INSERT不是成功的INSERT,并且不会更改此例程返回的值。因此,INSERT OR FAIL、INSERT OR IGNORE、INSERT OR ROLLBACK 和 INSERT OR ABORT 在插入失败时不会更改此例程的返回值。当 INSERT OR REPLACE 遇到约束冲突时,它不会失败。INSERT 在删除导致约束问题的行后继续完成,因此 INSERT 或 REPLACE 将始终更改此接口的返回值。

就此例程而言,INSERT被认为是成功的,即使它随后被回滚。

SQL 语句可通过 last_insert_rowid() SQL 函数访问此函数

如果一个单独的线程在sqlite3_last_insert_rowid() 函数运行时对同一个数据库连接执行新的INSERT并因此更改最后插入的rowid,则sqlite3_last_insert_rowid()返回的值是不可预测的并且可能不等于旧的或新的 last插入行号


运行时限制

int sqlite3_limit(sqlite3*, int id, int newVal);

该接口允许在逐个连接的基础上限制各种构造的大小。第一个参数是 要设置或查询限制的数据库连接。第二个参数是限制类别之一,用于定义要限制大小的构造类。第三个参数是该构造的新限制。

如果新限制为负数,则限制不变。对于每个限制类别 SQLITE_LIMIT_ NAME都有一个 硬上限 在编译时由一个名为 SQLITE_MAX_ NAME的 C 预处理器宏设置。(名称中的“_LIMIT_”更改为“_MAX_”。)将限制增加到其硬上限之上的尝试会被默默地截断到硬上限。

无论限制是否更改, sqlite3_limit()接口都会返回限制的先前值。因此,要在不更改限制的情况下找到限制的当前值,只需调用此接口并将第三个参数设置为 -1。

运行时限制旨在用于管理自己的内部数据库以及由不受信任的外部源控制的数据库的应用程序。一个示例应用程序可能是一个 Web 浏览器,它有自己的数据库来存储历史记录和由从 Internet 下载的 JavaScript 应用程序控制的独立数据库。可以为内部数据库提供较大的默认限制。可以为外部资源管理的数据库提供更小的限制,旨在防止拒绝服务攻击。开发人员可能还想使用sqlite3_set_authorizer() 接口来进一步控制不受信任的 SQL。可以使用 max_page_count PRAGMA包含由不受信任的脚本创建的数据库的大小。

未来的版本中可能会添加新的运行时限制类别。


加载扩展

int sqlite3_load_extension(
  sqlite3 *db,          /* Load the extension into this database connection */
  const char *zFile,    /* Name of the shared library containing extension */
  const char *zProc,    /* Entry point.  Derived from zFile if 0 */
  char **pzErrMsg       /* Put error message here if not 0 */
);

此接口从命名文件加载 SQLite 扩展库。

sqlite3_load_extension() 接口尝试加载 文件 zFile 中包含的SQLite 扩展库。如果无法直接加载文件,则会尝试加载各种操作系统特定的扩展。因此,例如,如果无法加载“samplelib”,则也可以尝试使用“samplelib.so”或“samplelib.dylib”或“samplelib.dll”之类的名称。

入口点是 zProc。zProc 可能为 0,在这种情况下,SQLite 将尝试自己提出一个入口点名称。它首先尝试“sqlite3_extension_init”。如果这不起作用,它会构造一个名称“sqlite3_X_init”,其中 X 由文件名中从最后一个“/”到第一个“.”的所有 ASCII 字母字符的小写等价物组成。并省略任何初始的“lib”。sqlite3_load_extension() 接口 在成功时返回SQLITE_OK ,如果出现问题则返回SQLITE_ERROR 。如果发生错误并且 pzErrMsg 不为 0,则 sqlite3_load_extension()接口将尝试用存储在从sqlite3_malloc()获得的内存中的错误消息文本填充 *pzErrMsg. 调用函数应通过调用sqlite3_free()释放此内存。

在调用此 API 之前,必须使用 sqlite3_enable_load_extension()sqlite3_db_config (db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION ,1,NULL) 启用扩展加载,否则将返回错误。

安全警告:建议使用 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION方法只启用该接口。应避免使用sqlite3_enable_load_extension()接口。这将使 SQL 函数load_extension()保持 禁用状态,并防止 SQL 注入使攻击者能够访问扩展加载功能。

另请参阅load_extension() SQL 函数


错误记录接口

void sqlite3_log(int iErrCode, const char *zFormat, ...);

sqlite3_log()接口 将消息写入由SQLITE_CONFIG_LOG选项 建立的错误日志中sqlite3_config()如果启用日志记录,则 zFormat 字符串和后续参数与sqlite3_snprintf()一起使用以生成最终输出字符串。

sqlite3_log() 接口旨在供虚拟表、整理函数和 SQL 函数等扩展使用。虽然没有什么可以阻止应用程序调用 sqlite3_log(),但这样做被认为是错误的形式。

zFormat 字符串不能为 NULL。

为避免死锁和其他线程问题,sqlite3_log() 例程不会使用动态分配的内存。日志消息存储在堆栈上的固定长度缓冲区中。如果日志消息超过几百个字符,它将被截断为缓冲区的长度。


查找下一个准备好的语句

sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);

该接口返回一个指针,指向与数据库连接pDb关联的 pStmt 之后的下一个准备语句如果 pStmt 为 NULL,则此接口返回指向与数据库连接 pDb 关联的第一个准备好的语句的指针。如果没有准备好的语句满足此例程的条件,则返回 NULL。

sqlite3_next_stmt(D,S)调用中的数据库连接指针 D 必须引用打开的数据库连接,尤其不能是 NULL 指针。


为虚拟表重载函数

int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);

虚拟表可以使用虚拟表模块的xFindFunction方法提供函数的替代实现但是这些函数的全局版本必须存在才能被重载。

此 API 确保存在具有特定名称和参数数量的函数的全局版本。如果在调用此 API 之前不存在此类函数,则会创建一个新函数。新函数的实现总是导致抛出异常。所以新功能本身对任何事情都没有好处。它的唯一目的是成为一个可以被虚拟表重载的占位符函数。


查询进度回调

void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);

sqlite3_progress_handler(D,N,X,P) 接口导致回调函数 X 在长时间运行时调用 sqlite3_exec()sqlite3_step()sqlite3_get_table()用于数据库连接 D。此接口的一个示例使用是在大型查询期间保持 GUI 更新。

参数 P 作为回调函数 X 的唯一参数传递。参数 N 是在回调 X 的连续调用之间评估的 虚拟机指令的近似数量。如果 N 小于 1,则禁用进度处理程序.

每个数据库连接一次只能定义一个进度处理程序 设置新的进度处理程序会取消旧的。将参数 X 设置为 NULL 会禁用进度处理程序。进度处理程序也可以通过将 N 设置为小于 1 的值来禁用。

如果进度回调返回非零值,则操作中断。此功能可用于在 GUI 进度对话框上实现“取消”按钮。

进度处理程序回调不得执行任何会修改调用进度处理程序的数据库连接的操作。注意,sqlite3_prepare_v2()sqlite3_step()都针对本段“修改”的意思修改了自己的数据库连接。


伪随机数生成器

void sqlite3_randomness(int N, void *P);

SQLite 包含一个高质量的伪随机数生成器 (PRNG),用于在将新记录插入到已使用最大可能 ROWID 的表中时选择随机ROWIDPRNG 还用于内置的 random() 和 randomblob() SQL 函数。此接口允许应用程序出于其他目的访问相同的 PRNG。

对该例程的调用将 N 个字节的随机性存储到缓冲区 P 中。P 参数可以是 NULL 指针。

如果之前未调用此例程,或者如果之前的调用中 N 小于 1 或 P 的 NULL 指针,则使用从默认sqlite3_vfs对象的 xRandomness 方法获得的随机性为 PRNG 播种。如果之前对该例程的调用具有 1 或更大的 N 和非 NULL P,则伪随机性是在内部生成的,无需求助于sqlite3_vfs xRandomness 方法。


尝试释放堆内存

int sqlite3_release_memory(int);

sqlite3_release_memory() 接口尝试通过释放数据库库持有的非必要内存分配来释放 N 字节的堆内存。用于缓存数据库页面以提高性能的内存是非必需内存的一个示例。sqlite3_release_memory() 返回实际释放的字节数,可能多于或少于请求的数量。如果 SQLite 未使用SQLITE_ENABLE_MEMORY_MANAGEMENT编译,则 sqlite3_release_memory() 例程是一个返回零的空操作。

另见:sqlite3_db_release_memory()


重置准备好的语句对象

int sqlite3_reset(sqlite3_stmt *pStmt);

调用 sqlite3_reset() 函数将准备好的语句 对象重置回其初始状态,准备重新执行。使用sqlite3_bind_*() API将值绑定到它们的任何 SQL 语句变量都会保留它们的值。使用sqlite3_clear_bindings()重置绑定。

sqlite3_reset(S)接口将准备好的语句S重置回其程序的开头。

如果最近一次准备好的语句S 调用sqlite3_step(S)返回SQLITE_ROWSQLITE_DONE,或者如果以前从未在 S 上调用过 sqlite3_step(S) ,则sqlite3_reset (S)返回SQLITE_OK

如果最近准备好的语句S 调用sqlite3_step(S)指示错误,则 sqlite3_reset(S)返回适当的错误代码

sqlite3_reset(S)接口不会更改预处理语句S 上任何绑定的值。


重置自动扩展加载

void sqlite3_reset_auto_extension(void);

该接口禁用了之前使用sqlite3_auto_extension()注册的所有自动扩展。


设置 SQL 函数的子类型

void sqlite3_result_subtype(sqlite3_context*,unsigned int);

sqlite3_result_subtype(C,T) 函数导致应用程序定义的 SQL 函数的结果的子类型与 sqlite3_context C 的值为 T。在当前版本的 SQLite 中仅保留子类型 T 的低 8 位;高阶位被丢弃。在 SQLite 的未来版本中,SQLite 保留的子类型字节数可能会增加。


序列化数据库

unsigned char *sqlite3_serialize(
  sqlite3 *db,           /* The database connection */
  const char *zSchema,   /* Which DB to serialize. ex: "main", "temp", ... */
  sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
  unsigned int mFlags    /* Zero or more SQLITE_SERIALIZE_* flags */
);

sqlite3_serialize(D,S,P,F) 接口返回一个指向内存的指针,它是数据库连接D 上 S 数据库的序列化。如果 P 不是 NULL 指针,则数据库的大小(以字节为单位)写入 * P.

对于普通的磁盘数据库文件,序列化只是磁盘文件的一个副本。对于内存数据库或“TEMP”数据库,如果该数据库备份到磁盘,序列化是将写入磁盘的相同字节序列。

通常的情况是 sqlite3_serialize() 将数据库的序列化复制到从sqlite3_malloc64()获得的内存中,并返回指向该内存的指针。调用者负责释放返回值以避免内存泄漏。但是,如果 F 参数包含 SQLITE_SERIALIZE_NOCOPY 位,则不会进行内存分配,并且 sqlite3_serialize() 函数将返回一个指向 SQLite 当前用于该数据库的数据库的连续内存表示的指针,如果没有,则返回 NULL数据库的这种连续内存表示存在。数据库的连续内存表示通常仅在之前调用过sqlite3_deserialize(D,S,...)时才会存在具有相同的 D 和 S 值。即使设置了 SQLITE_SERIALIZE_NOCOPY 位但不存在数据库的连续副本,数据库的大小也会写入 *P。

如果发生内存分配错误,即使从参数 F 中省略了 SQLITE_SERIALIZE_NOCOPY 位,对 sqlite3_serialize(D,S,P,F) 的调用也可能返回 NULL。

如果使用SQLITE_OMIT_DESERIALIZE选项 编译 SQLite,则省略此接口 。


设置上次插入 Rowid 值。

void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);

sqlite3_set_last_insert_rowid(D, R) 方法允许应用程序将通过调用 sqlite3_last_insert_rowid(D) 返回的值设置为 R,而无需将行插入数据库。


暂停执行一小段时间

int sqlite3_sleep(int);

sqlite3_sleep() 函数使当前线程暂停执行至少在其参数中指定的毫秒数。

如果操作系统不支持毫秒时间分辨率的睡眠请求,则时间将四舍五入到最接近的秒。返回操作系统实际请求的睡眠毫秒数。

SQLite 通过调用默认的sqlite3_vfs对象的 xSleep() 方法来实现这个接口。如果默认 VFS 的 xSleep() 方法没有正确实现,或者根本没有实现,那么 sqlite3_sleep() 的行为可能与前面段落中的描述不同。


比较两个快照句柄的年龄。

int sqlite3_snapshot_cmp(
  sqlite3_snapshot *p1,
  sqlite3_snapshot *p2
);

sqlite3_snapshot_cmp(P1, P2) 接口用于比较两个有效快照句柄的年龄。

如果两个快照句柄不与同一个数据库文件相关联,则比较的结果是未定义的。

此外,仅当自上次删除 wal 文件后通过调用 sqlite3_snapshot_get() 获得两个快照句柄时,比较结果才有效。当数据库改回回滚模式或数据库客户端数量降为零时,wal 文件将被删除。如果在上次删除 wal 文件之前获得了任一快照句柄,则此函数返回的值是未定义的。

否则,如果 P1 引用的快照比 P2 旧,则此 API 返回负值;如果两个句柄引用同一数据库快照,则此 API 返回零;如果 P1 是比 P2 更新的快照,则返回正值。

此接口仅在使用 SQLITE_ENABLE_SNAPSHOT选项编译 SQLite 时可用。


销毁快照

void sqlite3_snapshot_free(sqlite3_snapshot*);

sqlite3_snapshot_free ( P)接口会破坏sqlite3_snapshot P。应用程序必须最终使用此例程释放每个sqlite3_snapshot对象以避免内存泄漏。

sqlite3_snapshot_free()接口仅在使用 SQLITE_ENABLE_SNAPSHOT编译时选项时可用。


记录数据库快照

int sqlite3_snapshot_get(
  sqlite3 *db,
  const char *zSchema,
  sqlite3_snapshot **ppSnapshot
);

sqlite3_snapshot_get(D,S,P)接口尝试创建一个新的sqlite3_snapshot对象, 该对象记录数据库连接 D 中模式 S 的当前状态。成功时, sqlite3_snapshot_get(D,S,P)接口将指针写入新创建的sqlite3_snapshot对象放入 *P 并返回 SQLITE_OK。如果在调用此函数时模式 S 上还没有打开的读取事务,则会自动打开一个。

要使此功能成功,必须满足以下条件。如果调用 sqlite3_snapshot_get() 时以下任何语句为假,则返回 SQLITE_ERROR。在这种情况下,*P 的最终值未定义。

该函数也可能返回 SQLITE_NOMEM。如果在自动提交模式下使用数据库句柄调用它但由于某些其他原因而失败,则未定义是否在模式 S 上打开读取事务。

从成功调用 sqlite3_snapshot_get()返回的sqlite3_snapshot对象必须使用sqlite3_snapshot_free()释放 以避免内存泄漏。

sqlite3_snapshot_get()接口仅在使用 SQLITE_ENABLE_SNAPSHOT编译时选项时可用。


在历史快照上启动读取事务

int sqlite3_snapshot_open(
  sqlite3 *db,
  const char *zSchema,
  sqlite3_snapshot *pSnapshot
);

sqlite3_snapshot_open(D,S,P) 接口要么启动一个新的读取事务,要么升级数据库连接D的模式 S 的现有 事务,以便读取事务引用历史快照P,而不是数据库的最新更改。sqlite3_snapshot_open()接口在成功时返回 SQLITE_OK 或在失败时返回适当的错误代码

为了成功,调用sqlite3_snapshot_open(D,S,P)数据库连接不能处于 自动提交模式如果模式 S 上已经有一个读取事务打开,则数据库句柄必须没有活动语句(SELECT 语句已传递给 sqlite3_step() 但不是 sqlite3_reset() 或 sqlite3_finalize())。如果违反了这些条件中的任何一个,或者模式 S 不存在,或者快照对象无效,则返回 SQLITE_ERROR。

如果指定的快照已被检查点覆盖,则调用 sqlite3_snapshot_open() 将无法打开。在这种情况下,返回 SQLITE_ERROR_SNAPSHOT。

如果在调用此函数时已经有一个读取事务打开,那么如果返回 SQLITE_ERROR、SQLITE_BUSY 或 SQLITE_ERROR_SNAPSHOT,则相同的读取事务将保持打开状态(在同一数据库快照上)。如果返回另一个错误代码(例如 SQLITE_PROTOCOL 或 SQLITE_IOERR 错误代码),则读取事务的最终状态未定义。如果返回 SQLITE_OK,则读取事务现在在数据库快照 P 上打开。

如果数据库连接 D 不知道模式 S 的数据库文件处于WAL 模式,则对sqlite3_snapshot_open(D,S,P)的调用将失败如果数据库连接上没有先前的 I/O,或者如果数据库 在数据库连接上最近的 I/O 之后进入WAL 模式,则数据库连接可能不知道数据库文件处于WAL 模式。(提示:针对新打开的数据库连接运行“ PRAGMA application_id ”,以使其准备好使用快照。)

sqlite3_snapshot_open()接口仅在使用 SQLITE_ENABLE_SNAPSHOT编译时选项时可用。


从 wal 文件恢复快照

int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);

如果在所有数据库连接关闭后WAL 文件仍保留在磁盘上(通过使用SQLITE_FCNTL_PERSIST_WAL 文件控制 或因为打开数据库的最后一个进程在没有调用sqlite3_close()的情况下退出)并且随后在该数据库上打开一个新连接并且WAL 文件sqlite3_snapshot_open()接口将只能打开添加到 WAL 文件的最后一个事务,即使 WAL 文件包含其他有效事务。

此函数尝试扫描与数据库句柄 db 的数据库 zDb 关联的 WAL 文件,并使所有有效的快照对 sqlite3_snapshot_open() 可用。如果数据库上已经打开了读取事务,或者数据库不是 WAL 模式数据库,则会出错。

如果成功则返回 SQLITE_OK,否则返回 SQLite 错误代码。

此接口仅在使用 SQLITE_ENABLE_SNAPSHOT选项编译 SQLite 时可用。


弃用的软堆限制接口

void sqlite3_soft_heap_limit(int N);

这是sqlite3_soft_heap_limit64() 接口的弃用版本。提供此例程只是为了历史兼容性。所有新应用程序都应该使用 sqlite3_soft_heap_limit64()接口而不是这个接口。


评估 SQL 语句

int sqlite3_step(sqlite3_stmt*);

使用 sqlite3_prepare_v2()sqlite3_prepare_v3()sqlite3_prepare16_v2()sqlite3_prepare16_v3()或遗留接口sqlite3_prepare()sqlite3_prepare16()之一准备好准备好的语句后,必须调用此函数一次或多次以评估声明。

sqlite3_step() 接口的行为细节取决于语句是使用较新的“vX”接口 sqlite3_prepare_v3()sqlite3_prepare_v2()sqlite3_prepare16_v3()sqlite3_prepare16_v2()还是旧的遗留接口sqlite3_prepare()sqlite3_prepare16准备的()建议新应用程序使用新的“vX”接口,但将继续支持旧接口。

在旧接口中,返回值将是SQLITE_BUSYSQLITE_DONESQLITE_ROWSQLITE_ERRORSQLITE_MISUSE使用“v2”接口,也可以返回任何其他结果代码扩展结果代码。

SQLITE_BUSY意味着数据库引擎无法获取完成其工作所需的数据库锁。如果该语句是COMMIT 或发生在显式事务之外,则您可以重试该语句。如果该语句不是COMMIT并且发生在显式事务中,那么您应该在继续之前回滚该事务。

SQLITE_DONE表示语句已成功执行完毕。如果没有先调用sqlite3_reset()将虚拟机重置回其初始状态,则不应在此虚拟机上再次调用sqlite3_step()。

如果正在执行的 SQL 语句返回任何数据,则 每次新的数据行准备好由调用者处理时,都会返回SQLITE_ROW 。可以使用列访问函数访问这些值。再次调用 sqlite3_step() 以检索下一行数据。

SQLITE_ERROR表示发生了运行时错误(例如违反约束)。不应在 VM 上再次调用 sqlite3_step()。可以通过调用sqlite3_errmsg()找到更多信息。使用旧接口,可以通过在 准备好的语句上调用sqlite3_reset()来获取更具体的错误代码(例如, SQLITE_INTERRUPTSQLITE_SCHEMASQLITE_CORRUPT等)在“v2”接口中,更具体的错误码由sqlite3_step()直接返回。

SQLITE_MISUSE意味着这个例程被不恰当地调用了。也许它是在一个已经完成的准备好的语句上调用的,或者是在一个之前返回过 SQLITE_ERRORSQLITE_DONE的语句上调用的。或者可能是两个或多个线程同时使用同一个数据库连接。

对于 3.6.23.1 及之前的所有 SQLite 版本, 在 sqlite3_step() 返回除SQLITE_ROW以外的任何后续调用 sqlite3_step() 之前,需要调用 sqlite3_reset() 未能使用 sqlite3_reset()重置准备好的语句将导致从 sqlite3_step() 返回SQLITE_MISUSE但是在版本 3.6.23.1(2010-03-26,sqlite3_step() 开始在这种情况下自动调用sqlite3_reset()而不是返回SQLITE_MISUSE之后。这不被视为兼容性中断,因为任何收到 SQLITE_MISUSE 错误的应用程序都被定义为中断。 这SQLITE_OMIT_AUTORESET编译时选项可用于恢复遗留行为。

愚蠢的接口警报:在旧接口中,sqlite3_step() API 总是返回一个通用错误代码SQLITE_ERROR ,在除SQLITE_BUSYSQLITE_MISUSE之外的任何错误之后您必须调用 sqlite3_reset()sqlite3_finalize()才能找到能够更好地描述错误的特定错误代码之一。我们承认这是一个愚蠢的设计。该问题已通过“v2”界面修复。如果您使用sqlite3_prepare_v3()sqlite3_prepare_v2()sqlite3_prepare16_v2()sqlite3_prepare16_v3()准备所有 SQL 语句而不是遗留的sqlite3_prepare()sqlite3_prepare16()接口,然后更具体的错误代码由 sqlite3_step() 直接返回。建议使用“vX”接口。


确定准备好的语句是否已重置

int sqlite3_stmt_busy(sqlite3_stmt*);

sqlite3_stmt_busy(S) 接口返回 true(非零)如果 预处理语句S 已经使用sqlite3_step(S)步进至少一次 但既没有运行完成( sqlite3_step(S)返回SQLITE_DONE)也没有使用sqlite3_reset( S)如果 S 是 NULL 指针,则 sqlite3_stmt_busy(S) 接口返回 false。如果 S 不是 NULL 指针,也不是指向有效准备语句 对象的指针,则该行为是未定义的并且可能是不需要的。

该接口可以与sqlite3_next_stmt()组合使用, 以定位与需要重置的数据库连接关联的所有准备好的语句。例如,这可以在诊断例程中用于搜索保持事务打开的准备好的语句。


查询准备好的语句的 EXPLAIN 设置

int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);

如果准备语句 S 是 EXPLAIN 语句,sqlite3_stmt_isexplain(S) 接口返回 1,如果语句 S 是 EXPLAIN QUERY PLAN,则返回 2。如果 S 是普通语句或 NULL 指针,则 sqlite3_stmt_isexplain(S) 接口返回 0。


确定 SQL 语句是否写入数据库

int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);

当且仅当准备好的语句X 不直接更改数据库文件的内容时, sqlite3_stmt_readonly(X) 接口才返回 true(非零) 。

请注意,应用程序定义的 SQL 函数虚拟表可能会作为副作用间接更改数据库。例如,如果应用程序定义了一个调用sqlite3_exec()的函数“eval()” ,那么以下 SQL 语句将通过副作用更改数据库文件:

SELECT eval('DELETE FROM t1') FROM t2;

但是因为SELECT语句没有直接改变数据库文件,sqlite3_stmt_readonly() 仍然会返回 true。

诸如BEGINCOMMITROLLBACKSAVEPOINTRELEASE之类的事务控制语句会导致 sqlite3_stmt_readonly() 返回 true,因为这些语句本身实际上并不修改数据库,而是控制其他语句修改数据库的时间。ATTACHDETACH语句也会导致 sqlite3_stmt_readonly() 返回 true ,因为当这些语句更改数据库连接的配置时,它们不会更改磁盘上数据库文件的内容。sqlite3_stmt_readonly() 接口BEGIN开始为BEGIN返回 true仅设置内部标志,但BEGIN IMMEDIATEBEGIN EXCLUSIVE命令确实触及数据库,因此 sqlite3_stmt_readonly() 对这些命令返回 false。

如果该语句有可能更改数据库文件,则此例程返回 false。错误的返回并不能保证该语句会更改数据库文件。例如,UPDATE 语句可能有一个 WHERE 子句使其成为空操作,但 sqlite3_stmt_readonly() 结果仍然为 false。类似地,如果表已经存在,则 CREATE TABLE IF NOT EXISTS 语句是只读的空操作,但 sqlite3_stmt_readonly() 仍会为此类语句返回 false。

如果准备语句 X 是EXPLAINEXPLAIN QUERY PLAN 语句,则 sqlite3_stmt_readonly(X) 返回相同的值,就好像省略了 EXPLAIN 或 EXPLAIN QUERY PLAN 前缀一样。


准备好的语句扫描状态

int sqlite3_stmt_scanstatus(
  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
  int idx,                  /* Index of loop to report on */
  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
  void *pOut                /* Result written here */
);

此接口返回有关 pStmt 的预测和测量性能的信息。高级应用程序可以使用此接口来比较预测和测量的性能,并在发现差异时发出警告和/或重新运行ANALYZE 。

由于此接口预计很少使用,因此仅当使用SQLITE_ENABLE_STMT_SCANSTATUS 编译时选项编译 SQLite 时才可用。

“iScanStatusOp”参数决定返回哪些状态信息。“iScanStatusOp”必须是扫描状态选项之一,否则此接口的行为未定义。请求的测量值被写入“pOut”参数指向的变量中。参数“idx”标识要为其检索统计信息的特定循环。循环从零开始编号。如果 idx 超出范围 - 小于零或大于或等于用于实现语句的循环总数 - 返回非零值并且 pOut 指向的变量不变。

统计信息可能不适用于所有语句中的所有循环。在存在没有可用统计信息的循环的情况下,此函数的行为就像循环不存在一样 - 它返回非零值并保持 pOut 指向的变量不变。

另见:sqlite3_stmt_scanstatus_reset()


零扫描状态计数器

void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);

将所有sqlite3_stmt_scanstatus()相关事件计数器 清零。

此 API 仅在使用定义的预处理器符号SQLITE_ENABLE_STMT_SCANSTATUS构建库时可用。


准备好的声明状态

int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);

每个准备好的语句都维护着各种 SQLITE_STMTSTATUS 计数器,用于测量它执行特定操作的次数。这些计数器可用于监视准备好的语句的性能特征。例如,如果表步骤的数量大大超过表搜索或结果行的数量,这往往表明准备好的语句正在使用全表扫描而不是索引。

此接口用于从准备好的语句中检索和重置计数器值。第一个参数是要查询的准备好的语句对象。第二个参数是要查询的特定SQLITE_STMTSTATUS 计数器的整数代码 。返回请求的计数器的当前值。如果 resetFlg 为真,则在此接口调用返回后计数器将重置为零。

另见:sqlite3_status()sqlite3_db_status()


完成动态字符串

char *sqlite3_str_finish(sqlite3_str*);

sqlite3_str_finish(X)接口销毁 sqlite3_str 对象 X 并返回指向从sqlite3_malloc64()获得的 包含构造字符串的内存缓冲区 的指针。调用应用程序应将返回值传递给sqlite3_free()以避免内存泄漏。如果在构造字符串期间遇到任何错误,sqlite3_str_finish(X) 接口可能会返回 NULL指针如果sqlite3_str对象 X 中的字符串长度为零字节 , 则sqlite3_str_finish(X)接口也将返回 NULL 指针。


创建一个新的动态字符串对象

sqlite3_str *sqlite3_str_new(sqlite3*);

sqlite3_str_new(D)接口分配并初始化一个新的 sqlite3_str对象为避免内存泄漏, sqlite3_str_new()返回的对象必须通过随后调用 sqlite3_str_finish(X)来释放。

sqlite3_str_new(D)接口总是返回一个指向有效sqlite3_str对象的指针,尽管在发生内存不足错误时返回的对象可能是一个特殊的单例,它将默默地拒绝新文本,总是从 sqlite3_str_errcode()返回 SQLITE_NOMEM ,始终为sqlite3_str_length()返回 0 ,并始终从sqlite3_str_finish(X)返回 NULL 使用sqlite3_str_new(D)返回的值作为任何其他sqlite3_str方法的 sqlite3_str 参数总是安全的。

sqlite3_str_new(D)的 D 参数可能为 NULL。如果sqlite3_str_new(D)中的 D 参数不为 NULL,则sqlite3_str对象中包含的字符串的最大长度将为sqlite3_limit (D, SQLITE_LIMIT_LENGTH ) 设置的值,而不是SQLITE_MAX_LENGTH


字符串通配

int sqlite3_strglob(const char *zGlob, const char *zStr);

且仅当字符串 X 匹配GLOB模式P 时,sqlite3_strglob(P,X)接口返回零。sqlite3_strglob (P,X)中使用的GLOB模式匹配 的定义与“X GLOB P”运算符相同SQLite 理解的 SQL 方言。sqlite3_strglob(P,X)函数区分大小写。

请注意,此例程在匹配时返回零,如果字符串不匹配则返回非零,与sqlite3_stricmp()sqlite3_strnicmp()相同。

另见:sqlite3_strlike()


字符串 LIKE 匹配

int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);

且仅当字符串 X 与带有转义字符 E 的LIKE模式 P 匹配时,sqlite3_strlike(P,X,E)接口返回零。sqlite3_strlike( P,X,E)中使用的LIKE模式匹配 的定义与用于SQLite 理解的 SQL 方言中的“X LIKE P ESCAPE E”运算符。对于没有 ESCAPE 子句的“X LIKE P”,将sqlite3_strlike(P,X,E)的 E 参数设置为 0。与 LIKE 运算符一样,sqlite3_strlike(P,X,E)函数不区分大小写 - 等效于大写和小写 ASCII 字符相互匹配。

sqlite3_strlike(P,X,E)函数匹配 Unicode 字符,尽管只有 ASCII 字符是大小写折叠的。

请注意,此例程在匹配时返回零,如果字符串不匹配则返回非零,与sqlite3_stricmp()sqlite3_strnicmp()相同。

另见:sqlite3_strglob()


低级系统错误代码

int sqlite3_system_errno(sqlite3*);

尝试返回导致最近 I/O 错误或无法打开文件的底层操作系统错误代码或错误编号。返回值取决于操作系统。例如,在 unix 系统上,在 sqlite3_open_v2()返回SQLITE_CANTOPEN之后,可以调用此接口来取回导致问题的底层“errno”,例如 ENOSPC、EAUTH、EISDIR 等。


提取关于表的列的元数据

int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
  int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
  int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
  int *pAutoinc               /* OUTPUT: True if column is auto-increment */
);

sqlite3_table_column_metadata(X,D,T,C,....)例程在数据库连接X上返回 数据库D中表T的列C的信息。sqlite3_table_column_metadata()接口返回SQLITE_OK并填充非NULL指针在如果指定的列存在,则返回具有适当值的最后五个参数。如果指定的列不存在,sqlite3_table_column_metadata() 接口返回 SQLITE_ERROR。如果 sqlite3_table_column_metadata() 的列名参数是一个 NULL 指针,那么这个例程只是检查表是否存在,如果表存在则返回 SQLITE_OK,如果不存在则返回 SQLITE_ERROR。如果调用 sqlite3_table_column_metadata(X,D,T,C,...) 时表名参数 T 为 NULL,则结果为未定义行为。

该列由该函数的第二个、第三个和第四个参数标识。第二个参数是包含指定表的数据库名称(即“main”、“temp”或附加数据库)或 NULL。如果它为 NULL,则使用数据库引擎使用的相同算法在所有附加的数据库中搜索该表,以解析不合格的表引用。

此函数的第三个和第四个参数分别是所需列的表名和列名。

通过写入作为第 5 个和后续参数传递给此函数的内存位置来返回元数据。这些参数中的任何一个都可以为 NULL,在这种情况下,相应的元数据元素将被省略。

Parameter Output
Type
Description

5th const char* Data type
6th const char* Name of default collation sequence
7th int True if column has a NOT NULL constraint
8th int True if column is part of the PRIMARY KEY
9th int True if column is AUTOINCREMENT

为声明类型和排序规则序列返回的字符指针指向的内存在下一次​​调用任何 SQLite API 函数之前一直有效。

如果指定的表实际上是一个视图,则返回一个错误代码

如果指定的列是“rowid”、“oid”或“_rowid_”并且该表不是WITHOUT ROWID表并且已显式声明了 INTEGER PRIMARY KEY列,则为显式声明的列设置输出参数。如果没有 INTEGER PRIMARY KEY列,则rowid的输出设置如下:

data type: "INTEGER"
collation sequence: "BINARY"
not null: 0
primary key: 1
auto increment: 0

此函数会导致从磁盘读取所有数据库模式并进行解析(如果尚未完成),并在加载模式时遇到任何错误时返回错误。


测试界面

int sqlite3_test_control(int op, ...);

sqlite3_test_control() 接口用于读取 SQLite 的内部状态并将故障注入 SQLite 以进行测试。第一个参数是操作码,决定了后面所有参数的个数、含义和操作。

此接口不供应用程序使用。它仅用于验证 SQLite 库的正确操作。根据 SQLite 库的编译方式,此接口可能不存在。

操作代码的详细信息、它们的含义、它们采用的参数以及它们的作用都可能发生变化,恕不另行通知。与大多数 SQLite API 不同,此函数不能保证从一个版本到下一个版本的操作一致。


测试库是否是线程安全的

int sqlite3_threadsafe(void);

当且仅当 SQLite 编译时由于 SQLITE_THREADSAFE编译时选项被设置为 0 而省略了互斥代码,sqlite3_threadsafe() 函数返回零。

SQLite 可以使用或不使用互斥锁进行编译。SQLITE_THREADSAFE C 预处理器宏为 1 或 2 时,将启用互斥并且 SQLite 是线程安全的。SQLITE_THREADSAFE宏为 0 时,互斥量将被忽略。没有互斥体,从多个线程同时使用 SQLite 是不安全的。

启用互斥体会导致可衡量的性能损失。因此,如果速度至关重要,则禁用互斥体是有意义的。但是为了最大程度的安全,应该启用互斥锁。默认行为是启用互斥锁。

应用程序可以使用此接口来确保它所链接的 SQLite 版本是使用SQLITE_THREADSAFE宏的所需设置编译的。

此接口仅报告SQLITE_THREADSAFE标志的编译时互斥设置。如果 SQLite 是用 SQLITE_THREADSAFE=1 或 =2 编译的,则默认情况下启用互斥锁,但可以使用 动词SQLITE_CONFIG_SINGLETHREADSQLITE_CONFIG_MULTITHREADSQLITE_CONFIG_SERIALIZED调用sqlite3_config()来完全或部分禁用。sqlite3_threadsafe() 函数的返回值仅显示线程安全的编译时设置,而不是 sqlite3_config() 对该设置所做的任何运行时更改。换句话说,sqlite3_threadsafe() 的返回值不会因调用 sqlite3_config() 而改变。

有关其他信息,请参阅线程模式文档。


SQL 跟踪钩子

int sqlite3_trace_v2(
  sqlite3*,
  unsigned uMask,
  int(*xCallback)(unsigned,void*,void*,void*),
  void *pCtx
);

sqlite3_trace_v2(D,M,X,P) 接口使用属性掩码 M 和上下文指针 P 注册针对数据库连接D 的跟踪回调函数 X。如果 X 回调为 NULL 或如果 M 掩码为零,则禁用跟踪. M 参数应该是零个或多个SQLITE_TRACE常量的按位或运算组合。

每次调用 sqlite3_trace() 或 sqlite3_trace_v2() 都会覆盖(取消)之前对 sqlite3_trace() 或 sqlite3_trace_v2() 的任何调用。

只要掩码 M 标识的任何事件发生,就会调用 X 回调。回调的整数返回值目前被忽略,尽管这可能会在未来的版本中改变。回调实现应返回零以确保未来的兼容性。

使用四个参数调用跟踪回调:callback(T,C,P,X)。T 参数是SQLITE_TRACE 常量之一,用于指示调用回调的原因。C 参数是上下文指针的副本。P 和 X 参数是指针,其含义取决于 T。

sqlite3_trace_v2() 接口旨在替换遗留接口sqlite3_trace()sqlite3_profile(),这两个接口都已弃用。


确定数据库的事务状态

int sqlite3_txn_state(sqlite3*,const char *zSchema);

sqlite3_txn_state(D,S) 接口返回数据库连接D中模式S的当前 事务状态。如果S为NULL,则返回数据库连接D上任何模式的最高事务状态。交易状态是(按从低到高的顺序):

  1. SQLITE_TXN_NONE
  2. SQLITE_TXN_READ
  3. SQLITE_TXN_WRITE
如果 sqlite3_txn_state(D,S) 的 S 参数不是有效模式的名称,则返回 -1。


解锁通知

int sqlite3_unlock_notify(
  sqlite3 *pBlocked,                          /* Waiting connection */
  void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
  void *pNotifyArg                            /* Argument to pass to xNotify */
);

在共享缓存模式下运行时,如果无法获得共享缓存或共享缓存中各个表所需的锁,数据库操作可能会失败并出现SQLITE_LOCKED错误。有关共享缓存锁定的描述,请参阅 SQLite 共享缓存模式此 API 可用于注册一个回调,当当前持有所需锁的连接放弃它时,SQLite 将调用该回调。仅当使用定义的 SQLITE_ENABLE_UNLOCK_NOTIFY C 预处理器符号编译库时,此 API 才可用。

另请参阅:使用 SQLite 解锁通知功能

当数据库连接通过提交或回滚结束其当前事务时,将释放共享缓存锁。

当连接(称为阻塞连接)无法获得共享缓存锁并且 SQLITE_LOCKED 返回给调用者时,已锁定所需资源的数据库连接(阻塞连接)的标识将在内部存储。应用程序收到 SQLITE_LOCKED 错误后,它可以调用 sqlite3_unlock_notify() 方法,并将阻塞的连接句柄作为第一个参数来注册回调,当阻塞连接当前事务结束时将调用该回调。回调是从 结束阻塞连接事务的sqlite3_stepsqlite3_close调用中调用的。

如果在多线程应用程序中调用 sqlite3_unlock_notify(),则阻塞连接有可能在调用 sqlite3_unlock_notify() 时已经结束其事务。如果发生这种情况,则会立即调用指定的回调,从对 sqlite3_unlock_notify() 的调用中。

如果被阻塞的连接试图获得共享缓存表上的写锁,并且当前有多个其他连接持有同一张表上的读锁,则 SQLite 会任意选择其他连接之一作为阻塞联系。

阻塞的连接最多可以注册一个解锁通知回调。如果 sqlite3_unlock_notify() 在被阻塞的连接已经注册了解锁通知回调时被调用,那么新的回调会替换旧的。如果使用 NULL 指针作为第二个参数调用 sqlite3_unlock_notify(),则取消任何现有的解锁通知回调。阻塞的连接解锁通知回调也可以通过使用sqlite3_close()关闭阻塞的连接来取消。

解锁通知回调不可重入。如果应用程序从解锁通知回调中调用任何 sqlite3_xxx API 函数,则可能会导致崩溃或死锁。

除非检测到死锁(见下文),sqlite3_unlock_notify() 总是返回 SQLITE_OK。

回调调用详细信息

注册解锁通知回调后,应用程序会提供一个 void* 指针,该指针会在回调被调用时传递给回调。然而,回调函数的签名允许 SQLite 向它传递一个 void* 上下文指针数组。传递给解锁通知回调的第一个参数是指向 void* 指针数组的指针,第二个参数是数组中的条目数。

当阻塞连接的事务结束时,可能有多个阻塞连接注册了解锁通知回调。如果两个或多个这样的阻塞连接指定了相同的回调函数,则不会多次调用回调函数,而是使用捆绑在一起的阻塞连接指定的一组 void* 上下文指针调用一次回调函数。这使应用程序有机会优先考虑与未阻塞的数据库连接集相关的任何操作。

死锁检测

假设在注册解锁通知回调后,数据库在采取任何进一步操作之前等待回调发出(合理的假设),那么使用此 API 可能会导致应用程序死锁。例如,如果连接 X 正在等待连接 Y 的事务结束,类似地,连接 Y 正在等待连接 X 的事务,那么两个连接都不会继续,系统可能会无限期地保持死锁状态。

为了避免这种情况,sqlite3_unlock_notify() 执行死锁检测。如果对 sqlite3_unlock_notify() 的给定调用会使系统处于死锁状态,则返回 SQLITE_LOCKED 并且不会注册解锁通知回调。如果连接 A 在连接 B 的事务结束时注册了解锁通知回调,并且连接 B 本身在连接 A 的事务结束时注册了解锁通知回调,则系统处于死锁状态。还检测到间接死锁,因此如果连接 B 在连接 C 的事务结束时注册了一个解锁通知回调,则系统也被认为是死锁,其中连接 C 正在等待连接 A。任何数量的间接级别都是允许。

“DROP TABLE”异常

当对sqlite3_step()的调用返回 SQLITE_LOCKED 时,调用 sqlite3_unlock_notify() 几乎总是合适的。然而,有一个例外。当执行“DROP TABLE”或“DROP INDEX”语句时,SQLite 检查是否有任何当前正在执行的属于同一连接的 SELECT 语句。如果有,则返回 SQLITE_LOCKED。在这种情况下,没有“阻塞连接”,因此调用 sqlite3_unlock_notify() 会导致立即调用解锁通知回调。如果应用程序随后重新尝试“DROP TABLE”或“DROP INDEX”查询,则结果可能是无限循环。

解决此问题的一种方法是检查 sqlite3_step() 调用返回的扩展错误代码。如果存在阻塞连接,则扩展错误代码设置为 SQLITE_LOCKED_SHAREDCACHE。否则,在特殊的“DROP TABLE/INDEX”情况下,扩展错误代码只是 SQLITE_LOCKED。


数据变更通知回调

void *sqlite3_update_hook(
  sqlite3*,
  void(*)(void *,int ,char const *,char const *,sqlite3_int64),
  void*
);

sqlite3_update_hook() 接口向数据库连接 注册一个回调函数,该回调函数由第一个参数标识,每当在rowid 表中更新、插入或删除行时调用先前为同一数据库连接调用此函数设置的任何回调都将被覆盖。

第二个参数是指向在 rowid 表中更新、插入或删除行时要调用的函数的指针。回调的第一个参数是 sqlite3_update_hook() 的第三个参数的副本。第二个回调参数是SQLITE_INSERTSQLITE_DELETESQLITE_UPDATE 之一,具体取决于导致调用回调的操作。回调的第三个和第四个参数包含指向包含受影响行的数据库和表名的指针。最后一个回调参数是行的rowid在更新的情况下,这是更新发生后的rowid 。

修改内部系统表时(即 sqlite_sequence)不会调用更新挂钩。修改WITHOUT ROWID时,不会调用更新挂钩。

在当前实现中,由于ON CONFLICT REPLACE子句而删除冲突行时,不会调用更新挂钩 。使用截断优化删除行时也不会调用更新挂钩本段中定义的异常可能会在 SQLite 的未来版本中发生变化。

更新挂钩实现不得做任何会修改调用更新挂钩的数据库连接的事情。任何修改数据库连接的操作都必须推迟到触发更新挂钩的sqlite3_step()调用完成之后。注意,sqlite3_prepare_v2()sqlite3_step()都针对本段“修改”的意思修改了自己的数据库连接。

sqlite3_update_hook(D,C,P) 函数返回上一次对同一数据库连接D 的调用的 P 参数,或者对于 D 的第一次调用返回 NULL。

另请参阅sqlite3_commit_hook()sqlite3_rollback_hook()sqlite3_preupdate_hook()接口。


函数的用户数据

void *sqlite3_user_data(sqlite3_context*);

sqlite3_user_data() 接口返回指针的副本,该指针是最初注册应用程序定义函数的sqlite3_create_function()sqlite3_create_function16()例程 的 pUserData 参数(第 5 个参数) 。

必须从运行应用程序定义函数的同一线程调用此例程。


查找 SQL 值的子类型

unsigned int sqlite3_value_subtype(sqlite3_value*);

sqlite3_value_subtype(V) 函数返回应用程序定义的 SQL 函数参数 V 的子类型。子类型信息可用于将有限数量的上下文从一个 SQL 函数传递到另一个。使用sqlite3_result_subtype() 例程为 SQL 函数的返回值设置子类型。


确定虚拟表约束的排序规则

const char *sqlite3_vtab_collation(sqlite3_index_info*,int);

只能从对虚拟表的xBestIndex 方法的调用中调用此函数此函数返回一个指向字符串的指针,该字符串是适当归类序列的名称,用于对其参数标识的约束进行文本比较。

第一个参数必须是指向sqlite3_index_info对象的指针,它是 xBestIndex() 方法的第一个参数。第二个参数必须是 aConstraint[] 数组的索引,该数组属于传递给 xBestIndex 的 sqlite3_index_info 结构。

重要提示:第​​一个参数必须是传递给 xBestMethod() 方法的同一指针。第一个参数可能不是指向不同sqlite3_index_info对象的指针,即使是精确的副本。

返回值计算如下:

  1. 如果约束来自包含COLLATE 运算符的 WHERE 子句表达式,则返回由该 COLLATE 运算符指定的排序规则的名称。

  2. 如果没有 COLLATE 运算符,但作为约束主题的列通过传递到sqlite3_declare_vtab()的 CREATE TABLE 语句中的列定义的COLLATE 子句指定了替代排序顺序,则该替代排序的名称序列被返回。

  3. 否则,返回“BINARY”。


虚表接口配置

int sqlite3_vtab_config(sqlite3*, int op, ...);

该函数可以由虚拟表实现的xConnectxCreate方法调用,以配置虚拟表接口的各个方面。

如果在 xConnect 或 xCreate 虚拟表方法的上下文之外调用此接口,则行为未定义。

在调用 sqlite3_vtab_config(D,C,...) 中,D 参数是创建虚拟表的 数据库连接,它作为第一个参数传递给 调用 sqlite3_vtab_config()的xConnectxCreate方法。C 参数是虚拟表配置选项之一。C 之后参数的存在和含义取决于使用哪个虚拟表配置选项


确定虚拟表查询是否为 DISTINCT

int sqlite3_vtab_distinct(sqlite3_index_info*);

此 API 只能在虚拟表实现的xBestIndex 方法 中使用。从 xBestIndex() 外部调用此接口的结果是未定义的,并且可能有害。

sqlite3_vtab_distinct() 接口返回一个介于 0 和 3 之间的整数。sqlite3_vtab_distinct() 返回的整数为虚拟表提供了有关查询计划程序希望如何对输出进行排序的附加信息。只要虚拟表能够满足查询规划器的排序要求,它就可以设置“orderByConsumed”标志。

  1. 如果 sqlite3_vtab_distinct() 接口返回 0,这意味着查询计划器需要虚拟表以 sqlite3_index_info对象的“nOrderBy”和“aOrderBy”字段定义的排序顺序返回所有行。这是默认的期望。如果虚拟表按排序顺序输出所有行,那么无论 sqlite3_vtab_distinct() 的返回值如何,xBestIndex 方法设置“orderByConsumed”标志始终是安全的。

  2. 如果 sqlite3_vtab_distinct() 接口返回 1,这意味着查询规划器不需要按排序顺序返回行,只要在“aOrderBy”字段标识的所有列中具有相同值的所有行都是相邻的。当查询规划器执行 GROUP BY 时使用此模式。

  3. 如果 sqlite3_vtab_distinct() 接口返回 2,这意味着查询规划器不需要以任何特定顺序返回的行,只要所有“aOrderBy”列中具有相同值的行都是相邻的。此外,对于由“aOrderBy”字段标识的列中的每个特定值组合,只需要返回一行。返回所有“aOrderBy”列中具有相同值的两行或更多行总是可以的,只要所有这些行都是相邻的。虚拟表可以,如果它选择,忽略额外的行,这些行对于由“aOrderBy”标识的所有列具有相同的值。然而,省略额外的行是可选的。此模式用于 DISTINCT 查询。

  4. 如果 sqlite3_vtab_distinct() 接口返回 3,这意味着查询规划器只需要不同的行,但它确实需要对行进行排序。如果愿意,虚拟表实现可以自由地省略所有 aOrderBy 列中相同的行,但不需要省略任何行。此模式用于同时具有 DISTINCT 和 ORDER BY 子句的查询。

为了比较虚拟表输出值以查看这些值是否是相同的值以进行排序,两个 NULL 值被认为是相同的。换句话说,比较运算符是“IS”(或“IS NOT DISTINCT FROM”)而不是“==”。

如果一个虚拟表实现不能满足上面指定的要求,那么它不能在 sqlite3_index_info对象中设置“orderByConsumed”标志,否则可能会导致错误的答案。

只要未设置“orderByConsumed”标志,虚拟表实现总是可以按任意顺序自由返回行。当“orderByConsumed”标志未设置时,查询计划器将添加额外的 字节码以确保 SQL 查询返回的最终结果被正确排序。“orderByConsumed”标志和 sqlite3_vtab_distinct() 接口的使用仅仅是一种优化。仔细使用 sqlite3_vtab_distinct() 接口和“orderByConsumed”标志可能有助于对虚拟表的查询运行得更快。另一方面,过于激进并在无效时设置“orderByConsumed”标志可能会导致 SQLite 返回不正确的结果。


识别和处理 xBestIndex 中的 IN 约束

int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);

此接口只能在 虚拟表实现的xBestIndex() 方法中使用。从任何其他上下文调用此接口的结果是未定义的并且可能是有害的。

对形式为“ column IN (...) ”的虚拟表的约束作为 SQLITE_INDEX_CONSTRAINT_EQ约束传递给 xBestIndex 方法。如果 xBestIndex 想要使用这个约束,它必须将相应的 aConstraintUsage[].argvIndex 设置为一个正整数。然后,在处理 IN 运算符的通常模式下,SQLite 生成字节码,为 IN 运算符右侧的每个值 调用一次xFilter() 方法。因此,虚拟表一次只能从 IN 运算符的右侧看到一个值。

然而,在某些情况下,虚拟表同时查看 IN 运算符右侧的所有值是有利的。sqlite3_vtab_in() 接口以两种方式促进了这一点:

  1. 当且仅当P->aConstraint [N] 约束是一个可以同时处理的IN 运算符时, 对 sqlite3_vtab_in(P,N,-1) 的调用将返回 true(非零) 。换句话说,第三个参数为 -1 的 sqlite3_vtab_in() 是一种机制,虚拟表可以通过这种机制询问 SQLite 是否可以一次性处理 IN 运算符。

  2. 使用 F==1 或 F==0 调用 sqlite3_vtab_in(P,N,F) 向 SQLite 表明虚拟表是否希望同时处理 IN 运算符。因此,当第三个参数 (F) 为非负数时,此接口是虚拟表告诉 SQLite 它希望如何处理 IN 运算符的机制。

可以在同一个 xBestIndex 方法调用中多次调用 sqlite3_vtab_in(P,N,F) 接口。对于任何给定的 P,N 对,sqlite3_vtab_in(P,N,F) 的返回值在同一个 xBestIndex 调用中将始终相同。如果接口返回 true(非零),则意味着约束是一个 IN 运算符,可以一次处理所有操作。如果约束不是 IN 运算符或不能一次处理所有,则接口返回 false。

如果同时满足以下两个条件,则选择 IN 运算符的一次性处理:

  1. P->aConstraintUsage[N].argvIndex 值设置为正整数。这就是虚拟表告诉 SQLite 它要使用第 N 个约束的方式。

  2. F 为非负的最后一次调用 sqlite3_vtab_in(P,N,F) 时 F>=1。

如果上述条件之一或两个都为假,则 SQLite 对 IN 约束使用传统的一次一个处理策略。如果两个条件都为真,那么 xFilter 方法的第 argvIndex 参数将是一个sqlite3_value,它看起来是 NULL,但它可以传递给sqlite3_vtab_in_first()sqlite3_vtab_in_next()以找到右侧的所有值IN 约束。


确定虚拟表列访问是否用于更新

int sqlite3_vtab_nochange(sqlite3_context*);

如果在虚拟表的xColumn 方法中 调用 sqlite3_vtab_nochange(X) 例程,那么如果列作为 UPDATE 操作的一部分被提取,则它可能返回 true,在此期间列值不会更改。虚拟表实现可以使用此提示作为替换返回值的许可,该返回值的计算成本较低,并且相应的 xUpdate方法将其理解为“无变化”值。

如果xColumn方法调用 sqlite3_vtab_nochange() 并发现该列未被 UPDATE 语句更改,则 xColumn 方法可以选择返回而不设置结果,而不调用任何sqlite3_result_xxxxx() 接口在这种情况下,sqlite3_value_nochange(X)将为xUpdate方法中的同一列返回 true 。

sqlite3_vtab_nochange() 例程是一种优化。即使 sqlite3_vtab_nochange() 接口总是返回 false,虚拟表实现也应该继续给出正确的答案。在当前的实现中,sqlite3_vtab_nochange() 接口总是为增强的UPDATE FROM语句返回 false。


确定虚拟表冲突策略

int sqlite3_vtab_on_conflict(sqlite3 *);

此函数只能在对 INSERT 或 UPDATE 操作的虚拟表实现的xUpdate方法的调用中调用。返回值是SQLITE_ROLLBACKSQLITE_IGNORESQLITE_FAILSQLITE_ABORTSQLITE_REPLACE之一,具体取决于触发调用虚拟表的xUpdate方法的 SQL 语句ON CONFLICT模式。


xBestIndex() 中的约束值

int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);

此 API 只能在虚拟表实现的xBestIndex 方法 中使用。从 xBestIndex 方法外部调用此接口的结果是未定义的,可能有害。

当从虚拟表实现的xBestIndex方法中调用 sqlite3_vtab_rhs_value(P,J,V) 接口时,P 是sqlite3_index_info的副本传递给 xBestIndex 的对象指针和 J 是 P->aConstraint[] 中从 0 开始的索引,然后如果右侧操作数已知,则此例程尝试将 *V 设置为该约束的右侧操作数的值。如果右侧操作数未知,则 *V 设置为 NULL 指针。当且仅当 *V 被设置为一个值时,sqlite3_vtab_rhs_value(P,J,V) 接口返回 SQLITE_OK。如果第 J 个约束的右侧不可用,则 sqlite3_vtab_rhs_value(P,J,V) 接口返回 SQLITE_NOTFOUND。如果出现问题,sqlite3_vtab_rhs_value() 接口可以返回 SQLITE_OK 或 SQLITE_NOTFOUND 以外的结果代码。

sqlite3_vtab_rhs_value() 接口通常只有在约束的右侧操作数是原始 SQL 语句中的文字值时才会成功。如果右侧操作数是一个表达式或对其他列或主机参数的引用,则 sqlite3_vtab_rhs_value() 可能会返回SQLITE_NOTFOUND

一些约束,例如SQLITE_INDEX_CONSTRAINT_ISNULLSQLITE_INDEX_CONSTRAINT_ISNOTNULL,没有右手操作数。对于此类约束,sqlite3_vtab_rhs_value() 始终返回 SQLITE_NOTFOUND。

*V 中返回的sqlite3_value对象是受保护的 sqlite3_value,并且在 xBestIndex 方法调用期间保持有效。当 xBestIndex 返回时,sqlite3_vtab_rhs_value() 返回的 sqlite3_value 对象会自动释放。

此例程名称中的“_rhs_”是“Right-Hand Side”的缩写。


配置自动检查点

int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);

sqlite3_wal_autocheckpoint(D,N)是sqlite3_wal_hook()包装器, 如果预写日志文件 中有 N 个或更多帧,它会导致数据库连接D 上的任何数据库在提交事务后自动检查点。传递零值或负值作为 nFrame 参数会完全禁用自动检查点。

此函数注册的回调将替换使用sqlite3_wal_hook()注册的任何现有回调。同样,使用sqlite3_wal_hook()注册回调会禁用此函数配置的自动检查点机制。

wal_autocheckpoint pragma可用于从 SQL 调用此接口。

由这种机制发起的检查点是 被动的。

每个新的数据库连接默认启用自动检查点,阈值为 1000 或SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 页。仅当发现默认设置对特定应用而言不是最佳设置时才需要使用此接口。


检查点数据库

int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);

sqlite3_wal_checkpoint(D,X) 等同于 sqlite3_wal_checkpoint_v2 (D,X, SQLITE_CHECKPOINT_PASSIVE ,0,0)。

简而言之,sqlite3_wal_checkpoint(D,X) 将 数据库连接D上的数据库X的预写日志中的内容传输到数据库文件中,并重置预写日志。有关其他信息,请参阅检查点文档。

该接口曾经是导致检查点发生的唯一方法。但是随后添加了更新更强大的sqlite3_wal_checkpoint_v2() 接口。保留此接口是为了向后兼容,并为需要手动启动回调但不需要sqlite3_wal_checkpoint_v2()的全部功能(和相应的复杂性)的应用程序提供便利。


检查点数据库

int sqlite3_wal_checkpoint_v2(
  sqlite3 *db,                    /* Database handle */
  const char *zDb,                /* Name of attached database (or NULL) */
  int eMode,                      /* SQLITE_CHECKPOINT_* value */
  int *pnLog,                     /* OUT: Size of WAL log in frames */
  int *pnCkpt                     /* OUT: Total number of frames checkpointed */
);

sqlite3_wal_checkpoint_v2(D,X,M,L,C)接口以M方式对数据库连接D的 数据库X进行checkpoint操作,状态信息回写成L和C指向的整数,M参数必须是有效的检查点模式

SQLITE_CHECKPOINT_PASSIVE
在不等待任何数据库读取器或写入器完成的情况下检查尽可能多的帧,如果日志中的所有帧都已检查点,则同步数据库文件。 SQLITE_CHECKPOINT_PASSIVE 模式下永远不会调用繁忙处理程序回调。另一方面,如果有并发的读者或作者,被动模式可能会使检查点未完成。

SQLITE_CHECKPOINT_FULL
此模式会阻塞(它调用 忙处理程序回调),直到没有数据库编写器并且所有读取器都从最新的数据库快照中读取。然后它检查日志文件中的所有帧并同步数据库文件。此模式在挂起时阻止新的数据库写入者,但允许新的数据库读取者继续畅通无阻。

SQLITE_CHECKPOINT_RESTART
此模式与 SQLITE_CHECKPOINT_FULL 的工作方式相同,此外,在检查点日志文件后,它会阻塞(调用 忙处理程序回调),直到所有读者都只从数据库文件中读取。这确保了下一个写入器将从头开始重新启动日志文件。与 SQLITE_CHECKPOINT_FULL 一样,此模式在挂起时阻止新的数据库写入器尝试,但不会阻止读取器。

SQLITE_CHECKPOINT_TRUNCATE
此模式的工作方式与 SQLITE_CHECKPOINT_RESTART 相同,此外它还会在成功返回之前将日志文件截断为零字节。

如果 pnLog 不为 NULL,则 *pnLog 设置为日志文件中的总帧数,如果检查点由于错误或数据库未处于WAL 模式而无法运行,则设置为 -1 。如果 pnCkpt 不为 NULL,则 *pnCkpt 设置为日志文件中检查点帧的总数(包括在调用函数之前已经设置的任何帧)或 -1 如果检查点由于错误而无法运行或因为数据库不是WAL模式。请注意,成功完成 SQLITE_CHECKPOINT_TRUNCATE 后,日志文件将被截断为零字节,因此 *pnLog 和 *pnCkpt 都将设置为零。

所有调用都在数据库文件上获得独占的“检查点”锁。如果有任何其他进程同时在运行检查点操作,则无法获取锁并返回 SQLITE_BUSY。即使配置了繁忙处理程序,在这种情况下也不会调用它。

SQLITE_CHECKPOINT_FULL、RESTART 和 TRUNCATE 模式还获得了数据库文件上的独占“写入器”锁。如果无法立即获得写锁,并且配置了忙处理程序,则会调用它并重试写锁,直到忙处理程序返回 0 或成功获得锁。如上所述,在等待数据库读取器时也会调用繁忙处理程序。如果繁忙处理程序在获得写入器锁之前或在等待数据库读取器时返回 0,则检查点操作从该点开始以与 SQLITE_CHECKPOINT_PASSIVE 相同的方式进行 - 检查点尽可能多的帧,而不会进一步阻塞。在这种情况下返回 SQLITE_BUSY。

如果参数 zDb 为 NULL 或指向零长度字符串,则将在所有附加数据库连接db 的 WAL 数据库上尝试指定的操作。在这种情况下,写入输出参数 *pnLog 和 *pnCkpt 的值是未定义的。如果在处理一个或多个附加的 WAL 数据库时遇到 SQLITE_BUSY 错误,则仍会尝试对任何剩余的附加数据库执行该操作,并在最后返回 SQLITE_BUSY。如果在处理附加数据库时发生任何其他错误,则放弃处理并立即将错误代码返回给调用者。如果在处理附加数据库时没有遇到错误(SQLITE_BUSY 或其他),则返回 SQLITE_OK。

如果数据库 zDb 是未处于 WAL 模式的附加数据库的名称,则返回 SQLITE_OK 并且 *pnLog 和 *pnCkpt 都设置为 -1。如果 zDb 不是 NULL(或零长度字符串)并且不是任何附加数据库的名称,则 SQLITE_ERROR 返回给调用者。

除非它返回 SQLITE_MISUSE,否则 sqlite3_wal_checkpoint_v2() 接口设置由sqlite3_errcode()sqlite3_errmsg()查询的错误信息

PRAGMA wal_checkpoint命令可用于从 SQL 调用此接口。


预写日志提交挂钩

void *sqlite3_wal_hook(
  sqlite3*,
  int(*)(void *,sqlite3*,const char*,int),
  void*
);

sqlite3_wal_hook()函数用于注册一个回调,每次在 wal 模式下将数据提交到数据库时都会调用该回调

在提交发生并释放数据库上的关联写锁后,SQLite 调用回调,因此实现可以根据需要读取、写入或检查数据库。

调用时传递给回调函数的第一个参数是注册回调时传递给 sqlite3_wal_hook() 的第三个参数的副本。第二个是数据库句柄的副本。第三个参数是写入的数据库的名称——“main”或ATTACH数据库的名称。第四个参数是预写日志文件中当前的页数,包括刚刚提交的页数。

回调函数通常应返回SQLITE_OK如果返回错误代码,该错误将通过 SQLite 代码库向上传播,导致引发回调的语句报告错误,尽管提交仍会发生。如果回调返回SQLITE_ROWSQLITE_DONE,或者如果它返回一个不对应于任何有效 SQLite 错误代码的值,则结果是未定义的。

单个数据库句柄一次最多可以注册一个预写日志回调。调用sqlite3_wal_hook()替换任何先前注册的预写日志回调。返回值是上一次调用的第三个参数的副本(如果有),或者为 0。请注意,sqlite3_wal_autocheckpoint()接口和 wal_autocheckpoint pragma都调用sqlite3_wal_hook()并将覆盖任何先前的sqlite3_wal_hook()设置。


结果代码

#define SQLITE_OK           0   /* Successful result */
/* beginning-of-error-codes */
#define SQLITE_ERROR        1   /* Generic error */
#define SQLITE_INTERNAL     2   /* 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 sqlite3_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   /* Unknown opcode in sqlite3_file_control() */
#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 use only */
#define SQLITE_SCHEMA      17   /* The database schema changed */
#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT  19   /* Abort due to constraint 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_FORMAT      24   /* Not used */
#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB      26   /* File opened that is not a database file */
#define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */
#define SQLITE_WARNING     28   /* Warnings from sqlite3_log() */
#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */
#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */
/* end-of-error-codes */

许多 SQLite 函数从此处显示的集合中返回一个整数结果代码,以指示成功或失败。

SQLite 的未来版本可能会添加新的错误代码。

另见:扩展结果代码定义


扩展结果代码

#define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
#define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))
#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
#define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
#define SQLITE_IOERR_BEGIN_ATOMIC      (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
#define SQLITE_IOERR_DATA              (SQLITE_IOERR | (32<<8))
#define SQLITE_IOERR_CORRUPTFS         (SQLITE_IOERR | (33<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
#define SQLITE_BUSY_TIMEOUT            (SQLITE_BUSY   |  (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
#define SQLITE_CANTOPEN_SYMLINK        (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
#define SQLITE_CORRUPT_INDEX           (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
#define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
#define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
#define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
#define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (4<<8))
#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8)) /* internal use only */

在其默认配置中,SQLite API 例程返回 30 个整数 结果代码之一。然而,经验表明,这些结果代码中的许多都过于粗粒度。它们并没有像程序员希望的那样提供关于问题的尽可能多的信息。为了解决这个问题,较新版本的 SQLite(3.3.8 2006-10-09 及更高版本)包括对其他结果代码的支持,这些代码提供有关错误的更多详细信息。使用sqlite3_extended_result_codes() API在每个数据库连接的基础上启用或禁用 这些扩展结果代码。或者,可以使用 sqlite3_extended_errcode()获取最近错误的扩展代码。


xAccess VFS 方法的标志

#define SQLITE_ACCESS_EXISTS    0
#define SQLITE_ACCESS_READWRITE 1   /* Used by PRAGMA temp_store_directory */
#define SQLITE_ACCESS_READ      2   /* Unused */

这些整数常量可以用作sqlite3_vfs对象的 xAccess 方法的第三个参数。它们确定 xAccess 方法正在寻找的权限类型。使用 SQLITE_ACCESS_EXISTS,xAccess 方法只是检查文件是否存在。使用 SQLITE_ACCESS_READWRITE,xAccess 方法检查命名目录是否可读和可写(换句话说,是否可以在目录中添加、删除和重命名文件)。SQLITE_ACCESS_READWRITE 常量当前仅由 temp_store_directory pragma使用,尽管这可能会在 SQLite 的未来版本中改变。使用 SQLITE_ACCESS_READ,xAccess 方法检查文件是否可读。SQLITE_ACCESS_READ 常量目前未使用,但它可能会在 SQLite 的未来版本中使用。


授权人操作代码

/******************************************* 3rd ************ 4th ***********/
#define SQLITE_CREATE_INDEX          1   /* Index Name      Table Name      */
#define SQLITE_CREATE_TABLE          2   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_INDEX     3   /* Index Name      Table Name      */
#define SQLITE_CREATE_TEMP_TABLE     4   /* Table Name      NULL            */
#define SQLITE_CREATE_TEMP_TRIGGER   5   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_TEMP_VIEW      6   /* View Name       NULL            */
#define SQLITE_CREATE_TRIGGER        7   /* Trigger Name    Table Name      */
#define SQLITE_CREATE_VIEW           8   /* View Name       NULL            */
#define SQLITE_DELETE                9   /* Table Name      NULL            */
#define SQLITE_DROP_INDEX           10   /* Index Name      Table Name      */
#define SQLITE_DROP_TABLE           11   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_INDEX      12   /* Index Name      Table Name      */
#define SQLITE_DROP_TEMP_TABLE      13   /* Table Name      NULL            */
#define SQLITE_DROP_TEMP_TRIGGER    14   /* Trigger Name    Table Name      */
#define SQLITE_DROP_TEMP_VIEW       15   /* View Name       NULL            */
#define SQLITE_DROP_TRIGGER         16   /* Trigger Name    Table Name      */
#define SQLITE_DROP_VIEW            17   /* View Name       NULL            */
#define SQLITE_INSERT               18   /* Table Name      NULL            */
#define SQLITE_PRAGMA               19   /* Pragma Name     1st arg or NULL */
#define SQLITE_READ                 20   /* Table Name      Column Name     */
#define SQLITE_SELECT               21   /* NULL            NULL            */
#define SQLITE_TRANSACTION          22   /* Operation       NULL            */
#define SQLITE_UPDATE               23   /* Table Name      Column Name     */
#define SQLITE_ATTACH               24   /* Filename        NULL            */
#define SQLITE_DETACH               25   /* Database Name   NULL            */
#define SQLITE_ALTER_TABLE          26   /* Database Name   Table Name      */
#define SQLITE_REINDEX              27   /* Index Name      NULL            */
#define SQLITE_ANALYZE              28   /* Table Name      NULL            */
#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
#define SQLITE_FUNCTION             31   /* NULL            Function Name   */
#define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
#define SQLITE_COPY                  0   /* No longer used */
#define SQLITE_RECURSIVE            33   /* NULL            NULL            */

sqlite3_set_authorizer()接口注册了一个回调函数,调用它来授权某些 SQL 语句操作回调的第二个参数是一个整数代码,用于指定正在授权的操作。这些是授权方回调可能传递的整数操作代码。

这些动作代码值表示要授权哪种操作。授权回调函数的第三个和第四个参数将是参数或 NULL,具体取决于将这些代码中的哪一个用作第二个参数。授权回调的第 5 个参数是数据库的名称(“main”、“temp”等)(如果适用)。授权回调的第 6 个参数是负责访问尝试的最内层触发器或视图的名称,如果此访问尝试直接来自顶级 SQL 代码,则为 NULL。


文本编码

#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
#define SQLITE_UTF16          4    /* Use native byte order */
#define SQLITE_ANY            5    /* Deprecated */
#define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */

这些常量定义了表示 SQLite 支持的各种文本编码的整数代码。


基本数据类型

#define SQLITE_INTEGER  1
#define SQLITE_FLOAT    2
#define SQLITE_BLOB     4
#define SQLITE_NULL     5
#ifdef SQLITE_TEXT
# undef SQLITE_TEXT
#else
# define SQLITE_TEXT     3
#endif
#define SQLITE3_TEXT     3

SQLite 中的每个值都具有五种基本数据类型之一:

这些常量是每种类型的代码。

请注意,SQLITE_TEXT 常量在 SQLite 版本 2 中也用于完全不同的含义。链接到 SQLite 版本 2 和 SQLite 版本 3 的软件应该使用 SQLITE3_TEXT,而不是 SQLITE_TEXT。


检查点模式值

#define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
#define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
#define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */

这些常量定义了作为第三个参数传递给sqlite3_wal_checkpoint_v2()接口 的“检查点模式”的所有有效值。有关每种检查点模式的含义的详细信息,请参阅sqlite3_wal_checkpoint_v2()文档。


配置选项

#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
#define SQLITE_CONFIG_PCACHE       14  /* no-op */
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE       29  /* sqlite3_int64 */

这些常量是可用的整数配置选项,可以作为第一个参数传递给sqlite3_config()接口。

在 SQLite 的未来版本中可能会添加新的配置选项。现有的配置选项可能会停止。应用程序应检查sqlite3_config()的返回码以确保调用有效。如果调用已停用或不受支持的配置选项,则sqlite3_config ()接口将返回非零错误代码。

SQLITE_CONFIG_SINGLETHREAD
此选项没有参数。此选项将 线程模式设置为单线程。换句话说,它禁用所有互斥并将 SQLite 置于只能由单个线程使用的模式。如果使用SQLITE_THREADSAFE=0编译时选项编译 SQLite,则无法更改线程模式的默认值单线程,因此如果使用 SQLITE_CONFIG_SINGLETHREAD 配置选项调用,sqlite3_config()将返回 SQLITE_ERROR 。

SQLITE_CONFIG_MULTITHREAD
此选项没有参数。此选项将 线程模式设置为多线程。换句话说,它禁用了数据库连接准备好的语句对象上的互斥。该应用程序负责序列化对 数据库连接准备好的语句的访问。但是启用了其他互斥锁,这样只要没有两个线程同时尝试使用同一个 数据库连接,SQLite 就可以在多线程环境中安全使用。如果使用SQLITE_THREADSAFE=0编译时选项编译 SQLite,则无法设置多线程线程模式,并且 如果使用 SQLITE_CONFIG_MULTITHREAD 配置选项调用,sqlite3_config()将返回SQLITE_ERROR 。

SQLITE_CONFIG_SERIALIZED
此选项没有参数。此选项将 线程模式设置为序列化。换句话说,此选项启用所有互斥锁,包括数据库连接准备好的语句对象上的递归互斥锁。在这种模式下(当使用SQLITE_THREADSAFE=1编译 SQLite 时,这是默认模式 )SQLite 库本身将序列化对数据库连接准备语句的访问,以便应用程序可以在不同线程中自由使用相同的数据库连接或相同的准备语句同时。如果 SQLite 是用SQLITE_THREADSAFE=0编译的编译时选项则无法设置序列化线程模式如果使用 SQLITE_CONFIG_SERIALIZED 配置选项调用,sqlite3_config()将返回SQLITE_ERROR 。

SQLITE_CONFIG_MALLOC
SQLITE_CONFIG_MALLOC 选项采用单个参数,该参数是指向sqlite3_mem_methods结构实例的指针。该参数指定替代的低级内存分配例程,用于代替 SQLite 中内置的内存分配例程。在sqlite3_config()调用返回之前, SQLite 会制作自己的sqlite3_mem_methods结构内容的私有副本。

SQLITE_CONFIG_GETMALLOC
SQLITE_CONFIG_GETMALLOC 选项采用单个参数,该参数是指向sqlite3_mem_methods结构实例的指针。sqlite3_mem_methods 结构中填充了当前定义的内存分配例程例如,此选项可用于使用模拟内存分配失败或跟踪内存使用情况的包装器来重载默认内存分配例程。

SQLITE_CONFIG_SMALL_MALLOC
SQLITE_CONFIG_SMALL_MALLOC 选项采用 int 类型的单个参数,解释为布尔值,如果为真,则向 SQLite 提示它应尽可能避免大内存分配。如果可以自由分配大量内存,SQLite 将运行得更快,但某些应用程序可能更愿意运行得更慢,以换取如果避免大量分配可能出现的内存碎片保证。这个提示通常是关闭的。

SQLITE_CONFIG_MEMSTATUS
SQLITE_CONFIG_MEMSTATUS 选项采用 int 类型的单个参数,解释为布尔值,它启用或禁用内存分配统计信息的收集。当禁用内存分配统计信息时,以下 SQLite 接口将变得不可操作: 默认情况下启用内存分配统计,除非使用SQLITE_DEFAULT_MEMSTATUS =0 编译 SQLite,在这种情况下默认禁用内存分配统计。

SQLITE_CONFIG_SCRATCH
SQLITE_CONFIG_SCRATCH 选项不再使用。

SQLITE_CONFIG_PAGECACHE
SQLITE_CONFIG_PAGECACHE 选项指定一个内存池,SQLite 可以将其用于具有默认页面缓存实现的数据库页面缓存。如果应用程序定义的页面缓存实现是使用SQLITE_CONFIG_PCACHE2加载的,则此配置选项是空操作SQLITE_CONFIG_PAGECACHE 有三个参数:指向 8 字节对齐内存 (pMem) 的指针、每个页面缓存行的大小 (sz) 和缓存行数 (N)。sz 参数应该是最大数据库页面的大小(512 和 65536 之间的 2 的幂)加上每个页面标题的一些额外字节。可以使用SQLITE_CONFIG_PCACHE_HDRSZ确定页眉所需的额外字节数. 除了浪费内存之外,sz 参数大于必要值是无害的。pMem 参数必须是 NULL 指针或指向至少 sz*N 字节的 8 字节对齐内存块的指针,否则后续行为未定义。当 pMem 不为 NULL 时,SQLite 将努力使用提供的内存来满足页面缓存需求,如果页面缓存行大于 sz 字节或所有 pMem 缓冲区都已耗尽,则回退到sqlite3_malloc() 。如果 pMem 为 NULL 且 N 非零,则每个数据库连接都会从sqlite3_malloc()为页面缓存内存进行初始批量分配如果 N 为正数,则足以用于 N 个缓存行;如果 N 为负数,则为 -1024*N 字节,. 如果需要超出初始分配提供的额外页面缓存内存,则 SQLite 会为每个额外的缓存行单独转到sqlite3_malloc() 。

SQLITE_CONFIG_HEAP
SQLITE_CONFIG_HEAP 选项指定一个静态内存缓冲区,SQLite 将使用它来满足SQLITE_CONFIG_PAGECACHE提供的所有动态内存分配需求SQLITE_CONFIG_HEAP 选项仅在使用SQLITE_ENABLE_MEMSYS3SQLITE_ENABLE_MEMSYS5编译 SQLite 时可用,否则返回 SQLITE_ERRORSQLITE_CONFIG_HEAP 有三个参数:指向内存的 8 字节对齐指针、内存缓冲区中的字节数和最小分配大小。如果第一个指针(内存指针)为 NULL,则 SQLite 恢复使用其默认内存分配器(系统 malloc() 实现),撤消之前对SQLITE_CONFIG_MALLOC的任何调用. 如果内存指针不为 NULL,则使用替代内存分配器来处理所有 SQLite 内存分配需求。第一个指针(内存指针)必须与 8 字节边界对齐,否则 SQLite 的后续行为将是未定义的。最小分配大小上限为 2**12。最小分配大小的合理值是 2**5 到 2**8。

SQLITE_CONFIG_MUTEX
SQLITE_CONFIG_MUTEX 选项采用单个参数,该参数是指向sqlite3_mutex_methods结构实例的指针。该参数指定替代的低级互斥例程,用于替代 SQLite 中内置的互斥例程。在对sqlite3_config()的调用返回之前, SQLite 会复制sqlite3_mutex_methods结构 的内容如果 SQLite 是使用SQLITE_THREADSAFE=0编译时选项编译的,那么整个互斥子系统将从构建中省略,因此使用 SQLITE_CONFIG_MUTEX 配置选项调用 sqlite3_config()将返回SQLITE_ERROR

SQLITE_CONFIG_GETMUTEX
SQLITE_CONFIG_GETMUTEX 选项采用单个参数,该参数是指向sqlite3_mutex_methods结构实例的指针。sqlite3_mutex_methods 结构填充了当前定义的互斥例程例如,此选项可用于使用用于跟踪互斥使用情况以进行性能分析或测试的包装器来重载默认互斥分配例程。如果 SQLite 是使用SQLITE_THREADSAFE=0编译时选项编译的,那么整个互斥子系统将从构建中省略,因此使用 SQLITE_CONFIG_GETMUTEX 配置选项调用 sqlite3_config()将返回SQLITE_ERROR

SQLITE_CONFIG_LOOKASIDE
SQLITE_CONFIG_LOOKASIDE 选项采用两个参数来确定每个数据库连接上后备内存的默认大小。第一个参数是每个后备缓冲区槽的大小,第二个是分配给每个数据库连接的槽数。SQLITE_CONFIG_LOOKASIDE 设置默认后备大小。sqlite3_db_config()SQLITE_DBCONFIG_LOOKASIDE 选项可用于更改单个连接的后备配置。

SQLITE_CONFIG_PCACHE2
SQLITE_CONFIG_PCACHE2 选项采用单个参数,该参数是指向sqlite3_pcache_methods2对象的指针。该对象指定自定义页面缓存实现的接口。SQLite 复制了sqlite3_pcache_methods2对象。

SQLITE_CONFIG_GETPCACHE2
SQLITE_CONFIG_GETPCACHE2 选项采用单个参数,该参数是指向sqlite3_pcache_methods2对象的指针。SQLite 将当前页面缓存实现的副本复制到该对象中。

SQLITE_CONFIG_LOG
SQLITE_CONFIG_LOG 选项用于配置 SQLite 全局错误日志(SQLITE_CONFIG_LOG 选项有两个参数:一个指向调用签名为 void(*)(void*,int,const char*) 的函数的指针,以及一个指向 void 的指针。如果函数指针不为 NULL,则调用它通过sqlite3_log()处理每个日志记录事件。如果函数指针为 NULL,则sqlite3_log()接口变为无操作。作为 SQLITE_CONFIG_LOG 的第二个参数的空指针作为第一个参数传递给应用程序定义的每当调用该函数时记录器函数。记录器函数的第二个参数是相应 sqlite3_log()调用的第一个参数的副本,旨在成为结果代码扩展结果代码传递给记录器的第三个参数是通过sqlite3_snprintf()格式化后的日志消息SQLite 日志记录接口是不可重入的;应用程序提供的记录器函数不得调用任何 SQLite 接口。在多线程应用程序中,应用程序定义的记录器函数必须是线程安全的。

SQLITE_CONFIG_URI
SQLITE_CONFIG_URI 选项接受一个 int 类型的参数。如果非零,则全局启用 URI 处理。如果参数为零,则全局禁用 URI 处理。如果全局启用 URI 处理,则所有传递给sqlite3_open()sqlite3_open_v2()sqlite3_open16()或指定为ATTACH命令的一部分的文件名都被解释为 URI,无论在打开数据库连接时是否设置了SQLITE_OPEN_URI标志. 如果它是全局禁用的,则只有在打开数据库连接时设置了 SQLITE_OPEN_URI 标志时,文件名才会被解释为 URI。默认情况下,URI 处理是全局禁用的。默认值可以通过编译来改变 SQLITE_USE_URI符号定义。

SQLITE_CONFIG_COVERING_INDEX_SCAN
SQLITE_CONFIG_COVERING_INDEX_SCAN 选项采用单个整数参数,该参数被解释为布尔值,以便在查询优化器中启用或禁用覆盖索引以进行全表扫描。默认设置由SQLITE_ALLOW_COVERING_INDEX_SCAN编译时选项确定,或者如果省略该编译时选项则为“on”。禁用全表扫描覆盖索引的能力是因为一些错误编码的遗留应用程序在启用优化时可能会出现故障。提供禁用优化的能力允许旧的、有错误的应用程序代码无需更改即可工作,即使使用较新版本的 SQLite。

SQLITE_CONFIG_PCACHE 和 SQLITE_CONFIG_GETPCACHE
这些选项已过时,不应由新代码使用。保留它们是为了向后兼容,但现在是空操作。

SQLITE_CONFIG_SQLLOG
此选项仅在使用 SQLITE_ENABLE_SQLLOG编译 sqlite 时可用预处理器宏定义。第一个参数应该是指向类型为 void(*)(void*,sqlite3*,const char*, int) 的函数的指针。第二个应该是类型 (void*)。回调由库在三种不同的情况下调用,由作为第四个参数传递的值标识。如果第四个参数为0,那么作为第二个参数传递的数据库连接刚刚打开。第三个参数指向包含主数据库文件名称的缓冲区。如果第四个参数为1,那么第三个参数指向的SQL语句刚刚执行完毕。或者,如果第四个参数为 2,则作为第二个参数传递的连接将被关闭。第三个参数传给NULL,在这种情况下。在“test_sqllog.c”中可以看到使用此配置选项的示例

SQLITE_CONFIG_MMAP_SIZE
SQLITE_CONFIG_MMAP_SIZE 采用两个 64 位整数 (sqlite3_int64) 值,它们是默认的 mmap 大小限制( PRAGMA mmap_size的默认设置)和允许的最大 mmap 大小限制。每个数据库连接都可以使用PRAGMA mmap_size命令或使用 SQLITE_FCNTL_MMAP_SIZE文件控制来覆盖默认设置。如有必要,允许的最大 mmap 大小将被静默截断,以使其不超过 SQLITE_MAX_MMAP_SIZE编译时选项设置的编译时最大 mmap 大小。如果此选项的任一参数为负,则该参数将更改为其编译时默认值。

SQLITE_CONFIG_WIN32_HEAPSIZE
SQLITE_CONFIG_WIN32_HEAPSIZE 选项仅在 SQLite 为 Windows 编译并定义了SQLITE_WIN32_MALLOC预处理器宏时才可用。SQLITE_CONFIG_WIN32_HEAPSIZE 采用 32 位无符号整数值,指定创建堆的最大大小。

SQLITE_CONFIG_PCACHE_HDRSZ
SQLITE_CONFIG_PCACHE_HDRSZ 选项采用单个参数,该参数是一个指向整数的指针,并将SQLITE_CONFIG_PAGECACHE中每一页所需的每页额外字节数写入该整数所需的额外空间量可能因编译器、目标平台和 SQLite 版本而异。

SQLITE_CONFIG_PMASZ
SQLITE_CONFIG_PMASZ 选项采用一个无符号整数参数,并将多线程排序器的“最小 PMA 大小”设置为该整数。默认最小 PMA 大小由 SQLITE_SORTER_PMASZ编译时选项设置。当启用多线程排序(使用PRAGMA threads命令)并且要排序的内容量超过页面大小乘以 PRAGMA cache_size设置和此值的最小值时,将启动新线程以帮助进行排序操作。

SQLITE_CONFIG_STMTJRNL_SPILL
SQLITE_CONFIG_STMTJRNL_SPILL 选项采用单个参数,该参数成为语句日志溢出到磁盘的阈值。 语句日志保存在内存中,直到它们的大小(以字节为单位)超过此阈值,此时它们被写入磁盘。或者,如果阈值为 -1,则语句日志始终专门保存在内存中。由于许多语句日志永远不会变大,将溢出阈值设置为 64KiB 等值可以大大减少支持语句回滚所需的 I/O 量。此设置的默认值由 SQLITE_STMTJRNL_SPILL编译时选项控制。

SQLITE_CONFIG_SORTERREF_SIZE
SQLITE_CONFIG_SORTERREF_SIZE 选项接受类型为 (int) 的单个参数——排序器引用大小阈值的新值。通常,当 SQLite 使用外部排序根据 ORDER BY 子句对记录进行排序时,调用者需要的所有字段都存在于排序的记录中。但是,如果 SQLite 根据表列的声明类型确定它的值可能非常大——大于配置的排序器引用大小阈值——那么引用将存储在每个排序记录中,并从中加载所需的列值数据库作为记录按排序顺序返回。此选项的默认值是从不使用此优化。为此选项指定一个负值将恢复默认行为。此选项仅在使用 SQLite 编译时可用 SQLITE_ENABLE_SORTER_REFERENCES编译时选项。

SQLITE_CONFIG_MEMDB_MAXSIZE
SQLITE_CONFIG_MEMDB_MAXSIZE 选项接受单个参数 sqlite3_int64参数,这是使用sqlite3_deserialize()创建的内存数据库的默认最大大小可以使用SQLITE_FCNTL_SIZE_LIMIT file-control为单个数据库向上或向下调整此默认最大大小 如果从未使用过此配置设置,则默认最大值由SQLITE_MEMDB_DEFAULT_MAXSIZE编译时选项确定。如果未设置该编译时选项,则默认最大值为 1073741824。


数据库连接配置选项

#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
#define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
#define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
#define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */

这些常量是可用的整数配置选项,可以作为第二个参数传递给sqlite3_db_config()接口。

在 SQLite 的未来版本中可能会添加新的配置选项。现有的配置选项可能会停止。应用程序应检查sqlite3_db_config()的返回码以确保调用有效。如果调用已停用或不受支持的配置选项,则sqlite3_db_config ()接口将返回非零错误代码。

SQLITE_DBCONFIG_LOOKASIDE
此选项采用三个附加参数来确定 数据库连接的后备内存分配器配置第一个参数(sqlite3_db_config()的第三个参数是指向用于后备内存的内存缓冲区的指针。SQLITE_DBCONFIG_LOOKASIDE 动词之后的第一个参数可能为 NULL,在这种情况下,SQLite 将使用sqlite3_malloc()自行分配后备缓冲区. 第二个参数是每个后备缓冲区槽的大小。第三个参数是槽的数量。第一个参数中缓冲区的大小必须大于或等于第二个和第三个参数的乘积。缓冲区必须与 8 字节边界对齐。如果 SQLITE_DBCONFIG_LOOKASIDE 的第二个参数不是 8 的倍数,它会在内部向下舍入到下一个更小的 8 倍数。数据库连接的后备内存配置只能在该连接当前未使用后备内存时更改,或者在换句话说,当 sqlite3_db_status (D, SQLITE_CONFIG_LOOKASIDE,...) 为零。当后备内存正在使用时,任何更改后备内存配置的尝试都会使配置保持不变并返回 SQLITE_BUSY

SQLITE_DBCONFIG_ENABLE_FKEY
此选项用于启用或禁用 外键约束的实施。应该有两个额外的参数。第一个参数是一个整数,为 0 表示禁用 FK 强制执行,为正表示启用 FK 强制执行或为负表示保持 FK 强制执行不变。第二个参数是一个指向整数的指针,写入 0 或 1 以指示在此调用之后 FK 强制执行是关闭还是打开。第二个参数可以是 NULL 指针,在这种情况下,不会报告 FK 强制设置。

SQLITE_DBCONFIG_ENABLE_TRIGGER
该选项用于启用或禁用触发器应该有两个额外的参数。第一个参数是一个整数,0 表示禁用触发器,正数表示启用触发器,负数表示保持设置不变。第二个参数是指向一个整数的指针,写入 0 或 1 以指示在该调用之后触发器是被禁用还是被启用。第二个参数可以是 NULL 指针,在这种情况下不会报告触发器设置。

最初此选项禁用所有触发器。但是,从 SQLite 版本 3.35.0 开始,即使关闭此选项,仍然允许使用 TEMP 触发器。因此,换句话说,此选项现在仅禁用主数据库模式或 ATTACH 数据库模式中的触发器。

SQLITE_DBCONFIG_ENABLE_VIEW
此选项用于启用或禁用视图应该有两个额外的参数。第一个参数是一个整数,0 表示禁用视图,正数表示启用视图,负数表示保持设置不变。第二个参数是一个指向整数的指针,其中写入 0 或 1 以指示在该调用之后视图是禁用还是启用。第二个参数可以是 NULL 指针,在这种情况下不会报告视图设置。

最初此选项禁用所有视图。但是,从 SQLite 版本 3.35.0 开始,即使关闭此选项,仍然允许使用 TEMP 视图。因此,换句话说,此选项现在仅禁用主数据库模式或 ATTACH 数据库模式中的视图。

SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
此选项用于启用或禁用 fts3_tokenizer()函数,该函数是 FTS3全文搜索引擎扩展的一部分。应该有两个额外的参数。第一个参数是一个整数,它是 0 以禁用 fts3_tokenizer() 或正数以启用 fts3_tokenizer() 或负数以保持设置不变。第二个参数是一个指向整数的指针,写入 0 或 1 以指示在此调用后 fts3_tokenizer 是禁用还是启用。第二个参数可能是一个 NULL 指针,在这种情况下,新设置不会被报告回来。

SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
此选项用于独立于load_extension() SQL 函数启用或禁用sqlite3_load_extension() 接口。sqlite3_enable_load_extension() API启用或禁用 C-API sqlite3_load_extension()和 SQL 函数load_extension(). 应该有两个额外的参数。当此接口的第一个参数为 1 时,则仅启用 C-API 而 SQL 功能保持禁用状态。如果此接口的第一个参数为 0,则 C-API 和 SQL 函数都被禁用。如果第一个参数是 -1,则不会对 C-API 或 SQL 函数的状态进行任何更改。第二个参数是一个指向整数的指针,写入 0 或 1 以指示在此调用后sqlite3_load_extension()接口是禁用还是启用。第二个参数可能是一个 NULL 指针,在这种情况下,新设置不会被报告回来。

SQLITE_DBCONFIG_MAINDBNAME
此选项用于更改“主”数据库模式的名称。唯一的参数是一个指向常量 UTF8 字符串的指针,该字符串将成为新模式名称以代替“main”。SQLite 不会复制新的主模式名称字符串,因此应用程序必须确保传递到此 DBCONFIG 选项的参数在数据库连接关闭之前保持不变。

SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
通常,当处于 wal 模式的数据库关闭或与数据库句柄分离时,SQLite 会检查这是否意味着现在根本没有与数据库的连接。如果是这样,它会在关闭连接之前执行检查点操作。此选项可用于覆盖此行为。传递给此操作的第一个参数是一个整数 - 正数表示禁用关闭检查点,或零(默认值)启用它们,负数表示保持设置不变。第二个参数是指向一个整数的指针,写入 0 或 1 以指示关闭时检查点是否已被禁用 - 如果未禁用则为 0,如果已禁用则为 1。

SQLITE_DBCONFIG_ENABLE_QPSG
SQLITE_DBCONFIG_ENABLE_QPSG 选项激活或停用查询规划器稳定性保证(QPSG)。当 QPSG 处于活动状态时,无论绑定参数的值如何,单个 SQL 查询语句将始终使用相同的算法. QPSG 禁用了一些查看绑定参数值的查询优化,这会使某些查询变慢。但 QPSG 的优势在于行为更可预测。在 QPSG 处于活动状态时,SQLite 将始终在现场使用与在实验室测试期间使用的查询计划相同的查询计划。此设置的第一个参数是一个整数,0 表示禁用 QPSG,正数表示启用 QPSG,负数表示保持设置不变。第二个参数是一个指向整数的指针,写入 0 或 1 以指示在此调用后 QPSG 是禁用还是启用。

SQLITE_DBCONFIG_TRIGGER_EQP
默认情况下,EXPLAIN QUERY PLAN 命令的输出不包括触发器程序执行的任何操作的输出。此选项用于设置或清除(默认)控制此行为的标志。传递给此操作的第一个参数是一个整数 - 正数表示启用触发程序的输出,零表示禁用它,负数表示保持设置不变。第二个参数是一个指向整数的指针,其中写入 0 或 1 以指示触发器输出是否已被禁用 - 如果未禁用,则为 0,如果已禁用,则为 1。

SQLITE_DBCONFIG_RESET_DATABASE
设置 SQLITE_DBCONFIG_RESET_DATABASE 标志,然后运行 ​​VACUUM以将数据库重置回没有模式和内容的空数据库。以下过程甚至适用于严重损坏的数据库文件:
  1. 如果数据库连接是新打开的,请通过准备然后丢弃对数据库的一些查询或调用 sqlite3_table_column_metadata() 来确保它已读取数据库模式,忽略任何错误。仅当应用程序希望在重置后将数据库保持在 WAL 模式(如果重置前处于 WAL 模式)时才需要执行此步骤。
  2. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
  3. sqlite3_exec (db, "真空", 0, 0, 0);
  4. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
由于重置数据库具有破坏性和不可逆性,因此该过程需要使用这个晦涩的 API 和多个步骤来帮助确保不会意外发生。

SQLITE_DBCONFIG_DEFENSIVE
SQLITE_DBCONFIG_DEFENSIVE 选项激活或停用数据库连接的“防御”标志。启用防御标志后,将禁用允许普通 SQL 故意损坏数据库文件的语言功能。禁用的功能包括但不限于以下:

SQLITE_DBCONFIG_WRITABLE_SCHEMA
SQLITE_DBCONFIG_WRITABLE_SCHEMA 选项激活或停用“writable_schema”标志。这具有相同的效果,并且在逻辑上等同于设置PRAGMA writable_schema=ONPRAGMA writable_schema=OFF此设置的第一个参数是一个整数,0 表示禁用 writable_schema,正数表示启用 writable_schema,负数表示保持设置不变。第二个参数是一个指向整数的指针,写入 0 或 1 以指示在此调用后 writable_schema 是启用还是禁用。

SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 选项激活或停用ALTER TABLE RENAME命令的遗留行为,使其行为与版本 3.24.0 (2018-06-04) 之前一样。有关其他信息,请参阅ALTER TABLE RENAME 文档中的“兼容性声明” 。也可以使用PRAGMA legacy_alter_table语句 打开和关闭此功能。

SQLITE_DBCONFIG_DQS_DML
SQLITE_DBCONFIG_DQS_DML 选项仅针对 DML 语句(即 DELETE、INSERT、SELECT 和 UPDATE 语句)激活或停用遗留的双引号字符串文字错误功能。此设置的默认值由-DSQLITE_DQS 编译时选项确定。

SQLITE_DBCONFIG_DQS_DDL
SQLITE_DBCONFIG_DQS 选项激活或停用DDL 语句(例如 CREATE TABLE 和 CREATE INDEX)的遗留双引号字符串文字错误功能。此设置的默认值由-DSQLITE_DQS 编译时选项确定。

SQLITE_DBCONFIG_TRUSTED_SCHEMA
SQLITE_DBCONFIG_TRUSTED_SCHEMA 选项告诉 SQLite 假设数据库模式未被恶意内容污染。当 SQLITE_DBCONFIG_TRUSTED_SCHEMA 选项被禁用时,SQLite 采取额外的防御措施来保护应用程序免受伤害,包括:
  • 禁止在触发器、视图、CHECK 约束、DEFAULT 子句、表达式索引、部分索引或生成的列中使用 SQL 函数,除非这些函数被标记为SQLITE_INNOCUOUS
  • 禁止在触发器或视图中使用虚拟表,除非这些虚拟表被标记为SQLITE_VTAB_INNOCUOUS
此设置默认为“开”以实现旧版兼容性,但建议所有应用程序尽可能将其关闭。也可以使用PRAGMA trusted_schema语句控制此设置。

SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 选项激活或停用旧文件格式标志。激活时,此标志会导致所有新创建的数据库文件的模式格式版本号(在数据库头的偏移量 44 处找到的 4 字节整数)为 1。这反过来意味着生成的数据库文件将是可读和可写的通过任何 SQLite 版本回到 3.0.0 (2004-06-18)。如果没有此设置,SQLite 3.3.0 (2006-01-11) 之前的版本通常无法理解新创建的数据库。正如这些话所写的那样,现在几乎不需要生成一直兼容到 3.0.0 版本的数据库文件,因此这个设置几乎没有实际用处,但提供它是为了让 SQLite 可以继续要求能够生成与版本 3 兼容的新数据库文件。

请注意,当 SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 设置打开时,VACUUM命令在尝试处理具有生成的列和降序索引的表时将失败并出现一个模糊的错误。这不被认为是一个错误,因为 SQLite 版本 3.3.0 和更早版本不支持生成的列或降序索引。


授权方返回码

#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

授权者回调函数必须返回SQLITE_OK或 这两个常量之一,以便向 SQLite 发出该操作是否被允许的信号。有关其他信息,请参阅 授权方文档

请注意,SQLITE_IGNORE 也用作从sqlite3_vtab_on_conflict()接口 返回的冲突解决模式。


sqlite3_deserialize() 的标志

#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
#define SQLITE_DESERIALIZE_RESIZEABLE  2 /* Resize using sqlite3_realloc64() */
#define SQLITE_DESERIALIZE_READONLY    4 /* Database is read-only */

以下是sqlite3_deserialize(D,S,P,N,M,F)接口的第 6 个参数(F 参数)的允许值。

SQLITE_DESERIALIZE_FREEONCLOSE 意味着 P 参数中的数据库序列化保存在从sqlite3_malloc64()获得的内存中 ,并且 SQLite 应该取得这块内存的所有权并在它使用完后自动释放它。如果没有这个标志,调用者负责释放任何动态分配的内存。

SQLITE_DESERIALIZE_RESIZEABLE 标志意味着允许 SQLite 使用调用sqlite3_realloc64()来增加数据库的大小。仅当还使用 SQLITE_DESERIALIZE_FREEONCLOSE 时才应使用此标志。没有这个标志,反序列化数据库的大小不能增加到超过 M 参数指定的字节数。

SQLITE_DESERIALIZE_READONLY 标志意味着反序列化的数据库应该被视为只读的。


函数标志

#define SQLITE_DETERMINISTIC    0x000000800
#define SQLITE_DIRECTONLY       0x000080000
#define SQLITE_SUBTYPE          0x000100000
#define SQLITE_INNOCUOUS        0x000200000

这些常量可以与 首选文本编码一起作为sqlite3_create_function()sqlite3_create_function16()sqlite3_create_function_v2()的第四个参数进行或运算

SQLITE_DETERMINISTIC
SQLITE_DETERMINISTIC 标志意味着当输入参数相同时,新函数总是给出相同的输出。例如, abs() 函数是确定性的,但 randomblob()不是。函数必须是确定性的,以便在某些上下文中使用,例如与部分索引的 WHERE 子句一起使用或在生成的列中使用。SQLite 还可以通过将确定性函数从内部循环中分解出来来优化确定性函数。

SQLITE_DIRECTONLY
SQLITE_DIRECTONLY 标志意味着该函数只能从顶级 SQL 调用,不能在 VIEW 或 TRIGGER 中使用,也不能在模式结构中使用,例如CHECK 约束DEFAULT 子句表达式索引部分索引生成的列SQLITE_DIRECTONLY 标志是一项安全功能,推荐用于所有应用程序定义的 SQL 函数,尤其是具有副作用或可能泄露敏感信息的函数。

SQLITE_INNOCUOUS
SQLITE_INNOCUOUS 标志意味着该函数即使被误用也不太可能导致问题。一个无害的函数应该没有副作用,并且不应该依赖于它的输入参数以外的任何值。abs() 函数是一个无害函数的例子load_extension () SQL 函数并非无害,因为它有副作用。

SQLITE_INNOCUOUS 类似于 SQLITE_DETERMINISTIC,但并不完全相同。random() 函数是一个无害但不确定的函数示例

某些增强的安全设置(SQLITE_DBCONFIG_TRUSTED_SCHEMAPRAGMA trusted_schema=OFF)禁止在视图和触发器以及模式结构(例如CHECK 约束DEFAULT 子句表达式索引部分索引生成的列)中使用 SQL 函数,除非函数被标记为 SQLITE_INNOCUOUS . 大多数内置函数都是无害的。建议开发人员避免将 SQLITE_INNOCUOUS 标志用于应用程序定义的函数,除非该函数经过仔细审核并发现没有潜在的安全不利副作用和信息泄漏。

SQLITE_SUBTYPE
SQLITE_SUBTYPE 标志向 SQLite 表明函数可以调用 sqlite3_value_subtype()来检查其参数的子类型。指定此标志对标量或聚合用户函数没有影响。但是,如果没有为用户定义的窗口函数指定,则在调用窗口函数之前,属于传递给窗口函数的参数的任何子类型都可能被丢弃(即 sqlite3_value_subtype() 将始终返回 0)。


冲突解决模式

#define SQLITE_ROLLBACK 1
/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
#define SQLITE_FAIL     3
/* #define SQLITE_ABORT 4  // Also an error code */
#define SQLITE_REPLACE  5

这些常量由sqlite3_vtab_on_conflict()返回,以通知虚拟表实现对于正在评估的 SQL 语句,ON CONFLICT模式是什么。

请注意,SQLITE_IGNORE常量也用作sqlite3_set_authorizer()回调的潜在返回值,并且 SQLITE_ABORT也是结果代码


标准文件控制操作码

#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
#define SQLITE_FCNTL_LAST_ERRNO              4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15
#define SQLITE_FCNTL_TEMPFILENAME           16
#define SQLITE_FCNTL_MMAP_SIZE              18
#define SQLITE_FCNTL_TRACE                  19
#define SQLITE_FCNTL_HAS_MOVED              20
#define SQLITE_FCNTL_SYNC                   21
#define SQLITE_FCNTL_COMMIT_PHASETWO        22
#define SQLITE_FCNTL_WIN32_SET_HANDLE       23
#define SQLITE_FCNTL_WAL_BLOCK              24
#define SQLITE_FCNTL_ZIPVFS                 25
#define SQLITE_FCNTL_RBU                    26
#define SQLITE_FCNTL_VFS_POINTER            27
#define SQLITE_FCNTL_JOURNAL_POINTER        28
#define SQLITE_FCNTL_WIN32_GET_HANDLE       29
#define SQLITE_FCNTL_PDB                    30
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
#define SQLITE_FCNTL_LOCK_TIMEOUT           34
#define SQLITE_FCNTL_DATA_VERSION           35
#define SQLITE_FCNTL_SIZE_LIMIT             36
#define SQLITE_FCNTL_CKPT_DONE              37
#define SQLITE_FCNTL_RESERVE_BYTES          38
#define SQLITE_FCNTL_CKPT_START             39
#define SQLITE_FCNTL_EXTERNAL_READER        40
#define SQLITE_FCNTL_CKSM_FILE              41

这些整数常量是sqlite3_io_methods对象 的 xFileControl 方法和sqlite3_file_control() 接口的操作码。

  • EXPERIMENTAL SQLITE_FCNTL_EXTERNAL_READER操作码用于检测另一个进程中是否有数据库客户端,并且在数据库上打开了 wal-mode 事务。它仅在 unix 上可用。与此文件控制一起传递的 (void*) 参数应该是指向类型 (int) 值的指针。如果数据库是 wal 模式数据库并且当前在数据库上打开了 SQL 事务的另一个进程中至少存在一个客户端,则整数值设置为 1。如果数据库不是 wal-mode db,或者如果在任何其他进程中没有这样的连接,它被设置为 0。此操作码不能用于检测客户端在当前进程中打开的事务,只能用于其他进程中。

  • 仅由 cksmvfs VFS 模块使用。


    虚拟表约束运算符代码

    #define SQLITE_INDEX_CONSTRAINT_EQ          2
    #define SQLITE_INDEX_CONSTRAINT_GT          4
    #define SQLITE_INDEX_CONSTRAINT_LE          8
    #define SQLITE_INDEX_CONSTRAINT_LT         16
    #define SQLITE_INDEX_CONSTRAINT_GE         32
    #define SQLITE_INDEX_CONSTRAINT_MATCH      64
    #define SQLITE_INDEX_CONSTRAINT_LIKE       65
    #define SQLITE_INDEX_CONSTRAINT_GLOB       66
    #define SQLITE_INDEX_CONSTRAINT_REGEXP     67
    #define SQLITE_INDEX_CONSTRAINT_NE         68
    #define SQLITE_INDEX_CONSTRAINT_ISNOT      69
    #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL  70
    #define SQLITE_INDEX_CONSTRAINT_ISNULL     71
    #define SQLITE_INDEX_CONSTRAINT_IS         72
    #define SQLITE_INDEX_CONSTRAINT_LIMIT      73
    #define SQLITE_INDEX_CONSTRAINT_OFFSET     74
    #define SQLITE_INDEX_CONSTRAINT_FUNCTION  150
    

    这些宏定义了 sqlite3_index_info .aConstraint[].op 字段的允许值。每个值代表一个运算符,它是使用虚拟表的查询的 WHERE 子句中约束项的一部分。

    运算符的左侧操作数由相应的 aConstraint[].iColumn 字段给出。iColumn 为 -1 表示左侧操作数是 rowid。SQLITE_INDEX_CONSTRAINT_LIMIT 和 SQLITE_INDEX_CONSTRAINT_OFFSET 运算符没有左手操作数,因此对于这些运算符,相应的 aConstraint[].iColumn 没有意义,不应使用。

    从 SQLITE_INDEX_CONSTRAINT_FUNCTION 到值 255 的所有运算符值都被保留以表示由虚拟表实现的xFindFunction 方法重载的函数。

    可以使用sqlite3_vtab_rhs_value()接口访问每个约束的右侧操作数。通常,右侧操作数只有在输入 SQL 中显示为单个常量文字时才可用。如果右侧操作数是另一列或表达式(甚至是常量表达式)或参数,则 sqlite3_vtab_rhs_value() 可能无法提取它。SQLITE_INDEX_CONSTRAINT_ISNULL 和 SQLITE_INDEX_CONSTRAINT_ISNOTNULL 运算符没有右手操作数,因此对这些运算符调用 sqlite3_vtab_rhs_value() 将始终返回 SQLITE_NOTFOUND。

    可以使用sqlite3_vtab_collat​​ion()接口找到用于比较的整理顺序。对于大多数现实世界的虚拟表,约束的整理顺序并不重要(例如,因为约束是数字的),因此通常不需要 sqlite3_vtab_collat​​ion() 接口。


    设备特性

    #define SQLITE_IOCAP_ATOMIC                 0x00000001
    #define SQLITE_IOCAP_ATOMIC512              0x00000002
    #define SQLITE_IOCAP_ATOMIC1K               0x00000004
    #define SQLITE_IOCAP_ATOMIC2K               0x00000008
    #define SQLITE_IOCAP_ATOMIC4K               0x00000010
    #define SQLITE_IOCAP_ATOMIC8K               0x00000020
    #define SQLITE_IOCAP_ATOMIC16K              0x00000040
    #define SQLITE_IOCAP_ATOMIC32K              0x00000080
    #define SQLITE_IOCAP_ATOMIC64K              0x00000100
    #define SQLITE_IOCAP_SAFE_APPEND            0x00000200
    #define SQLITE_IOCAP_SEQUENTIAL             0x00000400
    #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
    #define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
    #define SQLITE_IOCAP_IMMUTABLE              0x00002000
    #define SQLITE_IOCAP_BATCH_ATOMIC           0x00004000
    

    sqlite3_io_methods对象 的 xDeviceCharacteristics 方法 返回一个整数,它是这些位值的向量,表示保存sqlite3_io_methods 引用的文件的大容量存储设备的 I/O 特性。

    SQLITE_IOCAP_ATOMIC 属性意味着任何大小的所有写入都是原子的。SQLITE_IOCAP_ATOMICnnn 值意味着写入大小为 nnn 字节且与 nnn 的整数倍地址对齐的块是原子的。SQLITE_IOCAP_SAFE_APPEND 值意味着当数据附加到文件时,首先附加数据,然后扩展文件的大小,而不是相反。SQLITE_IOCAP_SEQUENTIAL 属性意味着信息写入磁盘的顺序与调用 xWrite() 的顺序相同。SQLITE_IOCAP_POWERSAFE_OVERWRITE 属性意味着在崩溃或断电后重新启动后,在应用程序级别写入的文件中的唯一字节可能已经更改,并且相邻字节,甚至同一扇区内的字节保证不变。SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 标志表示文件在打开时无法删除。SQLITE_IOCAP_IMMUTABLE 标志表示该文件位于只读介质上,即使具有提升权限的进程也无法更改。

    SQLITE_IOCAP_BATCH_ATOMIC 属性意味着当这些写操作被SQLITE_FCNTL_BEGIN_ATOMIC_WRITESQLITE_FCNTL_COMMIT_ATOMIC_WRITE括起来时,底层文件系统支持原子地执行多个写操作。


    文件锁定级别

    #define SQLITE_LOCK_NONE          0
    #define SQLITE_LOCK_SHARED        1
    #define SQLITE_LOCK_RESERVED      2
    #define SQLITE_LOCK_PENDING       3
    #define SQLITE_LOCK_EXCLUSIVE     4
    

    SQLite 使用这些整数值之一作为第二个参数来调用它对sqlite3_io_methods对象 的 xLock() 和 xUnlock() 方法。


    互斥量类型

    #define SQLITE_MUTEX_FAST             0
    #define SQLITE_MUTEX_RECURSIVE        1
    #define SQLITE_MUTEX_STATIC_MAIN      2
    #define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
    #define SQLITE_MUTEX_STATIC_MEM2      4  /* NOT USED */
    #define SQLITE_MUTEX_STATIC_OPEN      4  /* sqlite3BtreeOpen() */
    #define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_randomness() */
    #define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
    #define SQLITE_MUTEX_STATIC_LRU2      7  /* NOT USED */
    #define SQLITE_MUTEX_STATIC_PMEM      7  /* sqlite3PageMalloc() */
    #define SQLITE_MUTEX_STATIC_APP1      8  /* For use by application */
    #define SQLITE_MUTEX_STATIC_APP2      9  /* For use by application */
    #define SQLITE_MUTEX_STATIC_APP3     10  /* For use by application */
    #define SQLITE_MUTEX_STATIC_VFS1     11  /* For use by built-in VFS */
    #define SQLITE_MUTEX_STATIC_VFS2     12  /* For use by extension VFS */
    #define SQLITE_MUTEX_STATIC_VFS3     13  /* For use by application VFS */
    

    sqlite3_mutex_alloc()接口采用单个参数,该参数是这些整数常量之一

    一组静态互斥量可能会从一个 SQLite 版本到下一个版本发生变化。覆盖内置互斥锁逻辑的应用程序必须准备好容纳额外的静态互斥锁。


    文件打开操作的标志

    #define SQLITE_OPEN_READONLY         0x00000001  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_READWRITE        0x00000002  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_CREATE           0x00000004  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_DELETEONCLOSE    0x00000008  /* VFS only */
    #define SQLITE_OPEN_EXCLUSIVE        0x00000010  /* VFS only */
    #define SQLITE_OPEN_AUTOPROXY        0x00000020  /* VFS only */
    #define SQLITE_OPEN_URI              0x00000040  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_MEMORY           0x00000080  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_MAIN_DB          0x00000100  /* VFS only */
    #define SQLITE_OPEN_TEMP_DB          0x00000200  /* VFS only */
    #define SQLITE_OPEN_TRANSIENT_DB     0x00000400  /* VFS only */
    #define SQLITE_OPEN_MAIN_JOURNAL     0x00000800  /* VFS only */
    #define SQLITE_OPEN_TEMP_JOURNAL     0x00001000  /* VFS only */
    #define SQLITE_OPEN_SUBJOURNAL       0x00002000  /* VFS only */
    #define SQLITE_OPEN_SUPER_JOURNAL    0x00004000  /* VFS only */
    #define SQLITE_OPEN_NOMUTEX          0x00008000  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_FULLMUTEX        0x00010000  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_SHAREDCACHE      0x00020000  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
    #define SQLITE_OPEN_NOFOLLOW         0x01000000  /* Ok for sqlite3_open_v2() */
    #define SQLITE_OPEN_EXRESCODE        0x02000000  /* Extended result codes */
    

    这些位值用于sqlite3_open_v2()接口的第三个参数和sqlite3_vfs.xOpen方法的第四个参数。

    只有那些标记为“Ok for sqlite3_open_v2()”的标志可以用作sqlite3_open_v2()接口的第三个参数。其他标志历来被 sqlite3_open_v2() 忽略,尽管 SQLite 的未来版本可能会更改,以便在将任何不允许的位传递到 sqlite3_open_v2() 时引发错误。应用程序不应依赖于历史行为。

    请特别注意,将 SQLITE_OPEN_EXCLUSIVE 标志传递给 sqlite3_open_v2() *不会*导致使用 O_EXCL 打开基础数据库文件。将 SQLITE_OPEN_EXCLUSIVE 传递给 sqlite3_open_v2()在历史上一直是空操作,并且可能在未来版本的 SQLite 中成为错误。


    准备标志

    #define SQLITE_PREPARE_PERSISTENT              0x01
    #define SQLITE_PREPARE_NORMALIZE               0x02
    #define SQLITE_PREPARE_NO_VTAB                 0x04
    

    这些常量定义了各种标志,这些标志可以传递到sqlite3_prepare_v3()sqlite3_prepare16_v3()接口的“prepFlags”参数中。

    SQLite 的未来版本中可能会添加新的标志。

    SQLITE_PREPARE_PERSISTENT
    SQLITE_PREPARE_PERSISTENT 标志是对查询计划器的提示,即准备好的语句将保留很长时间并且可能会重复使用多次。如果没有这个标志,sqlite3_prepare_v3()sqlite3_prepare16_v3()假设准备好的语句将只使用一次或最多几次,然后使用 sqlite3_finalize()相对较快地销毁。当前的实现通过避免使用后备内存来响应此提示,以免耗尽后备内存的有限存储。SQLite 的未来版本可能会以不同方式处理此提示。

    SQLITE_PREPARE_NORMALIZE
    SQLITE_PREPARE_NORMALIZE 标志是空操作。任何想要使用 sqlite3_normalized_sql()接口的准备语句过去都需要这个标志。但是, sqlite3_normalized_sql()接口现在可用于所有准备好的语句,无论它们是否使用此标志。

    SQLITE_PREPARE_NO_VTAB
    如果语句使用任何虚拟表,SQLITE_PREPARE_NO_VTAB 标志会导致 SQL 编译器返回错误(错误代码 SQLITE_ERROR)。


    准备好的语句扫描状态操作码

    #define SQLITE_SCANSTAT_NLOOP    0
    #define SQLITE_SCANSTAT_NVISIT   1
    #define SQLITE_SCANSTAT_EST      2
    #define SQLITE_SCANSTAT_NAME     3
    #define SQLITE_SCANSTAT_EXPLAIN  4
    #define SQLITE_SCANSTAT_SELECTID 5
    

    以下常量可用于 sqlite3_stmt_scanstatus(S,X,T,V)接口的 T 参数。每个常量为 sqlite3_stmt_scanstatus() 指定一个不同的指标来返回。

    当返回给 V 的值是一个字符串时,保存该字符串的空间由准备好的语句 S 管理,并在 S 完成时自动释放。

    SQLITE_SCANSTAT_NLOOP
    V 参数指向的sqlite3_int64变量将被设置为第 X 次循环运行的总次数。

    SQLITE_SCANSTAT_NVISIT
    V 参数指向的sqlite3_int64变量将设置为第 X 次循环的所有迭代检查的总行数。

    SQLITE_SCANSTAT_EST
    V 参数指向的“double”变量将设置为查询规划器对第 X 次循环每次迭代输出的平均行数的估计。如果查询规划器的估计是准确的,那么这个值将近似于商 NVISIT/NLOOP 并且所有具有相同 SELECTID 的先前循环的这个值的乘积将是当前循环的 NLOOP 值。

    SQLITE_SCANSTAT_NAME
    V 参数指向的“const char *”变量将被设置为一个以零结尾的 UTF-8 字符串,其中包含用于第 X 次循环的索引或表的名称。

    SQLITE_SCANSTAT_EXPLAIN
    V 参数指向的“const char *”变量将被设置为一个以零结尾的 UTF-8 字符串,其中包含 第 X 个循环的EXPLAIN QUERY PLAN描述。

    SQLITE_SCANSTAT_SELECT
    V 参数指向的“int”变量将被设置为第 X 次循环的“select-id”。select-id 标识循环所属的查询或子查询。主查询的 select-id 为零。select-id 与EXPLAIN QUERY PLAN查询 的第一列中输出的值相同。


    xShmLock VFS 方法的标志

    #define SQLITE_SHM_UNLOCK       1
    #define SQLITE_SHM_LOCK         2
    #define SQLITE_SHM_SHARED       4
    #define SQLITE_SHM_EXCLUSIVE    8
    

    这些整数常量定义了sqlite3_io_methods 的 xShmLock 方法允许的各种锁定操作以下是 xShmLock 方法标志的唯一合法组合:

    • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
    • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE

    解锁时,必须提供与相应锁上相同的 SHARED 或 EXCLUSIVE 标志。

    xShmLock 方法可以在未锁定和 SHARED 之间或未锁定和 EXCLUSIVE 之间转换。它不能在 SHARED 和 EXCLUSIVE 之间转换。


    编译时库版本号

    #define SQLITE_VERSION        "3.39.2"
    #define SQLITE_VERSION_NUMBER 3039002
    #define SQLITE_SOURCE_ID      "2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603"
    

    sqlite3.h 标头中的SQLITE_VERSION C 预处理器宏计算为格式为“XYZ”的 SQLite 版本的字符串文字,其中 X 是主要版本号(SQLite3 始终为 3),Y 是次要版本号,Z 是版本号。SQLITE_VERSION_NUMBER C处理器宏解析为值为 (X*1000000 + Y*1000 + Z) 的整数,其中 X、Y 和 Z 与SQLITE_VERSION中使用的数字相同。SQLite 的任何给定版本的 SQLITE_VERSION_NUMBER 也将大于它的派生版本。要么 Y 保持不变而 Z 递增,要么 Y 递增而 Z 重置为零。

    3.6.18 版本(2009-09-11)开始,SQLite 源代码已存储在 Fossil 配置管理系统中SQLITE_SOURCE_ID 宏评估为一个字符串,该字符串标识其配置管理系统中的特定 SQLite 签入。SQLITE_SOURCE_ID 字符串包含签入 (UTC) 的日期和时间以及整个源树的 SHA1 或 SHA3-256 哈希。如果源代码自上次签入后以任何方式进行了编辑,则哈希的最后四位十六进制数字可能会被修改。

    另见:sqlite3_libversion()sqlite3_libversion_number()sqlite3_sourceid()sqlite_version()sqlite_source_id()


    定义特殊析构函数行为的常量

    typedef void (*sqlite3_destructor_type)(void*);
    #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
    #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)
    

    这些是析构函数的特殊值,作为最终参数传递给sqlite3_result_blob()等例程。如果析构函数参数是 SQLITE_STATIC,则意味着内容指针是常量,永远不会改变。它不需要被销毁。SQLITE_TRANSIENT 值意味着内容可能会在不久的将来发生变化,并且 SQLite 应该在返回之前制作自己的内容私有副本。

    typedef 是解决某些 C++ 编译器中的问题所必需的。


    状态参数

    #define SQLITE_STATUS_MEMORY_USED          0
    #define SQLITE_STATUS_PAGECACHE_USED       1
    #define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
    #define SQLITE_STATUS_SCRATCH_USED         3  /* NOT USED */
    #define SQLITE_STATUS_SCRATCH_OVERFLOW     4  /* NOT USED */
    #define SQLITE_STATUS_MALLOC_SIZE          5
    #define SQLITE_STATUS_PARSER_STACK         6
    #define SQLITE_STATUS_PAGECACHE_SIZE       7
    #define SQLITE_STATUS_SCRATCH_SIZE         8  /* NOT USED */
    #define SQLITE_STATUS_MALLOC_COUNT         9
    

    这些整数常量指定可以由sqlite3_status()返回的各种运行时状态参数。

    SQLITE_STATUS_MEMORY_USED
    此参数是使用sqlite3_malloc()直接或间接检查出的当前内存量。该图包括应用程序对sqlite3_malloc()的调用以及 SQLite 库对内部内存的使用情况。SQLITE_CONFIG_PAGECACHE控制的辅助页面缓存内存不包含在此参数中。返回的数量是sqlite3_mem_methods中的 xSize 方法报告的分配大小的总和

    SQLITE_STATUS_MALLOC_SIZE
    此参数记录传递给sqlite3_malloc()sqlite3_realloc()(或其内部等效项)的最大内存分配请求。只有在 *pHighwater 参数中返回给sqlite3_status()的值才有意义。写入 *pCurrent 参数的值未定义。

    SQLITE_STATUS_MALLOC_COUNT
    该参数记录了当前签出的单独内存分配的数量。

    SQLITE_STATUS_PAGECACHE_USED
    此参数返回 使用SQLITE_CONFIG_PAGECACHE配置 的页面缓存内存分配器中使用的页面数。返回的值以页为单位,而不是以字节为单位。

    SQLITE_STATUS_PAGECACHE_OVERFLOW
    此参数返回SQLITE_CONFIG_PAGECACHE缓冲区无法满足的页面缓存分配的字节数, 并且被迫溢出到sqlite3_malloc()返回的值包括因为它们太大而溢出的分配(它们大于 SQLITE_CONFIG_PAGECACHE的“sz”参数)和因为页面缓存中没有剩余空间而溢出的分配。

    SQLITE_STATUS_PAGECACHE_SIZE
    这个参数记录了交给pagecache内存分配器的最大内存分配请求。只有在 *pHighwater 参数中返回给sqlite3_status()的值才有意义。写入 *pCurrent 参数的值未定义。

    SQLITE_STATUS_SCRATCH_USED
    不再使用。

    SQLITE_STATUS_SCRATCH_OVERFLOW
    不再使用。

    SQLITE_STATUS_SCRATCH_SIZE
    不再使用。

    SQLITE_STATUS_PARSER_STACK
    *pHighwater 参数记录最深的解析器堆栈。*pCurrent 值未定义。*pHighwater 值仅在使用YYTRACKMAXSTACKDEPTH编译 SQLite 时才有意义

    可能会不时添加新的状态参数。


    同步类型标志

    #define SQLITE_SYNC_NORMAL        0x00002
    #define SQLITE_SYNC_FULL          0x00003
    #define SQLITE_SYNC_DATAONLY      0x00010
    

    当 SQLite 调用 sqlite3_io_methods对象的 xSync() 方法时,它使用这些整数值的组合作为第二个参数。

    当使用 SQLITE_SYNC_DATAONLY 标志时,意味着同步操作只需要将数据刷新到大容量存储。不需要刷新 inode 信息。如果标志的低四位等于 SQLITE_SYNC_NORMAL,则意味着使用正常的 fsync() 语义。如果低四位等于 SQLITE_SYNC_FULL,这意味着使用 Mac OS X 风格的 fullsync 而不是 fsync()。

    不要将 SQLITE_SYNC_NORMAL 和 SQLITE_SYNC_FULL 标志与PRAGMA synchronous =NORMAL 和PRAGMA synchronous =FULL 设置混淆。同步 pragma确定何时调用xSync VFS 方法并在所有平台上统一应用。SQLITE_SYNC_NORMAL 和 SQLITE_SYNC_FULL 标志确定同步操作的活力、严格程度或强度,并且仅在 Mac OSX 上对默认 SQLite 代码产生影响。(第三方 VFS 实现也可能区分 SQLITE_SYNC_NORMAL 和 SQLITE_SYNC_FULL,但在 SQLite 原生支持的操作系统中,只有 Mac OSX 关心差异。)


    测试接口操作代码

    #define SQLITE_TESTCTRL_FIRST                    5
    #define SQLITE_TESTCTRL_PRNG_SAVE                5
    #define SQLITE_TESTCTRL_PRNG_RESTORE             6
    #define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */
    #define SQLITE_TESTCTRL_BITVEC_TEST              8
    #define SQLITE_TESTCTRL_FAULT_INSTALL            9
    #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
    #define SQLITE_TESTCTRL_PENDING_BYTE            11
    #define SQLITE_TESTCTRL_ASSERT                  12
    #define SQLITE_TESTCTRL_ALWAYS                  13
    #define SQLITE_TESTCTRL_RESERVE                 14  /* NOT USED */
    #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
    #define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
    #define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
    #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
    #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
    #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
    #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
    #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
    #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
    #define SQLITE_TESTCTRL_BYTEORDER               22
    #define SQLITE_TESTCTRL_ISINIT                  23
    #define SQLITE_TESTCTRL_SORTER_MMAP             24
    #define SQLITE_TESTCTRL_IMPOSTER                25
    #define SQLITE_TESTCTRL_PARSER_COVERAGE         26
    #define SQLITE_TESTCTRL_RESULT_INTREAL          27
    #define SQLITE_TESTCTRL_PRNG_SEED               28
    #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS     29
    #define SQLITE_TESTCTRL_SEEK_COUNT              30
    #define SQLITE_TESTCTRL_TRACEFLAGS              31
    #define SQLITE_TESTCTRL_TUNE                    32
    #define SQLITE_TESTCTRL_LOGEST                  33
    #define SQLITE_TESTCTRL_LAST                    33  /* Largest TESTCTRL */
    

    这些常量是用作sqlite3_test_control()的第一个参数的有效操作代码参数。

    这些参数及其含义如有更改,恕不另行通知。这些值仅用于测试目的。应用程序不应使用任何这些参数或 sqlite3_test_control()接口。


    SQL 跟踪事件代码

    #define SQLITE_TRACE_STMT       0x01
    #define SQLITE_TRACE_PROFILE    0x02
    #define SQLITE_TRACE_ROW        0x04
    #define SQLITE_TRACE_CLOSE      0x08
    

    这些常量标识可以使用sqlite3_trace_v2()跟踪逻辑监视的事件类。sqlite3_trace_v2(D,M,X,P)的 M 参数是以下一个或多个常量的或运算组合。跟踪回调的第一个参数是以下常量之一。

    未来的版本中可能会添加新的跟踪常量。

    跟踪回调有四个参数:xCallback(T,C,P,X)。T 参数是上面的整数类型代码之一。C 参数是作为第四个参数传递给sqlite3_trace_v2()的上下文指针的副本。P 和 X 参数是指针,其含义取决于 T。

    SQLITE_TRACE_STMT
    SQLITE_TRACE_STMT 回调在准备语句首次开始运行时调用,也可能在准备语句执行期间的其他时间调用,例如在每个触发器子程序的开始处。P 参数是指向 准备好的语句的指针。X 参数是一个指向字符串的指针,该字符串是准备好的语句的未扩展 SQL 文本或指示触发器调用的 SQL 注释。 当 X 以“--”开头时,回调可以通过使用 X 参数 计算由旧版sqlite3_trace()接口返回的相同文本,否则调用sqlite3_expanded_sql(P) 。

    SQLITE_TRACE_PROFILE
    SQLITE_TRACE_PROFILE 回调提供的信息与sqlite3_profile()回调提供的信息大致相同P 参数是指向准备好的语句的指针,X 参数指向一个 64 位整数,它是准备好的语句运行所花费的纳秒数的估计值。SQLITE_TRACE_PROFILE 回调在语句完成时被调用。

    SQLITE_TRACE_ROW
    每当准备好的语句生成单行结果时,都会调用 SQLITE_TRACE_ROW 回调。P 参数是指向准备好的语句的指针,X 参数未使用。

    SQLITE_TRACE_CLOSE
    数据库连接关闭时调用 SQLITE_TRACE_CLOSE 回调。P 参数是指向数据库连接对象的指针,X 参数未使用。


    允许从 [sqlite3_txn_state()] 返回值

    #define SQLITE_TXN_NONE  0
    #define SQLITE_TXN_READ  1
    #define SQLITE_TXN_WRITE 2
    

    这些常量定义数据库文件的当前事务状态。sqlite3_txn_state(D,S)接口返回这些常量之一,以描述数据库连接D中模式 S 的事务状态。

    SQLITE_TXN_NONE
    SQLITE_TXN_NONE 状态意味着当前没有事务待处理。

    SQLITE_TXN_READ
    SQLITE_TXN_READ 状态表示数据库当前处于读取事务中。已从数据库文件中读取内容,但数据库文件中的任何内容均未更改。如果发生任何更改并且没有其他冲突的并发写入事务,事务状态将前进到 SQLITE_TXN_WRITE。事务状态将在ROLLBACKCOMMIT之后恢复为 SQLITE_TXN_NONE

    SQLITE_TXN_WRITE
    SQLITE_TXN_WRITE 状态表示数据库当前处于写入事务中。内容已写入数据库文件但尚未提交。在下一次ROLLBACKCOMMIT时,事务状态将更改为 SQLITE_TXN_NONE


    虚拟表配置选项

    #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
    #define SQLITE_VTAB_INNOCUOUS          2
    #define SQLITE_VTAB_DIRECTONLY         3
    

    这些宏定义了 sqlite3_vtab_config()接口的各种选项,虚拟表实现可以使用这些选项来自定义和优化它们的行为。

    SQLITE_VTAB_CONSTRAINT_SUPPORT
    支持sqlite3_vtab_config (db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X)形式的调用 ,其中 X 是一个整数。如果 X 为零,则xCreatexConnect方法调用sqlite3_vtab_config()的虚拟表不支持约束。在此配置(默认配置)中,如果对xUpdate方法的调用返回SQLITE_CONSTRAINT,则整个语句将回滚,就好像OR ABORT已被指定为用户 SQL 语句的一部分,而不管指定的实际 ON CONFLICT 模式如何。

    如果 X 非零,则虚拟表实现保证如果xUpdate返回SQLITE_CONSTRAINT,它将在对内部或持久数据结构进行任何修改之前返回。如果ON CONFLICT模式为 ABORT、FAIL、IGNORE 或 ROLLBACK,则 SQLite 能够回滚语句或数据库事务,并根据需要放弃或继续处理当前 SQL 语句。如果 ON CONFLICT 模式是 REPLACE 并且xUpdate方法返回 SQLITE_CONSTRAINT,SQLite 处理这个就像 ON CONFLICT 模式已经被 ABORT 一样。

    处理 OR REPLACE 所需的虚拟表实现必须在xUpdate方法中执行。如果对 sqlite3_vtab_on_conflict()函数的调用表明当前的 ON CONFLICT 策略是 REPLACE,则虚拟表实现应在 xUpdate 回调中静默替换适当的行并返回 SQLITE_OK。或者,如果这不可能,它可能会返回 SQLITE_CONSTRAINT,在这种情况下,SQLite 会回退到 OR ABORT 约束处理。

    SQLITE_VTAB_DIRECTONLY
    从虚拟表实现的xConnectxCreate方法中调用 sqlite3_vtab_config (db,SQLITE_VTAB_DIRECTONLY)形式禁止从触发器和视图中使用该虚拟表。

    SQLITE_VTAB_INNOCUOUS
    从虚拟表实现的xConnectxCreate方法中以sqlite3_vtab_config (db,SQLITE_VTAB_INNOCUOUS)形式调用表明 该虚拟表可以在触发器和视图中安全使用。从概念上讲,SQLITE_VTAB_INNOCUOUS 标记意味着虚拟表即使被恶意黑客控制也不会造成严重危害。除非绝对必要,否则开发人员应避免设置 SQLITE_VTAB_INNOCUOUS 标志。


    Win32 目录类型

    #define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
    #define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
    

    这些宏仅在 Windows 上可用。它们为sqlite3_win32_set_directory接口 的类型参数定义了允许的值。


    运行时限制类别

    #define SQLITE_LIMIT_LENGTH                    0
    #define SQLITE_LIMIT_SQL_LENGTH                1
    #define SQLITE_LIMIT_COLUMN                    2
    #define SQLITE_LIMIT_EXPR_DEPTH                3
    #define SQLITE_LIMIT_COMPOUND_SELECT           4
    #define SQLITE_LIMIT_VDBE_OP                   5
    #define SQLITE_LIMIT_FUNCTION_ARG              6
    #define SQLITE_LIMIT_ATTACHED                  7
    #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
    #define SQLITE_LIMIT_VARIABLE_NUMBER           9
    #define SQLITE_LIMIT_TRIGGER_DEPTH            10
    #define SQLITE_LIMIT_WORKER_THREADS           11
    

    这些常量定义了可以在运行时使用sqlite3_limit()降低的各种性能限制。各种限制的含义概要如下所示。SQLite中的限制提供了更多信息

    SQLITE_LIMIT_LENGTH
    任何字符串或 BLOB 或表行的最大大小,以字节为单位。

    SQLITE_LIMIT_SQL_LENGTH
    SQL 语句的最大长度,以字节为单位。

    SQLITE_LIMIT_COLUMN
    表定义或SELECT结果集中的最大列数,或索引或 ORDER BY 或 GROUP BY 子句中的最大列数。

    SQLITE_LIMIT_EXPR_DEPTH
    任何表达式的分析树的最大深度。

    SQLITE_LIMIT_COMPOUND_SELECT
    复合 SELECT 语句中的最大术语数。

    SQLITE_LIMIT_VDBE_OP
    虚拟机程序中用于执行一条SQL 语句的最大指令数。如果sqlite3_prepare_v2()或等价物试图在单个准备好的语句中为超过这么多操作码分配空间,则返回 SQLITE_NOMEM 错误。

    SQLITE_LIMIT_FUNCTION_ARG
    函数参数的最大数量。

    SQLITE_LIMIT_ATTACHED
    附加数据库的最大数量

    SQLITE_LIMIT_LIKE_PATTERN_LENGTH
    LIKEGLOB运算符的模式参数的最大长度

    SQLITE_LIMIT_VARIABLE_NUMBER
    SQL 语句中任意参数的最大索引号。

    SQLITE_LIMIT_TRIGGER_DEPTH
    触发器的最大递归深度。

    SQLITE_LIMIT_WORKER_THREADS
    单个 准备好的语句可以启动的最大辅助工作线程数。


    数据库连接的状态参数

    #define SQLITE_DBSTATUS_LOOKASIDE_USED       0
    #define SQLITE_DBSTATUS_CACHE_USED           1
    #define SQLITE_DBSTATUS_SCHEMA_USED          2
    #define SQLITE_DBSTATUS_STMT_USED            3
    #define SQLITE_DBSTATUS_LOOKASIDE_HIT        4
    #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE  5
    #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL  6
    #define SQLITE_DBSTATUS_CACHE_HIT            7
    #define SQLITE_DBSTATUS_CACHE_MISS           8
    #define SQLITE_DBSTATUS_CACHE_WRITE          9
    #define SQLITE_DBSTATUS_DEFERRED_FKS        10
    #define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
    #define SQLITE_DBSTATUS_CACHE_SPILL         12
    #define SQLITE_DBSTATUS_MAX                 12   /* Largest defined DBSTATUS */
    

    这些常量是可用的整数“动词”,可以作为第二个参数传递给sqlite3_db_status()接口。

    在 SQLite 的未来版本中可能会添加新的动词。现有的动词可能会被终止。应用程序应检查 sqlite3_db_status()的返回码以确保调用有效。如果调用已停用或不受支持的动词,则sqlite3_db_status()接口将返回非零错误代码。

    SQLITE_DBSTATUS_LOOKASIDE_USED
    此参数返回当前检出的后备内存插槽数。

    SQLITE_DBSTATUS_LOOKASIDE_HIT
    此参数返回使用后备内存满足的 malloc 尝试次数。只有高水值才有意义;当前值始终为零。

    SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
    此参数返回可能已使用后备内存满足但由于请求的内存量大于后备插槽大小而失败的 malloc 尝试次数。只有高水值才有意义;当前值始终为零。

    SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
    此参数返回可能已使用后备内存满足但由于所有后备内存已在使用而失败的 malloc 尝试次数。只有高水值才有意义;当前值始终为零。

    SQLITE_DBSTATUS_CACHE_USED
    此参数返回与数据库连接关联的所有分页缓存使用的堆内存的近似字节数。与 SQLITE_DBSTATUS_CACHE_USED 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_CACHE_USED_SHARED
    此参数类似于 DBSTATUS_CACHE_USED,不同之处在于,如果在两个或多个连接之间共享分页缓存,则该分页缓存使用的堆内存字节在附加连接之间平均分配。换句话说,如果没有共享与数据库连接关联的寻呼机缓存,则此请求返回与 DBSTATUS_CACHE_USED 相同的值。或者,如果共享一个或多个分页缓存,则此调用返回的值将小于 DBSTATUS_CACHE_USED 返回的值。与 SQLITE_DBSTATUS_CACHE_USED_SHARED 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_SCHEMA_USED
    此参数返回用于存储与连接关联的所有数据库(主数据库、临时数据库和任何ATTACH数据库)的模式的堆内存的近似字节数。报告模式使用的全部内存量,即使模式内存由于 启用共享缓存模式而与其他数据库连接共享。与 SQLITE_DBSTATUS_SCHEMA_USED 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_STMT_USED
    此参数返回与数据库连接关联的所有准备好的语句使用的堆和后备内存的近似字节数。与 SQLITE_DBSTATUS_STMT_USED 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_CACHE_HIT
    此参数返回已发生的寻呼机缓存命中数。与 SQLITE_DBSTATUS_CACHE_HIT 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_CACHE_MISS
    此参数返回已发生的寻呼机高速缓存未命中数。与 SQLITE_DBSTATUS_CACHE_MISS 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_CACHE_WRITE
    此参数返回已写入磁盘的脏缓存条目数。具体来说,wal模式数据库写入wal文件的页数,或者rollback模式数据库写入数据库文件的页数。不包括作为事务回滚或数据库恢复操作的一部分写入的任何页面。如果在将页面写入磁盘时发生 IO 或其他错误,则对后续 SQLITE_DBSTATUS_CACHE_WRITE 请求的影响是不确定的。与 SQLITE_DBSTATUS_CACHE_WRITE 关联的高水位标记始终为 0。

    SQLITE_DBSTATUS_CACHE_SPILL
    该参数返回由于页面缓存溢出而在事务中间写入磁盘的脏缓存条目数。如果一次将事务全部写入磁盘,则事务效率更高。当页面在事务处理过程中溢出时,会引入额外的开销。此参数可用于帮助识别可以通过增加高速缓存大小来解决的低效问题。

    SQLITE_DBSTATUS_DEFERRED_FKS
    当且仅当所有外键约束(延迟的或立即的)都已解决时,此参数为当前值返回零。高水位标记始终为 0。


    准备好的语句的状态参数

    #define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
    #define SQLITE_STMTSTATUS_SORT              2
    #define SQLITE_STMTSTATUS_AUTOINDEX         3
    #define SQLITE_STMTSTATUS_VM_STEP           4
    #define SQLITE_STMTSTATUS_REPREPARE         5
    #define SQLITE_STMTSTATUS_RUN               6
    #define SQLITE_STMTSTATUS_FILTER_MISS       7
    #define SQLITE_STMTSTATUS_FILTER_HIT        8
    #define SQLITE_STMTSTATUS_MEMUSED           99
    

    这些预处理器宏定义整数代码,这些代码命名与sqlite3_stmt_status()接口 关联的计数器值。各个计数器的含义如下:

    SQLITE_STMTSTATUS_FULLSCAN_STEP
    这是 SQLite 作为全表扫描的一部分在表中前进的次数。此计数器的大数字可能表示通过谨慎使用索引来提高性能的机会。

    SQLITE_STMTSTATUS_SORT
    这是已发生的排序操作数。此计数器中的非零值可能表示有机会通过谨慎使用索引来提高性能。

    SQLITE_STMTSTATUS_AUTOINDEX
    这是插入到临时索引中的行数,临时索引是为了帮助连接运行得更快而自动创建的。此计数器中的非零值可能表示有机会通过添加不需要在每次运行语句时重新初始化的永久索引来提高性能。

    SQLITE_STMTSTATUS_VM_STEP
    如果该数字小于或等于 2147483647,则这是准备语句执行的虚拟机操作数。虚拟机操作数可以用作准备语句完成的总工作量的代理。如果虚拟机操作数超过 2147483647 则此语句状态代码返回的值未定义。

    SQLITE_STMTSTATUS_REPREPARE
    这是由于架构更改或 绑定参数更改可能影响查询计划而自动重新生成准备语句的次数。

    SQLITE_STMTSTATUS_RUN
    这是准备好的语句已运行的次数。出于此计数器的目的,一次“运行”是对 sqlite3_step() 的一次或多次调用,然后是对sqlite3_reset()的调用。计数器在每个周期的第一个sqlite3_step()调用时递增。

    SQLITE_STMTSTATUS_FILTER_HIT
    SQLITE_STMTSTATUS_FILTER_MISS
    SQLITE_STMTSTATUS_FILTER_HIT 是由于布隆过滤器返回未找到而绕过连接步骤的次数。相应的 SQLITE_STMTSTATUS_FILTER_MISS 值是布隆过滤器返回查找的次数,因此连接步骤必须正常处理。

    SQLITE_STMTSTATUS_MEMUSED
    这是用于存储准备好的语句的堆内存的近似字节数。该值实际上不是计数器,因此当操作码为 SQLITE_STMTSTATUS_MEMUSED 时,sqlite3_stmt_status() 的 resetFlg 参数将被忽略。


    数据库快照

    typedef struct sqlite3_snapshot {
      unsigned char hidden[48];
    } sqlite3_snapshot;
    

    快照对象的一个​​实例记录了 历史上某个特定点的WAL 模式数据库的状态。

    WAL 模式下,在同一个数据库文件上打开的多个数据库连接可以各自读取数据库文件的不同历史版本。数据库连接开始读取事务时,该连接会看到数据库的未更改副本,因为它在事务首次启动的时间点存在。在启动新的读取事务之前,读取器看不到其他连接对数据库的后续更改。

    sqlite3_snapshot 对象记录有关数据库文件历史版本的状态信息,以便以后可以打开一个新的读取事务,该事务可以看到数据库的历史版本而不是最新版本。

    1 构造函数:sqlite3_snapshot_get()

    1 析构函数:sqlite3_snapshot_free()

    3 个方法: sqlite3_snapshot_cmp()sqlite3_snapshot_open()sqlite3_snapshot_recover()


    64 位整数类型

    #ifdef SQLITE_INT64_TYPE
      typedef SQLITE_INT64_TYPE sqlite_int64;
    # ifdef SQLITE_UINT64_TYPE
        typedef SQLITE_UINT64_TYPE sqlite_uint64;
    # else
        typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
    # endif
    #elif defined(_MSC_VER) || defined(__BORLANDC__)
      typedef __int64 sqlite_int64;
      typedef unsigned __int64 sqlite_uint64;
    #else
      typedef long long int sqlite_int64;
      typedef unsigned long long int sqlite_uint64;
    #endif
    typedef sqlite_int64 sqlite3_int64;
    typedef sqlite_uint64 sqlite3_uint64;
    

    因为没有指定 64 位整数类型的跨平台方式,SQLite 包含 64 位有符号和无符号整数的类型定义。

    sqlite3_int64 和 sqlite3_uint64 是首选的类型定义。支持 sqlite_int64 和 sqlite_uint64 类型只是为了向后兼容。

    sqlite3_int64 和 sqlite_int64 类型可以存储介于 -9223372036854775808 和 +9223372036854775807 之间的整数值。sqlite3_uint64 和 sqlite_uint64 类型可以存储 0 到 +18446744073709551615 之间的整数值。


    虚拟表对象

    struct sqlite3_module {
      int iVersion;
      int (*xCreate)(sqlite3*, void *pAux,
                   int argc, const char *const*argv,
                   sqlite3_vtab **ppVTab, char**);
      int (*xConnect)(sqlite3*, void *pAux,
                   int argc, const char *const*argv,
                   sqlite3_vtab **ppVTab, char**);
      int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
      int (*xDisconnect)(sqlite3_vtab *pVTab);
      int (*xDestroy)(sqlite3_vtab *pVTab);
      int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
      int (*xClose)(sqlite3_vtab_cursor*);
      int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
                    int argc, sqlite3_value **argv);
      int (*xNext)(sqlite3_vtab_cursor*);
      int (*xEof)(sqlite3_vtab_cursor*);
      int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
      int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
      int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
      int (*xBegin)(sqlite3_vtab *pVTab);
      int (*xSync)(sqlite3_vtab *pVTab);
      int (*xCommit)(sqlite3_vtab *pVTab);
      int (*xRollback)(sqlite3_vtab *pVTab);
      int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
                           void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
                           void **ppArg);
      int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
      /* The methods above are in version 1 of the sqlite_module object. Those
      ** below are for version 2 and greater. */
      int (*xSavepoint)(sqlite3_vtab *pVTab, int);
      int (*xRelease)(sqlite3_vtab *pVTab, int);
      int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
      /* The methods above are in versions 1 and 2 of the sqlite_module object.
      ** Those below are for version 3 and greater. */
      int (*xShadowName)(const char*);
    };
    

    这种结构,有时称为“虚拟表模块”,定义了虚拟表的实现。该结构主要由模块的方法组成。

    通过填充此结构的持久实例并将指向该实例的指针传递给sqlite3_create_module()sqlite3_create_module_v2()来创建虚拟表模块。注册保持有效,直到它被不同的模块替换或直到数据库连接关闭。在向任何数据库连接注册时,此结构的内容不得更改。


    虚拟表游标对象

    struct sqlite3_vtab_cursor {
      sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
      /* Virtual table implementations will typically add additional fields */
    };
    

    每个虚拟表模块实现都使用以下结构的子类来描述指向 虚拟表并用于循环遍历虚拟表的游标。游标是使用模块的 xOpen方法创建的,并由xClose方法销毁游标由模块的xFilterxNextxEofxColumnxRowid方法使用。每个模块实现都将定义游标结构的内容以满足自己的需要。

    这个超类的存在是为了定义对所有实现都通用的游标字段。


    一个打开的 BLOB 的句柄

    typedef struct sqlite3_blob sqlite3_blob;
    

    该对象的一个​​实例表示一个打开的 BLOB,可以在其 上执行增量 BLOB I/O这种类型的对象由 sqlite3_blob_open() 创建并由sqlite3_blob_close( ) 销毁sqlite3_blob_read()sqlite3_blob_write()接口可用于读取或写入 BLOB 的小部分sqlite3_blob_bytes()接口以字节为单位返回 BLOB的大小。

    1 构造函数:sqlite3_blob_open()

    1 析构函数:sqlite3_blob_close()

    4 种方法: sqlite3_blob_bytes()sqlite3_blob_read()sqlite3_blob_reopen()sqlite3_blob_write()


    数据库连接句柄

    typedef struct sqlite3 sqlite3;
    

    每个打开的 SQLite 数据库都由一个指向名为“sqlite3”的不透明结构实例的指针表示。将 sqlite3 指针视为对象很有用。sqlite3_open()sqlite3_open16 ()sqlite3_open_v2()接口是它的构造函数,sqlite3_close()sqlite3_close_v2()是它的析构函数。还有许多其他接口(例如 sqlite3_prepare_v2()sqlite3_create_function()sqlite3_busy_timeout()仅举三例)是 sqlite3 对象上的方法。

    3个构造函数: sqlite3_open()sqlite3_open16()sqlite3_open_v2()

    2 个析构函数: sqlite3_close()sqlite3_close_v2()

    76种方法:


    动态字符串对象

    typedef struct sqlite3_str sqlite3_str;
    

    sqlite3_str 对象的实例包含正在构造的动态大小的字符串。

    sqlite3_str 对象的生命周期如下:

    1. sqlite3_str 对象是使用sqlite3_str_new()创建的。
    2. 使用各种方法(例如sqlite3_str_appendf() )将文本附加到 sqlite3_str 对象。
    3. sqlite3_str 对象被销毁,它创建的字符串使用sqlite3_str_finish()接口返回。

    1 构造函数:sqlite3_str_new()

    1 析构函数:sqlite3_str_finish()

    9种方法:


    应用程序定义的页面缓存。

    typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
    struct sqlite3_pcache_methods2 {
      int iVersion;
      void *pArg;
      int (*xInit)(void*);
      void (*xShutdown)(void*);
      sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
      void (*xCachesize)(sqlite3_pcache*, int nCachesize);
      int (*xPagecount)(sqlite3_pcache*);
      sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
      void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
      void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
          unsigned oldKey, unsigned newKey);
      void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
      void (*xDestroy)(sqlite3_pcache*);
      void (*xShrink)(sqlite3_pcache*);
    };
    

    sqlite3_config ( SQLITE_CONFIG_PCACHE2 , ...) 接口可以 通过传入 sqlite3_pcache_methods2 结构的实例来注册替代页面缓存实现。在许多应用程序中,SQLite 分配的大部分堆内存都用于页面缓存。通过使用此 API 实现自定义页面缓存,应用程序可以更好地控制 SQLite 消耗的内存量、分配和释放内存的方式,以及用于确定数据库文件的哪些部分被缓存和缓存的策略。多长时间。

    替代页面缓存机制是一种极端措施,只有最苛刻的应用程序才需要。对于大多数用途,建议使用内置页面缓存。

    sqlite3_pcache_methods2 结构的内容在对sqlite3_config的调用中被 SQLite 复制到内部缓冲区因此,应用程序可能会在调用sqlite3_config()返回后丢弃该参数 。

    每次有效调用sqlite3_initialize()都会 调用一次 xInit() 方法 (通常在进程的生命周期内只调用一次)。xInit() 方法传递了 sqlite3_pcache_methods2.pArg 值的副本。xInit() 方法的目的是设置自定义页面缓存实现所需的全局数据结构。如果 xInit() 方法为 NULL,则使用内置的默认页面缓存而不是应用程序定义的页面缓存。

    xShutdown() 方法由sqlite3_shutdown()调用。如果需要,它可用于在进程关闭之前清理任何未完成的资源。xShutdown() 方法可能为 NULL。

    SQLite 自动序列化对 xInit 方法的调用,因此 xInit 方法不需要是线程安全的。xShutdown 方法仅从sqlite3_shutdown()调用,因此它也不需要是线程安全的。在多线程应用程序中,所有其他方法都必须是线程安全的。

    如果没有对 xShutdown() 的干预调用,SQLite 将永远不会多次调用 xInit()。

    SQLite 调用 xCreate() 方法来构造一个新的缓存实例。SQLite 通常会为每个打开的数据库文件创建一个缓存实例,但不能保证这一点。第一个参数 szPage 是缓存必须分配的页面大小(以字节为单位)。szPage 永远是二的幂。第二个参数 szExtra 是与每个页面缓存条目关联的额外存储字节数。szExtra 参数将小于 250。SQLite 将在每个页面上使用额外的 szExtra 字节来存储磁盘上有关底层数据库页面的元数据。传递给 szExtra 的值取决于 SQLite 版本、目标平台以及 SQLite 的编译方式。如果正在创建的缓存将用于缓存存储在磁盘上的文件的数据库页面,则 xCreate() 的第三个参数 bPurgeable 为真,如果用于内存数据库,则为 false。缓存实现不必根据 bPurgeable 的值做任何特殊的事情;它纯粹是建议性的。在 bPurgeable 为 false 的缓存中,SQLite 将永远不会调用 xUnpin() 除非故意删除页面。换句话说,在 bPurgeable 设置为 false 的缓存上调用 xUnpin() 将始终将“discard”标志设置为 true。因此,使用 bPurgeable false 创建的缓存永远不会包含任何未固定的页面。在 bPurgeable 设置为 false 的缓存上调用 xUnpin() 将始终将“discard”标志设置为 true。因此,使用 bPurgeable false 创建的缓存永远不会包含任何未固定的页面。在 bPurgeable 设置为 false 的缓存上调用 xUnpin() 将始终将“discard”标志设置为 true。因此,使用 bPurgeable false 创建的缓存永远不会包含任何未固定的页面。

    SQLite 可以随时调用 xCachesize() 方法来设置作为第一个参数传递的缓存实例的建议最大缓存大小(存储的页面数)。这是使用 SQLite“ PRAGMA cache_size ”命令配置的值。与 bPurgeable 参数一样,实现不需要对该值做任何事情;它仅供参考。

    xPagecount() 方法必须返回当前存储在缓存中的页面数,包括固定和未固定的。

    xFetch() 方法在缓存中定位一个页面并返回一个指向与该页面关联的 sqlite3_pcache_page 对象的指针,或一个 NULL 指针。返回的 sqlite3_pcache_page 对象的 pBuf 元素将是指向用于存储单个数据库页面内容的 szPage 字节缓冲区的指针。sqlite3_pcache_page 的 pExtra 元素将是一个指针,指向 SQLite 为页面缓存中的每个条目请求的额外存储的 szExtra 字节。

    要获取的页面由键确定。最小键值为 1。使用 xFetch 检索后,页面被视为“已固定”。

    如果请求的页面已经在页面缓存中,那么页面缓存实现必须返回一个指向页面缓冲区的指针,其内容完好无损。如果请求的页面不在缓存中,那么缓存实现应该使用 createFlag 参数的值来帮助它确定要采取的操作:

    createFlag Behavior when page is not already in cache
    0 Do not allocate a new page. Return NULL.
    1 Allocate a new page if it easy and convenient to do so. Otherwise return NULL.
    2 Make every effort to allocate a new page. Only return NULL if allocating a new page is effectively impossible.

    SQLite 通常会调用带有 0 或 1 的 createFlag 的 xFetch()。SQLite 只会在先前使用 1 的 createFlag 调用失败后使用 2 的 createFlag。在 xFetch() 调用之间,SQLite 可能会尝试通过将固定页面的内容溢出到磁盘并同步操作系统磁盘缓存来取消固定一个或多个缓存页面。

    xUnpin() 由 SQLite 调用,将指向当前固定页面的指针作为其第二个参数。如果第三个参数 discard 不为零,则页面必须从缓存中逐出。如果丢弃参数为零,则页面可以根据页面缓存实现的判断被丢弃或保留。页面缓存实现可以随时选择驱逐未固定的页面。

    缓存不得执行任何引用计数。无论之前调用 xFetch() 的次数如何,对 xUnpin() 的一次调用都会取消固定页面。

    xRekey() 方法用于更改与作为第二个参数传递的页面关联的键值。如果缓存以前包含与 newKey 关联的条目,则必须将其丢弃。保证不会固定与 newKey 关联的任何先前缓存条目。

    当 SQLite 调用 xTruncate() 方法时,缓存必须丢弃所有页码(键)大于或等于传递给 xTruncate() 的 iLimit 参数值的现有缓存条目。如果这些页面中的任何一个被固定,它们将被隐式取消固定,这意味着它们可以被安全地丢弃。

    xDestroy() 方法用于删除由 xCreate() 分配的缓存。应释放与指定缓存关联的所有资源。调用 xDestroy() 方法后,SQLite 认为sqlite3_pcache* 句柄无效,不会将其与任何其他 sqlite3_pcache_methods2 函数一起使用。

    当 SQLite 希望页面缓存释放尽可能多的堆内存时,它会调用 xShrink() 方法。页面缓存实现没有义务释放任何内存,但行为良好的实现应该尽力而为。


    准备好的语句对象

    typedef struct sqlite3_stmt sqlite3_stmt;
    

    此对象的一个​​实例表示已编译成二进制形式并准备好进行评估的单个 SQL 语句。

    将每个 SQL 语句视为一个单独的计算机程序。原始 SQL 文本是源代码。准备好的语句对象是编译后的目标代码。所有的SQL都必须先转换成prepared statement才能运行。

    准备好的语句对象的生命周期通常是这样的:

    1. 使用sqlite3_prepare_v2()创建准备好的语句对象
    2. 使用 sqlite3_bind_*() 接口将 值绑定到参数。
    3. 通过调用sqlite3_step()一次或多次来运行 SQL。
    4. 使用sqlite3_reset()重置准备好的语句,然后返回到步骤 2。执行此操作零次或多次。
    5. 使用sqlite3_finalize()销毁对象

    6 建设者:

    1 析构函数:sqlite3_finalize()

    51种方法:


    动态类型值对象

    typedef struct sqlite3_value sqlite3_value;
    

    SQLite 使用 sqlite3_value 对象来表示可以存储在数据库表中的所有值。SQLite 对其存储的值使用动态类型。存储在 sqlite3_value 对象中的值可以是整数、浮点值、字符串、BLOB 或 NULL。

    sqlite3_value 对象可以是“受保护的”或“不受保护的”。某些接口需要受保护的 sqlite3_value。其他接口将接受受保护或未受保护的 sqlite3_value。每个接受 sqlite3_value 参数的接口都指定它是否需要受保护的 sqlite3_value。sqlite3_value_dup()接口可用于从未受保护的 sqlite3_value 构造新的受保护 sqlite3_value

    术语“受保护”和“不受保护”是指是否持有互斥体。为受保护的 sqlite3_value 对象保留内部互斥锁,但没有为未受保护的 sqlite3_value 对象保留互斥锁。如果 SQLite 被编译为单线程(SQLITE_THREADSAFE=0并且sqlite3_threadsafe()返回 0)或者如果 SQLite 以简化互斥模式 SQLITE_CONFIG_SINGLETHREADSQLITE_CONFIG_MULTITHREAD之一运行, 则受保护和未受保护的 sqlite3_value 对象之间没有区别,它们可以可以互换使用。但是,为了最大限度地提高代码可移植性,建议应用程序仍然区分受保护和未受保护的 sqlite3_value 对象,即使不是严格要求也是如此。

    作为参数传递到应用程序定义的 SQL 函数的实现中的 sqlite3_value 对象受到保护。sqlite3_vtab_rhs_value()返回的 sqlite3_value 对象 受到保护。sqlite3_column_value()返回的 sqlite3_value 对象 不受保护。未受保护的 sqlite3_value 对象只能用作sqlite3_result_value()sqlite3_bind_value()sqlite3_value_dup()的参数。sqlite3_value_type()系列接口需要受保护的 sqlite3_value 对象

    18种方法:


    弃用的功能

    #ifndef SQLITE_OMIT_DEPRECATED
    int sqlite3_aggregate_count(sqlite3_context*);
    int sqlite3_expired(sqlite3_stmt*);
    int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
    int sqlite3_global_recover(void);
    void sqlite3_thread_cleanup(void);
    int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
                          void*,sqlite3_int64);
    #endif
    

    这些功能已弃用为了保持与旧代码的向后兼容性,将继续支持这些功能。但是,新的应用程序应该避免使用这些功能。为了鼓励程序员避免使用这些功能,我们不会解释它们的作用。


    在线备份 API。

    sqlite3_backup *sqlite3_backup_init(
      sqlite3 *pDest,                        /* Destination database handle */
      const char *zDestName,                 /* Destination database name */
      sqlite3 *pSource,                      /* Source database handle */
      const char *zSourceName                /* Source database name */
    );
    int sqlite3_backup_step(sqlite3_backup *p, int nPage);
    int sqlite3_backup_finish(sqlite3_backup *p);
    int sqlite3_backup_remaining(sqlite3_backup *p);
    int sqlite3_backup_pagecount(sqlite3_backup *p);
    

    备份 API 将一个数据库的内容复制到另一个数据库。它对于创建数据库备份或将内存数据库复制到持久文件或从持久文件中复制很有用。

    另请参阅:使用 SQLite 在线备份 API

    在备份操作期间,SQLite 在目标数据库文件上持有一个打开的写事务。源数据库仅在读取时才被读取锁定;它不会在整个备份操作中持续锁定。因此,可以在实时源数据库上执行备份,而不会在备份进行时阻止其他数据库连接读取或写入源数据库。

    要执行备份操作:

    1. sqlite3_backup_init()被调用一次来初始化备份,
    2. sqlite3_backup_step()被调用一次或多次以在两个数据库之间传输数据,最后
    3. 调用sqlite3_backup_finish()以释放与备份操作相关的所有资源。
    每次成功调用 sqlite3_backup_init() 时,应该只调用一次 sqlite3_backup_finish()。

    sqlite3_backup_init()

    sqlite3_backup_init(D,N,S,M) 的 D 和 N 参数分别是与目标数据库关联的 数据库连接和数据库名称。主数据库的数据库名称是“main”,临时数据库的数据库名称是“temp”,或者附加数据库的ATTACH语句中 AS 关键字后指定的名称。传递给 sqlite3_backup_init(D,N,S,M) 的 S 和 M 参数分别标识源数据库的数据库连接 和数据库名称。源和目标数据库连接(参数 S 和 D)必须不同,否则 sqlite3_backup_init(D,N,S,M) 将失败并出现错误。

    如果目标数据库上已经打开了读或读写事务,则调用 sqlite3_backup_init() 将失败,返回 NULL。

    如果sqlite3_backup_init(D,N,S,M)发生错误,则返回NULL,并在目标数据库连接D中保存错误码和错误信息。调用sqlite3_backup_init()失败的错误码和信息可以使用sqlite3_errcode()sqlite3_errmsg()和/或 sqlite3_errmsg16()函数检索。成功调用 sqlite3_backup_init() 会返回一个指向 sqlite3_backup对象的指针。sqlite3_backup对象可以与 sqlite3_backup_step() 和 sqlite3_backup_finish() 函数一起使用来执行指定的备份操作

    sqlite3_backup_step()

    函数 sqlite3_backup_step(B,N) 将在sqlite3_backup对象 B指定的源数据库和目标数据库之间复制最多 N 个页面。如果 N 为负数,则复制所有剩余的源页面。如果 sqlite3_backup_step(B,N) 成功复制 N 页并且还有更多页需要复制,则函数返回SQLITE_OK如果 sqlite3_backup_step(B,N) 成功完成将所有页面从源复制到目标,则它返回SQLITE_DONE如果在运行 sqlite3_backup_step(B,N) 时发生错误,则返回错误代码除了SQLITE_OKSQLITE_DONE,对 sqlite3_backup_step() 的调用可能会返回SQLITE_READONLYSQLITE_NOMEMSQLITE_BUSYSQLITE_LOCKEDSQLITE_IOERR_XXX扩展错误代码。

    sqlite3_backup_step() 可能返回SQLITE_READONLY如果

    1. 目标数据库以只读方式打开,或者
    2. 目标数据库正在使用预写日志日志记录并且目标和源页面大小不同,或者
    3. 目标数据库是内存数据库,目标和源页面大小不同。

    如果 sqlite3_backup_step() 无法获得所需的文件系统锁,则调用忙处理函数 (如果已指定)。如果忙处理程序在锁定可用之前返回非零值,则 SQLITE_BUSY返回给调用者。在这种情况下,可以稍后重试对 sqlite3_backup_step() 的调用。如果在调用 sqlite3_backup_step() 时正在使用源 数据库连接 写入源数据库,则立即返回SQLITE_LOCKED同样,在这种情况下,可以稍后重试对 sqlite3_backup_step() 的调用。如果 SQLITE_IOERR_XXXSQLITE_NOMEMSQLITE_READONLY被返回,那么重试对 sqlite3_backup_step() 的调用就没有意义了。这些错误被认为是致命的。应用程序必须接受备份操作失败并将备份操作句柄传递给 sqlite3_backup_finish() 以释放相关资源。

    对 sqlite3_backup_step() 的第一次调用获得了对目标文件的独占锁。在调用 sqlite3_backup_finish() 或备份操作完成并且 sqlite3_backup_step() 返回SQLITE_DONE之前,独占锁不会被释放。每次调用 sqlite3_backup_step() 都会获得一个共享锁在 sqlite3_backup_step() 调用期间持续的源数据库上。因为源数据库在调用 sqlite3_backup_step() 之间没有被锁定,所以源数据库可能会在备份过程中途被修改。如果源数据库被外部进程或通过备份操作使用的数据库连接之外的数据库连接修改,则备份将在下一次调用 sqlite3_backup_step() 时自动重新启动。如果使用与备份操作相同的数据库连接修改源数据库,则备份数据库会同时自动更新。

    sqlite3_backup_finish()

    当 sqlite3_backup_step() 返回SQLITE_DONE时,或者当应用程序希望放弃备份操作时,应用程序应该通过将sqlite3_backup传递给 sqlite3_backup_finish() 来销毁它。sqlite3_backup_finish() 接口释放与sqlite3_backup对象关联的所有资源。如果 sqlite3_backup_step() 尚未返回SQLITE_DONE,则回滚目标数据库上的任何活动写事务。sqlite3_backup对象无效,不能在调用 sqlite3_backup_finish() 后使用。

    如果没有发生 sqlite3_backup_step() 错误,则 sqlite3_backup_finish返回的值为SQLITE_OK,无论 sqlite3_backup_step() 是否完成。如果在同一sqlite3_backup对象上的任何先前 sqlite3_backup_step() 调用期间发生内存不足情况或 IO 错误,则 sqlite3_backup_finish() 返回相应的错误代码

    从 sqlite3_backup_step()返回SQLITE_BUSYSQLITE_LOCKED不是永久性错误,不会影响 sqlite3_backup_finish() 的返回值。

    sqlite3_backup_remaining() 和 sqlite3_backup_pagecount()

    sqlite3_backup_remaining() 例程返回在最近的 sqlite3_backup_step() 结束时仍要备份的页数。sqlite3_backup_pagecount() 例程在最近的 sqlite3_backup_step() 结束时返回源数据库中的总页数。这些函数返回的值仅由 sqlite3_backup_step() 更新。如果以更改源数据库大小或剩余页数的方式修改源数据库,则这些更改不会反映在 sqlite3_backup_pagecount() 和 sqlite3_backup_remaining() 的输出中,直到下一个 sqlite3_backup_step() 之后。

    并发使用数据库句柄

    当备份操作正在进行或正在初始化时,应用程序可能会将数据库连接用于其他目的。如果 SQLite 被编译并配置为支持线程安全数据库连接,那么源数据库连接可以在其他线程中同时使用。

    但是,应用程序必须保证在 调用 sqlite3_backup_init() 之后和相应调用 sqlite3_backup_finish() 之前,目标数据库连接不会(通过任何线程)传递给任何其他 API。SQLite 目前不会检查应用程序是否错误地访问了目标数据库连接 ,因此不会报告任何错误代码,但操作可能会出现故障。在备份过程中使用目标数据库连接也可能导致互斥死锁。

    如果以共享缓存模式运行,应用程序必须保证在备份运行时不访问目标数据库使用的共享缓存。实际上,这意味着应用程序必须保证正在备份的磁盘文件不会被进程内的任何连接访问,而不仅仅是传递给 sqlite3_backup_init() 的特定连接。

    sqlite3_backup对象本身是部分线程安全的多个线程可以安全地对 sqlite3_backup_step() 进行多个并发调用。但是,严格来说,sqlite3_backup_remaining() 和 sqlite3_backup_pagecount() API 并不是线程安全的。如果在另一个线程调用 sqlite3_backup_step() 的同时调用它们,则它们可能返回无效值。


    计算修改的行数

    int sqlite3_changes(sqlite3*);
    sqlite3_int64 sqlite3_changes64(sqlite3*);
    

    这些函数返回由唯一参数指定的数据库连接上最近完成的 INSERT、UPDATE 或 DELETE 语句修改、插入或删除的行数。这两个函数除了返回值的类型不同,如果最近一次 INSERT、UPDATE 或 DELETE 修改的行数大于“int”类型支持的最大值,则 sqlite3_changes( ) 未定义。执行任何其他类型的 SQL 语句不会修改这些函数返回的值。

    仅考虑由 INSERT、UPDATE 或 DELETE 语句直接进行的更改 -不计算由触发器外键操作REPLACE约束解析引起的辅助更改。

    不计算被INSTEAD OF 触发器拦截的视图更改 。在视图上运行 INSERT、UPDATE 或 DELETE 语句后,sqlite3_changes() 立即返回的值始终为零。只计算对真实表所做的更改。

    如果在触发器程序运行时执行 sqlite3_changes() 函数,事情会更加复杂。如果程序使用changes() SQL 函数,或者如果某些其他回调函数直接调用 sqlite3_changes(),则可能会发生这种情况。本质上:

    • 在进入触发器程序之前,sqlite3_changes() 函数返回的值被保存。触发程序完成后,恢复原始值。

    • 在触发器程序中,每个 INSERT、UPDATE 和 DELETE 语句在正常完成时设置 sqlite3_changes() 返回的值。当然,这个值不包括子触发器执行的任何更改,因为 sqlite3_changes() 值将在每个子触发器运行后保存和恢复。

    这意味着如果触发器中的第一个 INSERT、UPDATE 或 DELETE 语句使用 changes() SQL 函数(或类似函数),它会返回调用语句开始执行时设置的值。如果它被触发器程序中的第二个或后续此类语句使用,则返回的值反映由同一触发器中的前一个 INSERT、UPDATE 或 DELETE 语句修改的行数。

    如果一个单独的线程在sqlite3_changes()运行时对同一个数据库连接进行更改,则返回的值是不可预测的并且没有意义。

    也可以看看:


    关闭数据库连接

    int sqlite3_close(sqlite3*);
    int sqlite3_close_v2(sqlite3*);
    

    sqlite3_close() 和 sqlite3_close_v2() 例程是sqlite3对象的析构函数。如果sqlite3对象被成功销毁并且所有相关资源都被释放,则调用 sqlite3_close() 和 sqlite3_close_v2() 返回SQLITE_OK 。

    理想情况下,应用程序应该完成所有 准备好的语句关闭所有BLOB 句柄,并 在尝试关闭对象之前完成与sqlite3对象关联的所有sqlite3_backup对象。如果数据库连接与未完成的准备语句、BLOB 处理程序和/或未完成的 sqlite3_backup 对象相关联,则 sqlite3_close() 将使数据库连接保持打开状态并返回 SQLITE_BUSY如果使用未完成的准备语句、未关闭的 BLOB 处理程序和/或未完成的 sqlite3_backups 调用 sqlite3_close_v2(),它返回SQLITE_OK不管怎样,但它不会立即释放数据库连接,而是将数据库连接标记为不可用的“僵尸”,并安排在所有准备好的语句完成、所有 BLOB 句柄关闭以及所有备份完成后自动释放数据库连接。sqlite3_close_v2() 接口旨在与垃圾收集的宿主语言一起使用,并且调用析构函数的顺序是任意的。

    如果sqlite3对象在事务打开时被销毁,事务将自动回滚。

    sqlite3_close(C)sqlite3_close_v2(C)的 C 参数 必须是 NULL 指针或sqlite3_open()sqlite3_open16()sqlite3_open_v2()获得的sqlite3对象指针,并且之前未关闭。使用 NULL 指针参数调用 sqlite3_close() 或 sqlite3_close_v2() 是无害的空操作。


    整理需要回调

    int sqlite3_collation_needed(
      sqlite3*,
      void*,
      void(*)(void*,sqlite3*,int eTextRep,const char*)
    );
    int sqlite3_collation_needed16(
      sqlite3*,
      void*,
      void(*)(void*,sqlite3*,int eTextRep,const void*)
    );
    

    为了避免在可以使用数据库之前必须注册所有归类序列,可以向 数据库连接注册一个回调函数,以便在需要未定义的归类序列时调用。

    如果该函数是使用 sqlite3_collat​​ion_needed() API 注册的,那么它将以未定义的排序规则序列的名称作为以 UTF-8 编码的字符串传递。如果使用 sqlite3_collat​​ion_needed16() ,名称将以机器本机字节顺序作为 UTF-16 传递。对任一函数的调用都会替换现有的需要排序规则的回调。

    调用回调时,传递的第一个参数是 sqlite3_collat​​ion_needed() 或 sqlite3_collat​​ion_needed16() 的第二个参数的副本。第二个参数是数据库连接。第三个参数是SQLITE_UTF8SQLITE_UTF16BESQLITE_UTF16LE 之一,指示所需的排序规则函数的最理想形式。第四个参数是所需归类序列的名称。

    回调函数应使用sqlite3_create_collat​​ion()sqlite3_create_collat​​ion16()sqlite3_create_collat​​ion_v2()注册所需的排序 规则


    查询结果中的数据来源

    const char *sqlite3_column_database_name(sqlite3_stmt*,int);
    const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
    const char *sqlite3_column_table_name(sqlite3_stmt*,int);
    const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
    const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
    const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
    

    这些例程提供了一种方法来确定作为SELECT语句 中特定结果列来源的数据库、表和表列 。数据库或表或列的名称可以作为 UTF-8 或 UTF-16 字符串返回。_database_ 例程返回数据库名称,_table_ 例程返回表名,origin_ 例程返回列名。返回的字符串有效,直到使用sqlite3_finalize()销毁准备好的语句,或者直到通过第一次调用sqlite3_step()为特定运行自动重新准备语句,或者直到以不同的编码再次请求相同的信息。

    返回的名称是数据库、表和列的原始无别名名称。

    这些接口的第一个参数是准备好的语句这些函数返回有关语句返回的第 N 个结果列的信息,其中 N 是第二个函数参数。最左边的列是这些例程的第 0 列。

    如果语句返回的第 N 列是一个表达式或子查询并且不是列值,那么所有这些函数都返回 NULL。如果发生内存分配错误,这些例程也可能返回 NULL。否则,它们返回从中提取查询结果列的附加数据库、表或列的名称。

    与所有其他 SQLite API 一样,那些名称以“16”结尾的 API 返回 UTF-16 编码的字符串,而其他函数返回 UTF-8。

    这些 API 仅在使用 SQLITE_ENABLE_COLUMN_METADATA C 预处理器符号编译库时可用。

    如果两个或多个线程 同时为同一个准备好的语句和结果列调用一个或多个列元数据接口,则结果是未定义的。


    查询结果声明的数据类型

    const char *sqlite3_column_decltype(sqlite3_stmt*,int);
    const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
    

    第一个参数是准备好的语句如果该语句是一个SELECT语句,并且该SELECT的返回结果集的第 N 列是表列(不是表达式或子查询),则返回表列的声明类型。如果结果集的第 N 列是表达式或子查询,则返回 NULL 指针。返回的字符串始终采用 UTF-8 编码。

    例如,给定数据库模式:

    创建表 t1(c1 变体);

    以及以下要编译的语句:

    从 t1 选择 c1 + 1,c1;

    此例程将为第二个结果列 (i==1) 返回字符串“VARIANT”,并为第一个结果列 (i==0) 返回 NULL 指针。

    SQLite 使用动态运行时类型。因此,仅仅因为列被声明为包含特定类型并不意味着存储在该列中的数据是声明的类型。SQLite 是强类型的,但类型是动态的而不是静态的。类型与单个值相关联,而不是与用于保存这些值的容器相关联。


    结果集中的列名

    const char *sqlite3_column_name(sqlite3_stmt*, int N);
    const void *sqlite3_column_name16(sqlite3_stmt*, int N);
    

    这些例程返回分配给SELECT语句 结果集中特定列的名称。sqlite3_column_name() 接口返回一个指向以零结尾的 UTF-8 字符串的指针,而 sqlite3_column_name16() 返回一个指向以零结尾的 UTF-16 字符串的指针。第一个参数是 实现SELECT语句的准备语句。第二个参数是列号。最左边的列是数字 0。

    返回的字符串指针是有效的,直到准备好的语句sqlite3_finalize()销毁,或者直到语句被第一次调用sqlite3_step()为特定运行自动重新准备,或者直到下一次调用 sqlite3_column_name() 或 sqlite3_column_name16()同一列。

    如果 sqlite3_malloc() 在任一例程的处理过程中失败(例如在从 UTF-8 到 UTF-16 的转换过程中),则返回 NULL 指针。

    结果列的名称是该列的“AS”子句的值(如果有 AS 子句)。如果没有 AS 子句,则列的名称是未指定的,并且可能从一个 SQLite 版本到下一个版本更改。


    提交和回滚通知回调

    void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
    void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
    

    sqlite3_commit_hook() 接口注册了一个回调函数,只要事务被提交 就会被调用先前为同一数据库连接调用 sqlite3_commit_hook() 设置的任何回调都将被覆盖。sqlite3_rollback_hook() 接口注册了一个回调函数,只要事务被回滚就会被调用。先前为同一数据库连接调用 sqlite3_rollback_hook() 设置的任何回调都将被覆盖。pArg 参数传递给回调。如果提交挂钩函数的回调返回非零值,则提交将转换为回滚。

    sqlite3_commit_hook(D,C,P) 和 sqlite3_rollback_hook(D,C,P) 函数返回同一数据库连接D上同一函数的先前调用的 P 参数,或者对于 D 上每个函数的第一次调用返回 NULL。

    提交和回滚挂钩回调不可重入。回调实现不得做任何会修改调用回调的数据库连接的事情。任何修改数据库连接的操作都必须推迟到首先触发提交或回滚挂钩的sqlite3_step()调用完成之后。请注意,运行任何其他 SQL 语句,包括 SELECT 语句,或仅调用sqlite3_prepare_v2()sqlite3_step()将修改本段中“修改”含义的数据库连接。

    注册 NULL 函数会禁用回调。

    当提交挂钩回调例程返回零时,允许COMMIT 操作正常继续。如果提交挂钩返回非零值,则COMMIT将转换为ROLLBACK回滚钩子在由返回非零的提交钩子引起的回滚时调用,就像任何其他回滚一样。

    出于此 API 的目的,如果执行显式“ROLLBACK”语句,或者错误或约束导致发生隐式回滚,则称事务已回滚。如果由于数据库连接关闭而自动回滚事务,则不会调用回滚回调。

    另请参阅sqlite3_update_hook()接口。


    运行时库编译选项诊断

    #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
    int sqlite3_compileoption_used(const char *zOptName);
    const char *sqlite3_compileoption_get(int N);
    #else
    # define sqlite3_compileoption_used(X) 0
    # define sqlite3_compileoption_get(X)  ((void*)0)
    #endif
    

    sqlite3_compileoption_used() 函数返回 0 或 1,指示指定的选项是否在编译时定义。SQLITE_ 前缀可以从传递给 sqlite3_compileoption_used() 的选项名称中省略。

    sqlite3_compileoption_get() 函数允许通过返回第 N 个编译时选项字符串来迭代在编译时定义的选项列表。如果 N 超出范围,则 sqlite3_compileoption_get() 返回 NULL 指针。SQLITE_ 前缀从 sqlite3_compileoption_get() 返回的任何字符串中被省略。

    通过在编译时指定SQLITE_OMIT_COMPILEOPTION_DIAGS选项,可以省略对诊断函数 sqlite3_compileoption_used() 和 sqlite3_compileoption_get() 的 支持。

    另请参阅:SQL 函数sqlite_compileoption_used()sqlite_compileoption_get()以及compile_options pragma


    判断 SQL 语句是否完整

    int sqlite3_complete(const char *sql);
    int sqlite3_complete16(const void *sql);
    

    这些例程在命令行输入期间很有用,可以确定当前输入的文本是否构成了完整的 SQL 语句,或者在将文本发送到 SQLite 进行解析之前是否需要额外的输入。如果输入字符串看起来是一个完整的 SQL 语句,这些例程将返回 1。如果语句以分号标记结尾并且不是格式正确的 CREATE TRIGGER 语句的前缀,则该语句被判断为完整的。嵌入在字符串文字或引用的标识符名称或注释中的分号不是独立的标记(它们是它们嵌入其中的标记的一部分),因此不算作语句终止符。最后一个分号后面的空格和注释将被忽略。

    如果语句不完整,这些例程返回 0。如果内存分配失败,则返回 SQLITE_NOMEM。

    这些例程不解析 SQL 语句,因此不会检测语法上不正确的 SQL。

    如果在调用 sqlite3_complete16() 之前未使用sqlite3_initialize()初始化 SQLite,则 sqlite3_complete16() 会自动调用 sqlite3_initialize()。如果初始化失败,则无论输入 SQL 是否完成,sqlite3_complete16() 的返回值都将是非零值。

    sqlite3_complete()的输入必须是以零结尾的 UTF-8 字符串。

    sqlite3_complete16()的输入必须是本机字节顺序的零终止 UTF-16 字符串。


    定义新的整理顺序

    int sqlite3_create_collation(
      sqlite3*,
      const char *zName,
      int eTextRep,
      void *pArg,
      int(*xCompare)(void*,int,const void*,int,const void*)
    );
    int sqlite3_create_collation_v2(
      sqlite3*,
      const char *zName,
      int eTextRep,
      void *pArg,
      int(*xCompare)(void*,int,const void*,int,const void*),
      void(*xDestroy)(void*)
    );
    int sqlite3_create_collation16(
      sqlite3*,
      const void *zName,
      int eTextRep,
      void *pArg,
      int(*xCompare)(void*,int,const void*,int,const void*)
    );
    

    这些函数添加、删除或修改与指定为第一个参数的数据库连接关联的排序规则。

    排序规则的名称是 sqlite3_create_collat​​ion() 和 sqlite3_create_collat​​ion_v2() 的 UTF-8 字符串,以及 sqlite3_create_collat​​ion16() 的本地字节顺序的 UTF-16 字符串。根据sqlite3_strnicmp()比较相等的排序规则名称被认为是相同的名称。

    第三个参数 (eTextRep) 必须是常量之一:

    eTextRep 参数确定传递给整理函数回调 xCompare 的字符串的编码。eTextRep的SQLITE_UTF16SQLITE_UTF16_ALIGNED值强制字符串为具有本机字节顺序的 UTF16。eTextRep的SQLITE_UTF16_ALIGNED值强制字符串从偶数字节地址开始。

    第四个参数 pArg 是一个应用程序数据指针,它作为第一个参数传递给整理函数回调。

    第五个参数 xCompare 是指向整理函数的指针。可以使用相同的名称但使用不同的 eTextRep 参数注册多个整理函数,SQLite 将使用需要最少数据转换的函数。如果 xCompare 参数为 NULL,则删除整理函数。当删除所有具有相同名称的整理功能时,该整理将不再可用。

    使用 pArg 应用程序数据指针的副本和 eTextRep 参数指定的编码中的两个字符串调用整理函数回调。整理函数回调的两个整数参数是两个字符串的长度,以字节为单位。如果第一个字符串分别小于、等于或大于第二个字符串,则整理函数必须返回一个负整数、零整数或正整数。给定相同的输入,整理函数必须始终返回相同的答案。如果两个或多个整理函数注册到相同的整理名称(使用不同的 eTextRep 值),那么在使用等效字符串调用时,所有函数都必须给出等效的答案。整理函数必须遵守所有字符串 A、B 和 C 的以下属性:

    1. 如果 A==B 则 B==A。
    2. 如果 A==B 且 B==C 则 A==C。
    3. 如果 A<B 则 B>A。
    4. 如果 A<B 且 B<C,则 A<C。

    如果一个整理函数没有满足上述任何约束,并且该整理函数被注册和使用,那么 SQLite 的行为是未定义的。

    sqlite3_create_collat​​ion_v2() 的工作方式与 sqlite3_create_collat​​ion() 类似,只是在删除整理函数时会在 pArg 上调用 xDestroy 回调。当以后调用归类创建函数或使用sqlite3_close()关闭数据库连接时,归类函数将被删除

    如果 sqlite3_create_collat​​ion_v2() 函数失败,则不会调用xDestroy 回调。使用非 NULL xDestroy 参数调用 sqlite3_create_collat​​ion_v2() 的应用程序应该检查返回代码并自行处理应用程序数据指针,而不是期望 SQLite 为它们处理它。这与所有其他 SQLite 接口不同。不一致是不幸的,但在不破坏向后兼容性的情况下无法更改。

    另见: sqlite3_collat​​ion_needed()sqlite3_collat​​ion_needed16()


    创建和销毁 VFS 文件名

    char *sqlite3_create_filename(
      const char *zDatabase,
      const char *zJournal,
      const char *zWal,
      int nParam,
      const char **azParam
    );
    void sqlite3_free_filename(char*);
    

    这些接口供VFS shim实现使用,在该上下文之外没有用。

    sqlite3_create_filename(D,J,W,N,P) 分配内存来保存数据库文件名 D 的版本,对应的日志文件 J 和 WAL 文件 W 以及数组 P 中的 N URI 参数键/值对。sqlite3_create_filename 的结果(D,J,W,N,P) 是指向数据库文件名的指针,可以安全地传递给以下例程:

    如果发生内存分配错误,sqlite3_create_filename() 可能会返回 NULL 指针。从 sqlite3_create_filename(X) 获得的内存必须通过相应调用 sqlite3_free_filename(Y) 来释放。

    sqlite3_create_filename(D,J,W,N,P) 中的 P 参数应该是一个包含 2*N 个字符串指针的数组。此数组中的每对指针对应于查询参数的键和值。如果 N 为零,则 P 参数可以是 NULL 指针。P 数组中的 2*N 个指针都不能是 NULL 指针,关键指针不应该是空字符串。sqlite3_create_filename(D,J,W,N,P) 的 D、J 或 W 参数都不能是 NULL 指针,尽管它们可以是空字符串。

    sqlite3_free_filename(Y) 例程释放先前从 sqlite3_create_filename() 获得的内存分配。调用 sqlite3_free_filename(Y) 其中 Y 是 NULL 指针是无害的空操作。

    如果 sqlite3_free_filename(Y) 的 Y 参数不是 NULL 指针或先前从 sqlite3_create_filename() 获取的指针,那么可能会发生堆损坏或段错误等坏事。在调用 sqlite3_free_filename(Y) 之后不应再次使用值 Y。这意味着如果使用 Y 调用了 VFS 的sqlite3_vfs.xOpen()方法,则还应在调用 sqlite3_free_filename(Y) 之前调用相应的 [sqlite3_module.xClose() 方法。


    注册一个虚拟表实现

    int sqlite3_create_module(
      sqlite3 *db,               /* SQLite connection to register module with */
      const char *zName,         /* Name of the module */
      const sqlite3_module *p,   /* Methods for the module */
      void *pClientData          /* Client data for xCreate/xConnect */
    );
    int sqlite3_create_module_v2(
      sqlite3 *db,               /* SQLite connection to register module with */
      const char *zName,         /* Name of the module */
      const sqlite3_module *p,   /* Methods for the module */
      void *pClientData,         /* Client data for xCreate/xConnect */
      void(*xDestroy)(void*)     /* Module destructor function */
    );
    

    这些例程用于注册新的虚拟表模块名称。在使用模块创建新的虚拟表之前以及为模块使用预先存在的虚拟表之前,必须注册模块名称

    模块名称注册在第一个参数指定的数据库连接上。模块的名称由第二个参数给出。第三个参数是指向虚拟表模块实现的指针。第四个参数是一个任意的客户端数据指针,当创建或重新初始化一个新的虚拟表时,它被传递到虚拟表模块的xCreatexConnect方法中。

    sqlite3_create_module_v2() 接口有第五个参数,它是指向 pClientData 析构函数的指针。当 SQLite 不再需要 pClientData 指针时,SQLite 将调用析构函数(如果它不为 NULL)。如果对 sqlite3_create_module_v2() 的调用失败,也会调用析构函数。sqlite3_create_module() 接口等同于带有 NULL 析构函数的 sqlite3_create_module_v2()。

    如果第三个参数(指向 sqlite3_module 对象的指针)为 NULL,则不会创建新模块,并且会删除任何具有相同名称的现有模块。

    另见:sqlite3_drop_modules()


    错误代码和消息

    int sqlite3_errcode(sqlite3 *db);
    int sqlite3_extended_errcode(sqlite3 *db);
    const char *sqlite3_errmsg(sqlite3*);
    const void *sqlite3_errmsg16(sqlite3*);
    const char *sqlite3_errstr(int);
    int sqlite3_error_offset(sqlite3 *db);
    

    如果最近一次与 数据库连接D 关联的 sqlite3_* API 调用失败,则 sqlite3_errcode(D) 接口返回该 API 调用的数字结果代码扩展结果代码sqlite3_extended_errcode() 接口是相同的,除了它总是返回 扩展结果代码,即使扩展结果代码被禁用。

    sqlite3_errcode() 和/或 sqlite3_extended_errcode() 返回的值可能会随着每次 API 调用而改变。除了,有一些接口保证永远不会改变错误代码的值。错误代码保留接口包括以下内容:

    • sqlite3_errcode()
    • sqlite3_extended_errcode()
    • sqlite3_errmsg()
    • sqlite3_errmsg16()
    • sqlite3_error_offset()

    sqlite3_errmsg() 和 sqlite3_errmsg16() 返回描述错误的英文文本,分别为 UTF-8 或 UTF-16。保存错误消息字符串的内存在内部进行管理。应用程序不需要担心释放结果。但是,错误字符串可能会被后续调用其他 SQLite 接口函数覆盖或释放。

    sqlite3_errstr() 接口返回描述结果代码的英文文本,作为 UTF-8。保存错误消息字符串的内存在内部进行管理,不得由应用程序释放。

    如果最近的错误引用了输入 SQL 中的特定标记,则 sqlite3_error_offset() 接口返回该标记开头的字节偏移量。sqlite3_error_offset() 返回的字节偏移假定输入的 SQL 是 UTF8。如果最近的错误没有引用输入 SQL 中的特定标记,则 sqlite3_error_offset() 函数返回 -1。

    当使用序列化线程模式时,可能会出现在第一个错误和调用这些接口之间的单独线程上发生第二个错误的情况。当发生这种情况时,将报告第二个错误,因为这些接口总是报告最新的结果。为了避免这种情况,每个线程可以通过在开始使用D之前调用sqlite3_mutex_enter ( sqlite3_db_mutex (D))并在对这里列出的接口的所有调用完成之后调用sqlite3_mutex_leave ( sqlite3_db_mutex (D))来获得对数据库连接D的独占使用权。

    如果一个接口因 SQLITE_MISUSE 而失败,这意味着该接口被应用程序错误地调用了。在这种情况下,可能会或可能不会设置错误代码和消息。


    检索语句 SQL

    const char *sqlite3_sql(sqlite3_stmt *pStmt);
    char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
    #ifdef SQLITE_ENABLE_NORMALIZE
    const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
    #endif
    

    如果 P 是由sqlite3_prepare_v2()sqlite3_prepare_v3()sqlite3_prepare16_v2()sqlite3_prepare16_v3()创建的,则 sqlite3_sql(P) 接口返回一个指向用于创建准备语句P 的 UTF-8 SQL 文本副本的指针。sqlite3_expanded_sql(P) 接口返回一个指向 UTF-8 字符串的指针,该字符串包含带有 扩展绑定参数的准备语句 P 的 SQL 文本。sqlite3_normalized_sql(P) 接口返回一个指向 UTF-8 字符串的指针,该字符串包含准备语句 P 的规范化 SQL 文本。用于规范化 SQL 语句的语义未指定并且可能会更改。至少,文字值将替换为合适的占位符。

    例如,如果使用 SQL 文本“SELECT $abc,:xyz”创建准备语句,并且参数 $abc 绑定到整数 2345 而参数 :xyz 未绑定,则 sqlite3_sql() 将返回原始字符串“SELECT $abc,:xyz" 但 sqlite3_expanded_sql() 将返回 "SELECT 2345,NULL"。

    如果没有足够的内存来保存结果,或者如果结果超过SQLITE_LIMIT_LENGTH确定的最大字符串长度,则 sqlite3_expanded_sql() 接口返回 NULL 。

    SQLITE_TRACE_SIZE_LIMIT编译选项限制绑定参数扩展的大小。SQLITE_OMIT_TRACE编译选项导致 sqlite3_expanded_sql() 始终返回 NULL。

    sqlite3_sql(P) 和 sqlite3_normalized_sql(P) 返回的字符串由 SQLite 管理,并在准备好的语句完成时自动释放。另一方面,sqlite3_expanded_sql(P) 返回的字符串是从sqlite3_malloc()获得的,应用程序必须通过将其传递给sqlite3_free()来释放它。

    sqlite3_normalized_sql() 接口仅在定义了SQLITE_ENABLE_NORMALIZE编译时选项时可用。


    翻译文件名

    const char *sqlite3_filename_database(const char*);
    const char *sqlite3_filename_journal(const char*);
    const char *sqlite3_filename_wal(const char*);
    

    这些例程可用于自定义 VFS 实现,用于在主数据库文件、日志文件和 WAL 文件之间转换文件名。

    如果 F 是 SQLite 核心传递给 VFS 的 sqlite 数据库文件、日志文件或 WAL 文件的名称,则 sqlite3_filename_database(F) 返回相应数据库文件的名称。

    如果 F 是 SQLite 核心传递给 VFS 的 sqlite 数据库文件、日志文件或 WAL 文件的名称,或者如果 F 是从sqlite3_db_filename()获得的数据库文件名,则 sqlite3_filename_journal(F) 返回相应的名称回滚日志文件。

    如果 F 是由 SQLite 核心传递到 VFS 的 sqlite 数据库文件、日志文件或 WAL 文件的名称,或者如果 F 是从sqlite3_db_filename()获得的数据库文件名,则 sqlite3_filename_wal(F) 返回名称对应的 WAL 文件。

    在以上所有情况下,如果 F 不是从 SQLite 核心传递到 VFS 的数据库名称、日志或 WAL 文件名,并且 F 不是sqlite3_db_filename()的返回值,则结果未定义,可能是内存访问冲突。


    内存分配子系统

    void *sqlite3_malloc(int);
    void *sqlite3_malloc64(sqlite3_uint64);
    void *sqlite3_realloc(void*, int);
    void *sqlite3_realloc64(void*, sqlite3_uint64);
    void sqlite3_free(void*);
    sqlite3_uint64 sqlite3_msize(void*);
    

    SQLite 核心使用这三个例程来满足其所有内部内存分配需求。上一句中的“核心”不包括特定于操作系统的VFS实现。Windows VFS 使用本机 malloc() 和 free() 进行某些操作。

    sqlite3_malloc() 例程返回一个指向内存块的指针,该内存块的长度至少为 N 字节,其中 N 是参数。如果 sqlite3_malloc() 无法获得足够的空闲内存,它会返回一个 NULL 指针。如果 sqlite3_malloc() 的参数 N 为零或负数,则 sqlite3_malloc() 返回 NULL 指针。

    sqlite3_malloc64(N) 例程的工作方式与 sqlite3_malloc(N) 类似,只是 N 是无符号 64 位整数而不是带符号的 32 位整数。

    使用先前由 sqlite3_malloc() 或 sqlite3_realloc() 返回的指针调用 sqlite3_free() 会释放该内存,以便它可以被重用。如果使用 NULL 指针调用,则 sqlite3_free() 例程是空操作。将 NULL 指针传递给 sqlite3_free() 是无害的。释放后,不应读取或写入内存。即使读取以前释放的内存也可能导致分段错误或其他严重错误。如果使用不是从 sqlite3_malloc() 或 sqlite3_realloc() 获得的非 NULL 指针调用 sqlite3_free(),则可能会导致内存损坏、分段错误或其他严重错误。

    sqlite3_realloc(X,N) 接口尝试将先前的内存分配 X 调整为至少 N 字节。如果 sqlite3_realloc(X,N) 的 X 参数是 NULL 指针,那么它的行为与调用 sqlite3_malloc(N) 相同。如果 sqlite3_realloc(X,N) 的 N 参数为零或负数,则行为与调用 sqlite3_free(X) 完全相同。sqlite3_realloc(X,N) 返回一个指向至少 N 字节大小的内存分配的指针,如果可用内存不足则返回 NULL。如果 M 是先前分配的大小,则先前分配的 min(N,M) 字节被复制到 sqlite3_realloc(X,N) 返回的缓冲区的开头,并且先前分配被释放。如果 sqlite3_realloc(X,N) 返回 NULL 且 N 为正,则不会释放先前的分配。

    sqlite3_realloc64(X,N) 接口与 sqlite3_realloc(X,N) 的工作方式相同,只是 N 是 64 位无符号整数而不是 32 位有符号整数。

    如果 X 是先前从 sqlite3_malloc()、sqlite3_malloc64()、sqlite3_realloc() 或 sqlite3_realloc64() 获得的内存分配,则 sqlite3_msize(X) 返回该内存分配的大小(以字节为单位)。sqlite3_msize(X) 返回的值可能大于分配 X 时请求的字节数。如果 X 是 NULL 指针,则 sqlite3_msize(X) 返回零。如果 X 指向的不是内存分配的开始,或者如果它指向现在已被释放的以前有效的内存分配,则 sqlite3_msize(X) 的行为是未定义的并且可能有害。

    sqlite3_malloc()、sqlite3_realloc()、sqlite3_malloc64() 和 sqlite3_realloc64() 返回的内存始终至少对齐到 8 字节边界,如果使用SQLITE_4_BYTE_ALIGNED_MALLOC编译时选项,则始终对齐到 4 字节边界。

    sqlite3_free()sqlite3_realloc()的指针参数 必须是 NULL 或从先前调用sqlite3_malloc()sqlite3_realloc()获得的尚未释放的指针。

    在使用sqlite3_free()sqlite3_realloc()释放内存块后,应用程序不得读取或写入内存块的任何部分


    运行查询的便捷例程

    int sqlite3_get_table(
      sqlite3 *db,          /* An open database */
      const char *zSql,     /* SQL to be evaluated */
      char ***pazResult,    /* Results of the query */
      int *pnRow,           /* Number of result rows written here */
      int *pnColumn,        /* Number of result columns written here */
      char **pzErrmsg       /* Error msg written here */
    );
    void sqlite3_free_table(char **result);
    

    这是为向后兼容而保留的旧接口。不建议使用此接口。

    定义:结果表是由sqlite3_get_table()接口创建的内存数据结构 。结果表记录了一个或多个查询的完整查询结果。

    该表在概念上有许多行和列。但是这些数字并不是结果表本身的一部分。这些数字是单独获得的。令 N 为行数,M 为列数。

    结果表是指向以零结尾的 UTF-8 字符串的指针数组。数组中有 (N+1)*M 个元素。前 M 个指针指向包含列名的以零结尾的字符串。其余条目均指向查询结果。NULL 值导致 NULL 指针。所有其他值均采用sqlite3_column_text()返回的 UTF-8 零终止字符串表示形式

    结果表可能包含一个或多个内存分配。将结果表直接传递给sqlite3_free()是不安全的应使用sqlite3_free_table()释放结果表。

    作为结果表格式的例子,假设一个查询结果如下:

    Name        | Age
    -----------------------
    Alice       | 43
    Bob         | 28
    Cindy       | 21
    

    有两列 (M==2) 和三行 (N==3)。因此结果表有 8 个条目。假设结果表存储在名为 azResult 的数组中。然后 azResult 包含以下内容:

    azResult[0] = "Name";
    azResult[1] = "Age";
    azResult[2] = "Alice";
    azResult[3] = "43";
    azResult[4] = "Bob";
    azResult[5] = "28";
    azResult[6] = "Cindy";
    azResult[7] = "21";
    

    sqlite3_get_table() 函数在其第二个参数的以零结尾的 UTF-8 字符串中评估一个或多个以分号分隔的 SQL 语句,并将结果表返回到其第三个参数中给出的指针。

    在应用程序完成 sqlite3_get_table() 的结果后,它必须将结果表指针传递给 sqlite3_free_table() 以释放分配的内存。由于 sqlite3_malloc() 在 sqlite3_get_table ()中发生的方式,调用函数不得尝试直接调用sqlite3_free()只有 sqlite3_free_table()能够正确安全地释放内存。

    sqlite3_get_table() 接口是作为sqlite3_exec()的包装器实现的 sqlite3_get_table() 例程无权访问 SQLite 的任何内部数据结构。它仅使用此处定义的公共接口。因此,在内部sqlite3_exec()调用之外的包装层中发生的错误不会反映在对sqlite3_errcode()sqlite3_errmsg()的后续调用中


    函数辅助数据

    void *sqlite3_get_auxdata(sqlite3_context*, int N);
    void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
    

    (非聚合)SQL 函数可以使用这些函数将元数据与参数值相关联。如果在查询执行期间将相同的值传递给同一 SQL 函数的多次调用,则在某些情况下可能会保留关联的元数据。这可能有用的一个示例是在正则表达式匹配函数中。正则表达式的编译版本可以存储为与模式字符串相关联的元数据。然后只要模式字符串保持不变,编译后的正则表达式就可以在同一函数的多次调用中重复使用。

    sqlite3_get_auxdata(C,N) 接口返回一个指向元数据的指针,该元数据由 sqlite3_set_auxdata(C,N,P,X) 函数与应用程序定义函数的第 N 个参数值关联。对于最左边的函数参数,N 为零。如果没有与函数参数关联的元数据,则 sqlite3_get_auxdata(C,N) 接口返回 NULL 指针。

    sqlite3_set_auxdata(C,N,P,X) 接口将 P 保存为应用程序定义函数的第 N 个参数的元数据。如果元数据仍然有效,则对 sqlite3_get_auxdata(C,N) 的后续调用从最近的 sqlite3_set_auxdata(C,N,P,X) 调用返回 P,如果元数据已被丢弃,则返回 NULL。在每次调用 sqlite3_set_auxdata(C,N,P,X)(其中 X 不为 NULL)之后,当元数据被丢弃时,SQLite 将调用带有参数 P 的析构函数 X 恰好一次。SQLite 可以随时随意丢弃元数据,包括:

    • 当相应的功能参数发生变化时,或
    • SQL 语句调用 sqlite3_reset()sqlite3_finalize()时,或
    • 当在同一参数上再次调用 sqlite3_set_auxdata() 时,或者
    • 在发生内存分配错误时的原始 sqlite3_set_auxdata() 调用期间。

    请特别注意最后一个项目符号。sqlite3_set_auxdata(C,N,P,X) 中的析构函数 X 可能会在 sqlite3_set_auxdata() 接口返回之前立即被调用。因此,sqlite3_set_auxdata() 应该在函数实现接近尾声时调用,并且在调用 sqlite3_set_auxdata() 之后,函数实现不应使用任何 P。

    实际上,元数据保存在函数调用之间,函数参数是编译时常量,包括文字值和参数以及由它们组成的表达式。

    这些接口的 N 参数的值应该是非负的。未来的增强可能会使用负 N 值来定义新的函数缓存行为。

    这些例程必须从运行 SQL 函数的同一线程中调用。


    对堆大小施加限制

    sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
    sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
    

    这些接口对单个进程中所有数据库连接的堆内存量施加了限制。

    sqlite3_soft_heap_limit64() 接口设置和/或查询 SQLite 可以分配的堆内存量的软限制。SQLite 通过在堆内存使用量接近限制时减少页面缓存中保留的页面数,努力将堆内存利用率保持在软堆限制以下。软堆限制是“软”的,因为即使 SQLite 努力保持在限制以下,它也会超过限制而不是生成SQLITE_NOMEM错误。换句话说,软堆限制只是建议性的。

    sqlite3_hard_heap_limit64(N) 接口为将分配的内存量设置了 N 字节的硬上限。sqlite3_hard_heap_limit64(N) 接口类似于 sqlite3_soft_heap_limit64(N) ,只是当达到硬堆限制时内存分配将失败。

    sqlite3_soft_heap_limit64() 和 sqlite3_hard_heap_limit64() 的返回值是调用前堆限制的大小,或者在出现错误时为负值。如果参数 N 为负,则不会对堆限制进行任何更改。因此,堆限制的当前大小可以通过调用 sqlite3_soft_heap_limit64(-1) 或 sqlite3_hard_heap_limit(-1) 来确定。

    将堆限制设置为零会禁用堆限制器机制。

    软堆限制不能大于硬堆限制。如果启用了硬堆限制,并且如果使用大于硬堆限制的 N 值调用 sqlite3_soft_heap_limit(N),则软堆限制将设置为硬堆限制的值。只要启用硬堆限制,就会自动启用软堆限制。当调用sqlite3_hard_heap_limit64(N)时,软堆限制在1..N的范围之外,则软堆限制设置为N。启用硬堆限制时调用sqlite3_soft_heap_limit64(0)使软堆限制等于到硬堆限制。

    还可以使用 PRAGMA soft_heap_limitPRAGMA hard_heap_limit调整内存分配限制。

    如果满足以下一个或多个条件,则当前实现中不会强制执行堆限制:

    SQLite 将强制执行堆限制的情况可能会在 SQLite 的未来版本中发生变化。


    初始化 SQLite 库

    int sqlite3_initialize(void);
    int sqlite3_shutdown(void);
    int sqlite3_os_init(void);
    int sqlite3_os_end(void);
    

    sqlite3_initialize() 例程初始化 SQLite 库。sqlite3_shutdown() 例程释放由 sqlite3_initialize() 分配的任何资源。这些例程旨在帮助嵌入式系统上的进程初始化和关闭。使用 SQLite 的工作站应用程序通常不需要调用这些例程中的任何一个。

    如果在进程的生命周期内第一次调用 sqlite3_initialize(),或者如果它是在调用 sqlite3_shutdown() 之后第一次调用 sqlite3_initialize(),则对 sqlite3_initialize() 的调用是“有效”调用。只有有效调用 sqlite3_initialize() 才能进行任何初始化。所有其他调用都是无害的空操作。

    如果对 sqlite3_shutdown() 的调用是自上次 sqlite3_initialize() 以来对 sqlite3_shutdown() 的第一次调用,则该调用是“有效”调用。只有对 sqlite3_shutdown() 的有效调用才会进行任何取消初始化。所有其他对 sqlite3_shutdown() 的有效调用都是无害的空操作。

    sqlite3_initialize() 接口是线程安全的,但 sqlite3_shutdown() 不是。sqlite3_shutdown() 接口只能从单个线程调用。在调用 sqlite3_shutdown() 之前,必须关闭所有打开的数据库连接,并且必须释放所有其他 SQLite 资源。

    其中,sqlite3_initialize() 将调用 sqlite3_os_init()。同样,sqlite3_shutdown() 将调用 sqlite3_os_end()。

    sqlite3_initialize() 例程在成功时返回SQLITE_OK如果出于某种原因,sqlite3_initialize() 无法初始化库(可能无法分配所需的资源,例如互斥锁),它会返回SQLITE_OK以外的错误代码

    sqlite3_initialize() 例程由许多其他 SQLite 接口在内部调用,因此应用程序通常不需要直接调用 sqlite3_initialize()。例如,sqlite3_open()调用 sqlite3_initialize(),因此如果 SQLite 库尚未初始化,则在调用 sqlite3_open ( ) 时将自动初始化它。但是,如果 SQLite 是使用SQLITE_OMIT_AUTOINIT编译的 编译时选项,则省略对 sqlite3_initialize() 的自动调用,应用程序必须在使用任何其他 SQLite 接口之前直接调用 sqlite3_initialize()。为了获得最大的可移植性,建议应用程序始终在使用任何其他 SQLite 接口之前直接调用 sqlite3_initialize()。SQLite 的未来版本可能需要这个。换句话说,当使用SQLITE_OMIT_AUTOINIT编译 SQLite 时表现出的行为可能会成为 SQLite 未来版本的默认行为。

    sqlite3_os_init() 例程对 SQLite 库进行操作系统特定的初始化。sqlite3_os_end() 例程撤销 sqlite3_os_init() 的效果。这些例程执行的典型任务包括静态资源的分配或释放、全局变量的初始化、设置默认的sqlite3_vfs模块或使用sqlite3_config()设置默认配置

    应用程序不应该直接调用 sqlite3_os_init() 或 sqlite3_os_end()。应用程序应该只调用 sqlite3_initialize() 和 sqlite3_shutdown()。sqlite3_os_init() 接口由sqlite3_initialize() 自动调用,sqlite3_os_end() 由sqlite3_shutdown() 调用。在为 Unix、Windows 或 OS/2 编译时,sqlite3_os_init() 和 sqlite3_os_end() 的适当实现已内置到 SQLite 中。为其他平台构建时 (使用SQLITE_OS_OTHER=1编译时选项),应用程序必须为 sqlite3_os_init() 和 sqlite3_os_end() 提供合适的实现。sqlite3_os_init() 或 sqlite3_os_end() 的应用程序提供的实现必须在成功时返回SQLITE_OK和其他一些失败时的 错误代码。


    SQL 关键字检查

    int sqlite3_keyword_count(void);
    int sqlite3_keyword_name(int,const char**,int*);
    int sqlite3_keyword_check(const char*,int);
    

    这些例程提供对 SQLite 识别的 SQL 语言关键字集的访问。应用程序可以使用这些例程来确定是否需要转义特定标识符(例如,通过用双引号引起来)以免混淆解析器。

    sqlite3_keyword_count() 接口返回 SQLite 理解的不同关键字的数量。

    sqlite3_keyword_name(N,Z,L)接口找到第N个关键字,使*Z指向该关键字,表示为UTF8,并将关键字中的字节数写入*L。*Z 指向的字符串不是以零结尾的。如果 N 在范围内,则 sqlite3_keyword_name(N,Z,L) 例程返回 SQLITE_OK,否则返回 SQLITE_ERROR。如果 Z 或 L 为 NULL 或无效指针,则调用 sqlite3_keyword_name(N,Z,L) 会导致未定义的行为。

    sqlite3_keyword_check(Z,L) 接口检查 Z 指向的 L 字节 UTF8 标识符是否是关键字,如果是则返回非零,否则返回零。

    SQLite 使用的解析器是宽容的。通常可以使用关键字作为标识符,只要这种使用不会导致解析歧义。例如语句“CREATE TABLE BEGIN(REPLACE,PRAGMA,END);” 被 SQLite 接受,并创建一个名为“BEGIN”的新表,其中包含名为“REPLACE”、“PRAGMA”和“END”的三列。然而,最佳做法是避免使用关键字作为标识符。用于避免关键字名称冲突的常用技术包括:

    • 将所有标识符名称放在双引号内。这是转义标识符名称的官方 SQL 方法。
    • 将标识符名称放在 [...] 中。这不是标准的 SQL,但它是 SQL Server 所做的,因此许多程序员都使用这种技术。
    • 每个标识符都以字母“Z”开头,因为没有 SQL 关键字以“Z”开头。
    • 在每个标识符名称的某处包含一个数字。

    请注意,SQLite 可以理解的关键字数量取决于编译时选项。例如,如果使用-DSQLITE_OMIT_VACUUM选项编译 SQLite,则“VACUUM”不是关键字。此外,新的关键字可能会添加到 SQLite 的未来版本中。


    运行时库版本号

    SQLITE_EXTERN const char sqlite3_version[];
    const char *sqlite3_libversion(void);
    const char *sqlite3_sourceid(void);
    int sqlite3_libversion_number(void);
    

    这些接口提供与SQLITE_VERSIONSQLITE_VERSION_NUMBERSQLITE_SOURCE_ID C 预处理器宏 相同的信息,但与库而不是头文件相关联。谨慎的程序员可能会在他们的应用程序中包含 assert() 语句,以验证这些接口返回的值是否与标头中的宏匹配,从而确保使用匹配的库和头文件编译应用程序。

    assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
    assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
    assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
    

    sqlite3_version[] 字符串常量包含SQLITE_VERSION 宏的文本。sqlite3_libversion() 函数返回一个指向 sqlite3_version[] 字符串常量的指针。sqlite3_libversion() 函数是为在 DLL 中使用而提供的,因为 DLL 用户通常无法直接访问 DLL 中的字符串常量。sqlite3_libversion_number() 函数返回一个等于 SQLITE_VERSION_NUMBER的整数。sqlite3_sourceid() 函数返回一个指向字符串常量的指针,该常量的值与 SQLITE_SOURCE_ID C 预处理器宏相同。除非 SQLite 是使用合并的编辑副本构建的,否则散列的最后四个字符可能与SQLITE_SOURCE_ID不同.

    另请参阅:sqlite_version()sqlite_source_id()


    内存分配器统计

    sqlite3_int64 sqlite3_memory_used(void);
    sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
    

    SQLite 提供这两个接口来报告sqlite3_malloc()sqlite3_free()sqlite3_realloc() 例程的状态,它们构成了内置的内存分配子系统。

    sqlite3_memory_used()例程返回当前未完成的内存字节数(分配但未释放)。sqlite3_memory_highwater()例程返回自上次重置高水位线以来sqlite3_memory_used()最大值。sqlite3_memory_used()sqlite3_memory_highwater()返回的值包括 SQLite 在其sqlite3_malloc()实现中添加的任何开销,但不包括sqlite3_malloc()可能调用的任何底层系统库例程添加的开销。

    当且仅当 sqlite3_memory_highwater()的参数为真时,内存高水位线才会重置为 sqlite3_memory_used()的当前值。sqlite3_memory_highwater(1)返回的值是重置前的高水位线。


    格式化字符串打印函数

    char *sqlite3_mprintf(const char*,...);
    char *sqlite3_vmprintf(const char*, va_list);
    char *sqlite3_snprintf(int,char*,const char*, ...);
    char *sqlite3_vsnprintf(int,char*,const char*, va_list);
    

    这些例程与标准 C 库中的“printf()”函数族类似。这些例程理解标准库 printf() 中的大多数常见格式化选项以及一些额外的非标准格式(%q%Q%w%z)。有关详细信息,请参阅内置的 printf()文档。

    sqlite3_mprintf() 和 sqlite3_vmprintf() 例程将它们的结果写入从sqlite3_malloc64()获得的内存中。这两个例程返回的字符串应该由sqlite3_free()释放。如果sqlite3_malloc64()无法分配足够的内存来保存结果字符串,这两个例程都会返回 NULL 指针。

    sqlite3_snprintf() 例程类似于标准 C 库中的“snprintf()”。结果写入作为第二个参数提供的缓冲区,其大小由第一个参数指定。请注意,前两个参数的顺序与 snprintf() 相反。这是一个历史事故,如果不破坏向后兼容性就无法修复。另请注意,sqlite3_snprintf() 返回指向其缓冲区的指针,而不是实际写入缓冲区的字符数。我们承认写入的字符数将是一个更有用的返回值,但我们现在不能在不破坏兼容性的情况下更改 sqlite3_snprintf() 的实现。

    只要缓冲区大小大于零,sqlite3_snprintf() 就保证缓冲区始终以零终止。第一个参数“n”是缓冲区的总大小,包括零终止符的空间。所以能完整写出的最长字符串将是n-1个字符。

    sqlite3_vsnprintf() 例程是 sqlite3_snprintf() 的可变参数版本。

    另请参阅: 内置 printf()printf() SQL 函数


    互斥锁

    sqlite3_mutex *sqlite3_mutex_alloc(int);
    void sqlite3_mutex_free(sqlite3_mutex*);
    void sqlite3_mutex_enter(sqlite3_mutex*);
    int sqlite3_mutex_try(sqlite3_mutex*);
    void sqlite3_mutex_leave(sqlite3_mutex*);
    

    SQLite 核心使用这些例程进行线程同步。尽管它们旨在供 SQLite 内部使用,但允许链接到 SQLite 的代码使用这些例程中的任何一个。

    SQLite 源代码包含这些互斥例程的多个实现。在编译时自动选择适当的实现。SQLite 核心中提供了以下实现:

    • SQLITE_MUTEX_PTHREADS
    • SQLITE_MUTEX_W32
    • SQLITE_MUTEX_NOOP

    SQLITE_MUTEX_NOOP 实现是一组没有真正锁定的例程,适用于单线程应用程序。SQLITE_MUTEX_PTHREADS 和 SQLITE_MUTEX_W32 实现适用于 Unix 和 Windows。

    如果使用定义的 SQLITE_MUTEX_APPDEF 预处理器宏(使用“-DSQLITE_MUTEX_APPDEF=1”)编译 SQLite,则库中不包含互斥实现。在这种情况下,应用程序必须 在调用 sqlite3_initialize() 或任何其他调用 sqlite3_initialize() 的公共 sqlite3_ 函数之前使用 sqlite3_config() 函数的SQLITE_CONFIG_MUTEX选项提供自定义互斥实现。

    sqlite3_mutex_alloc() 例程分配一个新的互斥锁并返回指向它的指针。如果无法分配请求的互斥体,sqlite3_mutex_alloc() 例程返回 NULL。sqlite3_mutex_alloc() 的参数必须是这些整数常量之一:

    • SQLITE_MUTEX_FAST
    • SQLITE_MUTEX_RECURSIVE
    • SQLITE_MUTEX_STATIC_MAIN
    • SQLITE_MUTEX_STATIC_MEM
    • SQLITE_MUTEX_STATIC_OPEN
    • SQLITE_MUTEX_STATIC_PRNG
    • SQLITE_MUTEX_STATIC_LRU
    • SQLITE_MUTEX_STATIC_PMEM
    • SQLITE_MUTEX_STATIC_APP1
    • SQLITE_MUTEX_STATIC_APP2
    • SQLITE_MUTEX_STATIC_APP3
    • SQLITE_MUTEX_STATIC_VFS1
    • SQLITE_MUTEX_STATIC_VFS2
    • SQLITE_MUTEX_STATIC_VFS3

    前两个常量(SQLITE_MUTEX_FAST 和 SQLITE_MUTEX_RECURSIVE)导致 sqlite3_mutex_alloc() 创建一个新的互斥锁。当使用 SQLITE_MUTEX_RECURSIVE 时,新的互斥锁是递归的,但当使用 SQLITE_MUTEX_FAST 时,则不一定如此。互斥量实现不需要区分 SQLITE_MUTEX_RECURSIVE 和 SQLITE_MUTEX_FAST 如果不想的话。SQLite 只会在确实需要递归互斥量的情况下请求递归互斥量。如果主机平台上有更快的非递归互斥体实现,互斥体子系统可能会返回这样的互斥体以响应 SQLITE_MUTEX_FAST。

    sqlite3_mutex_alloc() 的其他允许参数(除 SQLITE_MUTEX_FAST 和 SQLITE_MUTEX_RECURSIVE 之外的任何参数)每个都返回一个指向静态预先存在的互斥体的指针。当前版本的 SQLite 使用了九个静态互斥锁。SQLite 的未来版本可能会添加额外的静态互斥锁。静态互斥量仅供 SQLite 内部使用。使用 SQLite 互斥锁的应用程序应该只使用由 SQLITE_MUTEX_FAST 或 SQLITE_MUTEX_RECURSIVE 返回的动态互斥锁。

    请注意,如果使用其中一个动态互斥参数(SQLITE_MUTEX_FAST 或 SQLITE_MUTEX_RECURSIVE),则 sqlite3_mutex_alloc() 会在每次调用时返回不同的互斥。对于静态互斥锁类型,每次调用具有相同类型编号时都会返回相同的互斥锁。

    sqlite3_mutex_free() 例程释放先前分配的动态互斥量。尝试解除分配静态互斥会导致未定义的行为。

    sqlite3_mutex_enter() 和 sqlite3_mutex_try() 例程尝试进入互斥锁。如果另一个线程已经在互斥体中,sqlite3_mutex_enter() 将阻塞并且 sqlite3_mutex_try() 将返回 SQLITE_BUSY。sqlite3_mutex_try() 接口 在成功进入时返回SQLITE_OK 。使用 SQLITE_MUTEX_RECURSIVE 创建的互斥量可以由同一个线程多次输入。在这种情况下,互斥量必须在另一个线程进入之前退出相同的次数。如果同一线程多次尝试进入除 SQLITE_MUTEX_RECURSIVE 之外的任何互斥量,则行为未定义。

    有些系统(例如Windows 95)不支持sqlite3_mutex_try()实现的操作。在那些系统上,sqlite3_mutex_try() 将始终返回 SQLITE_BUSY。SQLite 核心只使用 sqlite3_mutex_try() 作为优化,所以这是可以接受的行为。

    sqlite3_mutex_leave() 例程退出先前由同一线程输入的互斥量。如果调用线程当前未输入互斥量或当前未分配互斥量,则行为未定义。

    如果 sqlite3_mutex_enter()、sqlite3_mutex_try() 或 sqlite3_mutex_leave() 的参数是 NULL 指针,则所有三个例程都表现为空操作。

    另见:sqlite3_mutex_held()sqlite3_mutex_notheld()


    互斥量验证例程

    #ifndef NDEBUG
    int sqlite3_mutex_held(sqlite3_mutex*);
    int sqlite3_mutex_notheld(sqlite3_mutex*);
    #endif
    

    sqlite3_mutex_held() 和 sqlite3_mutex_notheld() 例程旨在用于 assert() 语句内部。SQLite 核心从不使用这些例程,除了在 assert() 内部,建议应用程序遵循核心的领导。SQLite 核心仅在使用 SQLITE_DEBUG 标志编译时提供这些例程的实现。如果定义了 SQLITE_DEBUG 并且未定义 NDEBUG,则仅需要外部互斥实现来提供这些例程。

    如果它们的参数中的互斥锁分别被调用线程持有或未持有,这些例程应返回 true。

    实现不需要提供这些例程的实际工作版本。如果实现不提供这些例程的工作版本,它至少应该提供始终返回 true 的存根,这样就不会出现虚假的断言失败。

    如果 sqlite3_mutex_held() 的参数是一个 NULL 指针,那么例程应该返回 1。这似乎违反直觉,因为很明显,如果互斥量不存在,则无法保持。但是互斥锁不存在的原因是因为构建没有使用互斥锁。而且我们不希望包含对 sqlite3_mutex_held() 调用的 assert() 失败,因此返回非零值是合适的做法。当给定 NULL 指针时,sqlite3_mutex_notheld() 接口也应该返回 1。


    打开一个新的数据库连接

    int sqlite3_open(
      const char *filename,   /* Database filename (UTF-8) */
      sqlite3 **ppDb          /* OUT: SQLite db handle */
    );
    int sqlite3_open16(
      const void *filename,   /* Database filename (UTF-16) */
      sqlite3 **ppDb          /* OUT: SQLite db handle */
    );
    int sqlite3_open_v2(
      const char *filename,   /* Database filename (UTF-8) */
      sqlite3 **ppDb,         /* OUT: SQLite db handle */
      int flags,              /* Flags */
      const char *zVfs        /* Name of VFS module to use */
    );
    

    这些例程打开由文件名参数指定的 SQLite 数据库文件。文件名参数被解释为 sqlite3_open() 和 sqlite3_open_v2() 的 UTF-8 以及 sqlite3_open16() 的本机字节顺序中的 UTF-16。数据库连接句柄通常在 *ppDb 中返回,即使发生错误也是如此。唯一的例外是,如果 SQLite 无法分配内存来保存sqlite3对象,则会将 NULL 写入 *ppDb 而不是指向sqlite3 对象的指针。如果数据库成功打开(和/或创建),则 返回SQLITE_OK否则返回错误代码sqlite3_errmsg ( )sqlite3_errmsg16()例程可用于在任何 sqlite3_open() 例程失败后获取错误的英语描述。

    对于使用 sqlite3_open() 或 sqlite3_open_v2() 创建的数据库,默认编码将为 UTF-8。使用 sqlite3_open16() 创建的数据库的默认编码将是本机字节顺序的 UTF-16。

    无论打开时是否发生错误,与数据库连接句柄关联的资源都应在不再需要时通过将其传递给sqlite3_close()来释放。

    sqlite3_open_v2() 接口的工作方式与 sqlite3_open() 类似,只是它接受两个附加参数以对新数据库连接进行额外控制。sqlite3_open_v2() 的标志参数必须至少包括以下三个标志组合之一:

    SQLITE_OPEN_READONLY
    数据库以只读模式打开。如果数据库尚不存在,则返回错误。

    SQLITE_OPEN_READWRITE
    如果可能,打开数据库以进行读写,或者仅在文件被操作系统写保护时才进行读取。在任何一种情况下,数据库都必须已经存在,否则将返回错误。

    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
    数据库以读写方式打开,如果不存在则创建。这是始终用于 sqlite3_open() 和 sqlite3_open16() 的行为。

    除了必需的标志外,还支持以下可选标志:

    SQLITE_OPEN_URI
    如果设置了此标志,则文件名可以解释为 URI。

    SQLITE_OPEN_MEMORY
    该数据库将作为内存数据库打开。如果启用了共享缓存模式,则数据库由“文件名”参数命名,用于缓存共享,但“文件名”将被忽略。

    SQLITE_OPEN_NOMUTEX
    新的数据库连接将使用“多线程” 线程模式这意味着允许单独的线程同时使用 SQLite,只要每个线程使用不同的数据库连接即可。

    SQLITE_OPEN_FULLMUTEX
    新的数据库连接将使用“序列化” 线程模式这意味着多个线程可以安全地同时尝试使用同一个数据库连接。(互斥量会阻止任何实际的并发,但在这种模式下尝试并没有坏处。)

    SQLITE_OPEN_SHAREDCACHE
    数据库打开时启用共享缓存,覆盖sqlite3_enable_shared_cache()提供的默认共享缓存设置

    SQLITE_OPEN_PRIVATECACHE
    数据库打开共享缓存禁用,覆盖sqlite3_enable_shared_cache()提供的默认共享缓存设置

    SQLITE_OPEN_EXRESCODE
    数据库连接以“扩展结果代码模式”出现。换句话说,数据库的行为有 if sqlite3_extended_result_codes(db,1)一旦连接被创建就调用数据库连接。除了设置扩展结果代码模式外,该标志还导致sqlite3_open_v2() 返回扩展结果代码。

    SQLITE_OPEN_NOFOLLOW
    数据库文件名不允许是符号链接

    如果 sqlite3_open_v2() 的第三个参数不是上面显示的必需组合之一,可以选择与其他 SQLITE_OPEN_* 位组合, 则行为未定义。SQLite 的历史版本已经默默地忽略了 sqlite3_open_v2() 的 flags 参数中的多余位,但是这种行为可能不会延续到 SQLite 的未来版本中,因此应用程序不应依赖它。特别注意 SQLITE_OPEN_EXCLUSIVE 标志是 sqlite3_open_v2() 的空操作。如果数据库已经存在,SQLITE_OPEN_EXCLUSIVE *不会*导致打开失败。SQLITE_OPEN_EXCLUSIVE 标志仅供VFS 接口使用,而不供 sqlite3_open_v2() 使用。

    sqlite3_open_v2() 的第四个参数是 sqlite3_vfs对象的名称,它定义了新数据库连接应该使用的操作系统接口。如果第四个参数是 NULL 指针,则使用默认的sqlite3_vfs对象。

    如果文件名为“:memory:”,则会为连接创建一个私有的临时内存数据库。当数据库连接关闭时,这个内存数据库将消失。SQLite 的未来版本可能会使用以“:”字符开头的其他特殊文件名。建议当数据库文件名确实以“:”字符开头时,您应该在文件名前加上路径名(例如“./”)以避免歧义。

    如果文件名是空字符串,则会创建一个私有的临时磁盘数据库。一旦数据库连接关闭,这个私有数据库就会自动删除。

    URI 文件名

    如果启用URI 文件名解释,并且文件名参数以“file:”开头,则文件名被解释为 URI。如果在 sqlite3_open_v2() 的第三个参数中设置了SQLITE_OPEN_URI标志,或者如果使用带有sqlite3_config()方法的SQLITE_CONFIG_URI选项 或通过SQLITE_USE_URI编译时选项全局启用它,则启用 URI 文件名解释。URI 文件名解释默认关闭,但 SQLite 的未来版本可能默认启用 URI 文件名解释。有关其他信息,请参阅“ URI 文件名”。

    URI 文件名根据 RFC 3986 进行解析。如果 URI 包含权限,则它必须是空字符串或字符串“localhost”。如果 authority 不是空字符串或“localhost”,则向调用者返回错误。URI 的片段组件(如果存在)将被忽略。

    SQLite 使用 URI 的路径部分作为包含数据库的磁盘文件的名称。如果路径以“/”字符开头,则它被解释为绝对路径。如果路径不以“/”开头(意味着授权部分从 URI 中省略),则该路径被解释为相对路径。在 Windows 上,绝对路径的第一个组成部分是驱动器说明(例如“C:”​​)。

    URI 的查询组件可能包含由 SQLite 本身或自定义 VFS 实现解释的参数。SQLite 及其内置的VFSes解释以下查询参数:

    • vfs:“vfs”参数可用于指定提供操作系统接口的 VFS 对象的名称,该接口应该用于访问磁盘上的数据库文件。如果此选项设置为空字符串,则使用默认 VFS 对象。指定未知的 VFS 是错误的。如果使用 sqlite3_open_v2() 并且存在 vfs 选项,则该选项指定的 VFS 优先于作为第四个参数传递给 sqlite3_open_v2() 的值。

    • 模式:模式参数可以设置为“ro”、“rw”、“rwc”或“memory”。试图将其设置为任何其他值都是错误的。如果指定了“ro”,那么数据库将以只读方式打开,就像在 sqlite3_open_v2() 的第三个参数中设置了SQLITE_OPEN_READONLY标志一样。如果 mode 选项设置为“rw”,则打开数据库进行读写(但不是创建)访问,就好像设置了 SQLITE_OPEN_READWRITE(但不是 SQLITE_OPEN_CREATE)一样。值“rwc”相当于同时设置 SQLITE_OPEN_READWRITE 和 SQLITE_OPEN_CREATE。如果模式选项设置为“内存”,那么一个纯内存数据库使用从不从磁盘读取或写入的。为 mode 参数指定一个比第三个参数中传递给 sqlite3_open_v2() 的标志指定的限制更少的值是错误的。

    • 缓存:缓存参数可以设置为“共享”或“私有”。将其设置为“共享”相当于在传递给 sqlite3_open_v2() 的标志参数中设置 SQLITE_OPEN_SHAREDCACHE 位。将缓存参数设置为“private”等同于设置 SQLITE_OPEN_PRIVATECACHE 位。如果使用 sqlite3_open_v2() 并且 URI 文件名中存在“缓存”参数,则其值将覆盖通过设置 SQLITE_OPEN_PRIVATECACHE 或 SQLITE_OPEN_SHAREDCACHE 标志请求的任何行为。

    • psow:psow 参数指示 powersafe 覆盖属性是否适用于数据库文件所在的存储介质。

    • nolock:nolock 参数是一个布尔查询参数,如果设置该参数,则在回滚日志模式下禁用文件锁定。这对于访问不支持锁定的文件系统上的数据库很有用。警告:如果两个或多个进程写入同一个数据库并且其中任何一个进程使用 nolock=1,则可能会导致数据库损坏。

    • immutable:immutable 参数是一个布尔查询参数,表示数据库文件存储在只读介质上。当设置了 immutable 时,SQLite 假定数据库文件无法更改,即使是具有更高权限的进程,因此数据库以只读方式打开,所有锁定和更改检测都被禁用。警告:在实际上发生变化的数据库文件上设置不可变属性可能会导致不正确的查询结果和/或SQLITE_CORRUPT错误。另请参阅:SQLITE_IOCAP_IMMUTABLE

    在 URI 的查询组件中指定未知参数不是错误。SQLite 的未来版本可能会理解额外的查询参数。有关其他信息,请参阅“对 SQLite 具有特殊含义的查询参数”。

    URI 文件名示例

    URI filenames Results
    file:data.db Open the file "data.db" in the current directory.
    file:/home/fred/data.db
    file:///home/fred/data.db
    file://localhost/home/fred/data.db
    Open the database file "/home/fred/data.db".
    file://darkstar/home/fred/data.db An error. "darkstar" is not a recognized authority.
    file:///C:/Documents%20and%20Settings/fred/Desktop/data.db Windows only: Open the file "data.db" on fred's desktop on drive C:. Note that the %20 escaping in this example is not strictly necessary - space characters can be used literally in URI filenames.
    file:data.db?mode=ro&cache=private Open file "data.db" in the current directory for read-only access. Regardless of whether or not shared-cache mode is enabled by default, use a private cache.
    file:/home/fred/data.db?vfs=unix-dotfile Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" that uses dot-files in place of posix advisory locking.
    file:data.db?mode=readonly An error. "readonly" is not a valid option for the "mode" parameter. Use "ro" instead: "file:data.db?mode=ro".

    URI 的路径和查询组件支持 URI 十六进制转义序列 (%HH)。十六进制转义序列由一个百分号 - “%” - 后跟两个指定八位位组值的十六进制数字组成。在解释 URI 文件名的路径或查询组件之前,它们使用 UTF-8 编码,所有十六进制转义序列替换为包含相应八位组的单个字节。如果此过程生成无效的 UTF-8 编码,则结果未定义。

    Windows 用户注意: 用于 sqlite3_open() 和 sqlite3_open_v2() 的文件名参数的编码必须是 UTF-8,而不是当前定义的任何代码页。包含国际字符的文件名在传递到 sqlite3_open() 或 sqlite3_open_v2() 之前必须转换为 UTF-8。

    Windows 运行时用户请注意: 必须在调用 sqlite3_open() 或 sqlite3_open_v2() 之前设置临时目录。否则,需要使用临时文件的各种功能可能会失败。

    另见:sqlite3_temp_directory


    预更新挂钩。

    #if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
    void *sqlite3_preupdate_hook(
      sqlite3 *db,
      void(*xPreUpdate)(
        void *pCtx,                   /* Copy of third arg to preupdate_hook() */
        sqlite3 *db,                  /* Database handle */
        int op,                       /* SQLITE_UPDATE, DELETE or INSERT */
        char const *zDb,              /* Database name */
        char const *zName,            /* Table name */
        sqlite3_int64 iKey1,          /* Rowid of row about to be deleted/updated */
        sqlite3_int64 iKey2           /* New rowid value (for a rowid UPDATE) */
      ),
      void*
    );
    int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
    int sqlite3_preupdate_count(sqlite3 *);
    int sqlite3_preupdate_depth(sqlite3 *);
    int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
    int sqlite3_preupdate_blobwrite(sqlite3 *);
    #endif
    

    这些接口仅在使用 SQLITE_ENABLE_PREUPDATE_HOOK编译时选项编译 SQLite 时可用。

    sqlite3_preupdate_hook()接口注册一个回调函数,该函数在数据库表上的每个INSERTUPDATEDELETE操作之前调用。一次最多可以在单个 数据库连接上注册一个预更新挂钩;每次调用sqlite3_preupdate_hook()都会覆盖之前的设置。 通过使用 NULL 指针作为第二个参数调用sqlite3_preupdate_hook()来禁用预更新挂钩。sqlite3_preupdate_hook()的第三个参数作为第一个参数传递给回调。

    preupdate 挂钩仅在对真实数据库表进行更改时触发;不会调用 preupdate 挂钩来更改虚拟表或系统表,如 sqlite_sequence 或 sqlite_stat1。

    预更新回调的第二个参数是指向注册预更新挂钩的数据库连接的指针。preupdate 回调的第三个参数是常量 SQLITE_INSERTSQLITE_DELETESQLITE_UPDATE 之一,用于标识即将发生的更新操作的类型。preupdate 回调的第四个参数是正在修改的数据库连接中的数据库名称。这对于主数据库是“main”,对于 TEMP 表是“temp”,或者是附加数据库的ATTACH语句中 AS 关键字后给出的名称。预更新回调的第五个参数是正在修改的表的名称。

    对于rowid 表的 UPDATE 或 DELETE 操作,传递给 preupdate 回调的第六个参数是被修改或删除的行的初始rowid对于对 rowid 表的 INSERT 操作,或对 WITHOUT ROWID 表的任何操作,第六个参数的值是未定义的。对于 rowid 表的 INSERT 或 UPDATE,第七个参数是被插入或更新的行的最终 rowid 值。传递给回调函数的第七个参数的值未针对 WITHOUT ROWID 表的操作或 rowid 表的 DELETE 操作定义。

    sqlite3_preupdate_old()sqlite3_preupdate_new()sqlite3_preupdate_count()sqlite3_preupdate_depth ()接口提供了有关预更新事件的附加信息。这些例程只能从预更新回调中调用。从预更新回调外部或使用 不同于提供给预更新回调的数据库连接指针调用这些例程中的任何例程会导致未定义且可能不受欢迎的行为。

    sqlite3_preupdate_count(D)接口返回正在插入、更新或删除的行中的列数

    sqlite3_preupdate_old(D,N,P)接口向 P 写入一个指针,该指针指向保护的 sqlite3_value,该值包含更新前表行第 N 列的值。N 参数必须介于 0 和比列数小 1 之间,否则行为将是未定义的。这只能在 SQLITE_UPDATE 和 SQLITE_DELETE 预更新回调中使用;如果它被 SQLITE_INSERT 回调使用,则行为未定义。当 preupdate 回调返回时,P 指向sqlite3_value将被销毁。

    sqlite3_preupdate_new(D,N,P)接口向 P 写入一个指针,该指针指向保护的 sqlite3_value,该值包含表行更新后的第 N 列的值。N 参数必须介于 0 和比列数小 1 之间,否则行为将是未定义的。这只能在 SQLITE_INSERT 和 SQLITE_UPDATE 预更新回调中使用;如果它被 SQLITE_DELETE 回调使用,则行为未定义。当 preupdate 回调返回时,P 指向sqlite3_value将被销毁。

    如果作为直接插入、更新或删除操作的结果调用预更新回调,则sqlite3_preupdate_depth(D)接口返回 0;或 1 表示由顶级触发器调用的插入、更新或删除;或 2 表示由顶级触发器调用的触发器引起的更改;等等。

    sqlite3_blob_write() API 用于更新 blob 列时,会使用 SQLITE_DELETE 调用预更新挂钩。这是因为在这种情况下,新值不可用。在这种情况下,当使用 op==SQLITE_DELETE 进行的回调实际上是使用 sqlite3_blob_write() API 进行的写入时,sqlite3_preupdate_blobwrite()返回正在写入的列的索引。在其他情况下,由于某些其他原因(包括常规 DELETE)调用预更新挂钩,sqlite3_preupdate_blobwrite() 返回 -1。

    另见: sqlite3_update_hook()


    跟踪和分析功能

    void *sqlite3_trace(sqlite3*,
       void(*xTrace)(void*,const char*), void*);
    void *sqlite3_profile(sqlite3*,
       void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
    

    这些例程已弃用。使用sqlite3_trace_v2()接口而不是此处描述的例程。

    这些例程注册回调函数,可用于跟踪和分析 SQL 语句的执行。

    sqlite3_trace() 注册的回调函数在 sqlite3_step( )运行 SQL 语句时的不同时间被调用sqlite3_trace() 回调在语句首次开始执行时使用 SQL 语句文本的 UTF-8 呈现来调用。当输入每个触发的子程序时,可能会发生其他 sqlite3_trace() 回调。触发器的回调包含标识触发器的 UTF-8 SQL 注释。

    SQLITE_TRACE_SIZE_LIMIT编译选项可用于限制sqlite3_trace() 输出中绑定参数扩展的长度。

    由 sqlite3_profile() 注册的回调函数在每个 SQL 语句完成时被调用。配置文件回调包含原始语句文本和该语句运行多长时间的挂钟时间估计。配置文件回调时间以纳秒为单位,但是当前的实现只能以毫秒为单位,因此时间中的最低六位数字无意义。未来版本的 SQLite 可能会提供更好的分析器回调解决方案。调用sqlite3_trace()sqlite3_trace_v2()将取消配置文件回调。


    设置 SQL 函数的结果

    void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
    void sqlite3_result_blob64(sqlite3_context*,const void*,
                               sqlite3_uint64,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_error_toobig(sqlite3_context*);
    void sqlite3_result_error_nomem(sqlite3_context*);
    void sqlite3_result_error_code(sqlite3_context*, int);
    void sqlite3_result_int(sqlite3_context*, int);
    void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
    void sqlite3_result_null(sqlite3_context*);
    void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
    void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
                               void(*)(void*), unsigned char encoding);
    void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
    void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
    void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
    void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
    void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
    void sqlite3_result_zeroblob(sqlite3_context*, int n);
    int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
    

    这些例程由实现 SQL 函数和聚合的 xFunc 或 xFinal 回调使用。有关更多信息,请参阅 sqlite3_create_function()sqlite3_create_function16()

    这些函数的工作方式非常类似于用于将值绑定到预准备语句中的主机参数的参数绑定函数系列。有关其他信息,请参阅SQL 参数文档。

    sqlite3_result_blob() 接口将应用程序定义函数的结果设置为 BLOB,其内容由第二个参数指向,长度为 N 字节,其中 N 是第三个参数。

    sqlite3_result_zeroblob(C,N) 和 sqlite3_result_zeroblob64(C,N) 接口将应用程序定义函数的结果设置为包含所有零字节和 N 字节大小的 BLOB。

    sqlite3_result_double() 接口将应用程序定义函数的结果设置为其第二个参数指定的浮点值。

    sqlite3_result_error() 和 sqlite3_result_error16() 函数导致实现的 SQL 函数抛出异常。SQLite 使用 sqlite3_result_error() 或 sqlite3_result_error16() 的第二个参数指向的字符串作为错误消息的文本。SQLite 将来自 sqlite3_result_error() 的错误消息字符串解释为 UTF-8。SQLite 使用与 sqlite3_bind_text16() 相同的字节顺序确定规则sqlite3_result_error16()中的字符串解释为 UTF-16. 如果 sqlite3_result_error() 或 sqlite3_result_error16() 的第三个参数为负数,则 SQLite 将第一个零字符之前的所有文本作为错误消息。如果 sqlite3_result_error() 或 sqlite3_result_error16() 的第三个参数是非负数,则 SQLite 从第二个参数中获取那么多字节(不是字符)作为错误消息。sqlite3_result_error() 和 sqlite3_result_error16() 例程在返回之前制作错误消息文本的私有副本。因此,调用函数可以在文本返回后释放或修改文本而不会造成伤害。sqlite3_result_error_code() 函数更改 SQLite 由于函数错误而返回的错误代码。默认情况下,错误代码是 SQLITE_ERROR。

    sqlite3_result_error_toobig() 接口导致 SQLite 抛出一个错误,表明字符串或 BLOB 太长而无法表示。

    sqlite3_result_error_nomem() 接口导致 SQLite 抛出一个错误,指示内存分配失败。

    sqlite3_result_int() 接口将应用程序定义函数的返回值设置为第二个参数中给出的 32 位有符号整数值。sqlite3_result_int64() 接口将应用程序定义函数的返回值设置为第二个参数中给出的 64 位有符号整数值。

    sqlite3_result_null() 接口将应用程序定义函数的返回值设置为 NULL。

    sqlite3_result_text()、sqlite3_result_text16()、sqlite3_result_text16le() 和 sqlite3_result_text16be() 接口将应用程序定义函数的返回值设置为文本字符串,表示为 UTF-8、UTF-16 本地字节顺序、UTF- 16 little endian,或 UTF-16 big endian,分别。sqlite3_result_text64() 接口将应用程序定义函数的返回值设置为第五个(也是最后一个)参数指定编码的文本字符串,该参数必须是SQLITE_UTF8SQLITE_UTF16SQLITE_UTF16BESQLITE_UTF16LE 之一. SQLite 从 sqlite3_result_text* 接口的第二个参数中获取来自应用程序的文本结果。如果 sqlite3_result_text* 接口的第三个参数为负,则 SQLite 从第二个参数到第一个零字符获取结果文本。如果 sqlite3_result_text* 接口的第三个参数是非负数,那么第二个参数指向的文本的字节数(不是字符数)将作为应用程序定义的函数结果。如果第三个参数是非负数,那么它必须是 NUL 终止符出现的字符串中的字节偏移量(如果字符串以 NUL 终止)。如果任何 NUL 字符出现在字符串中的字节偏移量小于第三个参数的值,那么生成的字符串将包含嵌入的 NUL,并且对具有嵌入的 NUL 的字符串进行运算的表达式的结果是未定义的。如果 sqlite3_result_text* 接口或 sqlite3_result_blob 的第 4 个参数是非 NULL 指针,则 SQLite 在使用完该结果后调用该函数作为文本或 BLOB 结果的析构函数。如果 sqlite3_result_text* 接口或 sqlite3_result_blob 的第 4 个参数是特殊常量 SQLITE_STATIC,则 SQLite 假定文本或 BLOB 结果在常量空间中,并且不会复制参数的内容,也不会在内容上调用析构函数完成使用该结果。sqlite3_malloc()在它返回之前。

    对于sqlite3_result_text16()、sqlite3_result_text16le()和sqlite3_result_text16be()例程,以及对于sqlite3_result_text64(),当编码不是UTF8时,如果输入的UTF16以字节顺序标记(BOM,U+FEFF)开头,那么BOM是从字符串中删除,字符串的其余部分将根据 BOM 指定的字节顺序进行解释。文本开头的 BOM 指定的字节顺序覆盖接口过程指定的字节顺序。因此,例如,如果调用 sqlite3_result_text16le() 并使用以字节 0xfe、0xff(大端字节顺序标记)开头的文本,则输入的前两个字节将被跳过,其余输入将被解释为 UTF16BE 文本。

    对于 sqlite3_result_text16()、sqlite3_result_text16be()、sqlite3_result_text16le() 和 sqlite3_result_text64() 例程的 UTF16 输入文本,如果文本包含无效的 UTF16 字符,则无效字符可能会转换为 unicode 替换字符 U+FFFD。

    sqlite3_result_value() 接口将应用程序定义函数的结果设置为第二个参数指定的 不受保护的 sqlite3_value对象的副本。sqlite3_result_value() 接口制作 sqlite3_value 的副本, 以便参数中指定的sqlite3_value可以在 sqlite3_result_value() 返回后无害地更改或释放。在需要不受保护的 sqlite3_value 对象的地方,可以始终使用 受保护的sqlite3_value对象,因此任何一种sqlite3_value对象都可以与此接口一起使用。

    sqlite3_result_pointer(C,P,T,D) 接口将结果设置为 SQL NULL 值,就像sqlite3_result_null(C)一样,除了它还将宿主语言指针 P 或类型 T 与该 NULL 值相关联,以便指针可以 使用sqlite3_value_pointer()在应用程序定义的 SQL 函数中检索。如果 D 参数不为 NULL,则它是指向 P 参数的析构函数的指针。当 SQLite 以 P 结束时,SQLite 以 P 作为其唯一参数调用 D。T 参数应该是静态字符串,最好是字符串文字。sqlite3_result_pointer() 例程是为 SQLite 3.20.0 添加的指针传递接口的一部分。

    如果这些例程是从与包含接收sqlite3_context指针的应用程序定义函数的线程不同的线程中调用的,则结果是未定义的。


    SQLite 运行时状态

    int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
    int sqlite3_status64(
      int op,
      sqlite3_int64 *pCurrent,
      sqlite3_int64 *pHighwater,
      int resetFlag
    );
    

    这些接口用于检索有关 SQLite 性能的运行时状态信息,并可选择重置各种高水位标记。第一个参数是要测量的特定参数的整数代码。公认的整数代码的形式为SQLITE_STATUS_...参数的当前值返回到 *pCurrent。*pHighwater 返回最高记录值。如果 resetFlag 为真,则在写入 *pHighwater 后重置最高记录值。有些参数不记录最高值。对于这些参数,没有任何内容写入 *pHighwater 并且 resetFlag 被忽略。其他参数只记录高水位线,不记录当前值。对于后面这些参数,没有任何内容写入 *pCurrent。

    sqlite3_status() 和 sqlite3_status64() 例程在成功时返回 SQLITE_OK,在失败时返回非零错误代码

    如果当前值或高水位线太大而无法用 32 位整数表示,则 sqlite3_status() 返回的值是未定义的。

    另见:sqlite3_db_status()


    向动态字符串添加内容

    void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
    void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
    void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
    void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
    void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
    void sqlite3_str_reset(sqlite3_str*);
    

    这些接口将内容添加到先前从sqlite3_str_new()获得的 sqlite3_str 对象。

    sqlite3_str_appendf(X , F,...)sqlite3_str_vappendf(X,F,V)接口使用 SQLite 的内置 printf 功能将格式化文本附加到 sqlite3_str对象 X的末尾。

    sqlite3_str_append(X,S,N)方法恰好将字符串 S 中的 N 个字节附加到sqlite3_str对象 X 的末尾。N 必须是非负数。S 必须包含至少 N 个非零字节的内容。要完整地附加一个以零结尾的字符串,请改用sqlite3_str_appendall() 方法。

    sqlite3_str_appendall(X,S)方法将以零结尾的字符串 S的完整内容附加到sqlite3_str对象 X的末尾。

    sqlite3_str_appendchar(X,N,C)方法将单字节字符 C 的 N 个副本附加到 sqlite3_str 对象 X 的末尾例如,可以使用此方法来添加空格缩进。

    sqlite3_str_reset(X)方法将sqlite3_str对象 X 中正在构造的字符串重置为零字节长度。

    这些方法不返回结果代码。如果发生错误,该事实将记录在sqlite3_str对象中,并且可以通过随后调用sqlite3_str_errcode(X)来恢复。


    动态字符串的状态

    int sqlite3_str_errcode(sqlite3_str*);
    int sqlite3_str_length(sqlite3_str*);
    char *sqlite3_str_value(sqlite3_str*);
    

    这些接口返回sqlite3_str对象的当前状态。

    如果在 sqlite3_str X 中构造动态字符串时发生任何先前错误,则sqlite3_str_errcode(X)方法将返回适当的错误代码。sqlite3_str_errcode(X)方法在出现任何内存不足错误后返回 SQLITE_NOMEM 如果动态字符串的大小超过 SQLITE_MAX_LENGTH返回 SQLITE_TOOBIG ,如果没有错误则返回 SQLITE_OK。

    sqlite3_str_length(X)方法返回sqlite3_str对象X中正在构建的动态字符串当前长度,以字节为单位。sqlite3_str_length( X ) 返回的长度不包括零终止字节。

    sqlite3_str_value(X)方法返回指向 X 中正在构造的动态字符串的当前内容的指针。sqlite3_str_value(X) 返回的值由sqlite3_str对象X 管理,并且可能被同一对象上的任何后续方法释放或更改 sqlite3_str对象。在同一对象上的任何后续方法调用之后,应用程序不得使用返回的 sqlite3_str_value(X)指针。应用程序可以更改sqlite3_str_value(X)返回的字符串的内容,只要它们不写入 0 到sqlite3_str_length(X)范围之外的任何字节,并且在任何后续 sqlite3_str 方法调用之后不读取或写入任何字节。


    字符串比较

    int sqlite3_stricmp(const char *, const char *);
    int sqlite3_strnicmp(const char *, const char *, int);
    

    sqlite3_stricmp()sqlite3_strnicmp() API 允许应用程序和扩展以大小写无关的方式比较包含 UTF-8 字符串的两个缓冲区的内容,使用 SQLite 在比较标识符时内部使用的相同“大小写无关”定义


    修改的总行数

    int sqlite3_total_changes(sqlite3*);
    sqlite3_int64 sqlite3_total_changes64(sqlite3*);
    

    这些函数返回自数据库连接打开以来完成的所有INSERTUPDATEDELETE语句 插入、修改或删除的行总数,包括那些作为触发器程序的一部分执行的行。这两个函数除了返回值的类型不同,如果连接修改的行数超过“int”类型支持的最大值,那么sqlite3_total_changes()的返回值是未定义的。执行任何其他类型的 SQL 语句不会影响 sqlite3_total_changes() 返回的值。

    作为外键操作的一部分所做的更改包括在计数中,但作为 REPLACE 约束解析的一部分所做的更改则不包括在内。不计算被 INSTEAD OF 触发器拦截的视图更改。

    sqlite3_total_changes(D)接口仅报告由于对数据库连接 D 运行 SQL 语句而更改的行数。其他数据库连接的任何更改都将被忽略要检测来自其他数据库连接的数据库文件的更改,请使用PRAGMA data_version命令或 SQLITE_FCNTL_DATA_VERSION 文件控件

    如果一个单独的线程在sqlite3_total_changes()运行时对同一个数据库连接进行更改,则返回的值是不可预测的并且没有意义。

    也可以看看:


    获取 URI 参数的值

    const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
    int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
    sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
    const char *sqlite3_uri_key(const char *zFilename, int N);
    

    这些是实用例程,对自定义 VFS 实现很有用,它们检查数据库文件是否是包含特定查询参数的 URI,如果是,则获取该查询参数的值。

    这些接口的第一个参数(以下简称为 F)必须是以下之一:

    如果 F 参数不是上述之一,则行为未定义且可能不合需要。旧版本的 SQLite 比新版本更能容忍无效的 F 参数。

    如果 F 是一个合适的文件名(如前一段所述)并且如果 P 是查询参数的名称,则 sqlite3_uri_parameter(F,P) 返回 P 参数的值(如果存在)或 NULL 指针(如果 P 不存在)作为 F 上的查询参数出现。如果 P 是 F 的查询参数并且没有显式值,则 sqlite3_uri_parameter(F,P) 返回一个指向空字符串的指针。

    sqlite3_uri_boolean(F,P,B)例程假定P是一个布尔参数,根据P的值返回true(1)或false(0)。sqlite3_uri_boolean(F,P,B)例程返回true(1)如果查询参数 P 的值在任何情况下都是“yes”、“true”或“on”之一,或者如果该值以非零数字开头。如果查询参数 P 的值在任何情况下都是“no”、“false”或“off”之一,或者如果值以数字零开头,则 sqlite3_uri_boolean(F,P,B) 例程返回 false (0)。如果 P 不是 F 上的查询参数,或者如果 P 的值与上述任何一个都不匹配,则 sqlite3_uri_boolean(F,P,B) 返回 (B!=0)。

    sqlite3_uri_int64(F,P,D) 例程将 P 的值转换为 64 位有符号整数并返回该整数,如果 P 不存在则返回 D。如果 P 的值不是整数,则返回零。

    sqlite3_uri_key(F,N) 返回指向文件名 F 的第 N 个查询参数的名称(不是值)的指针,如果 N 小于零或大于查询参数的数量减 1,则返回 NULL 指针。 N 值从零开始,因此 N 应为 0 以获取第一个查询参数的名称,为 1 以获取第二个参数,依此类推。

    如果 F 是 NULL 指针,则 sqlite3_uri_parameter(F,P) 返回 NULL,而 sqlite3_uri_boolean(F,P,B) 返回 B。如果 F 不是 NULL 指针,也不是 SQLite 核心传入的数据库文件路径名指针xOpen VFS 方法,那么这个例程的行为是未定义的,可能是不需要的。

    从 SQLite版本 3.31.0(2020-01-22)开始,输入的 F 参数除了主数据库文件外,还可以是回滚日志文件或 WAL 文件的名称。在版本 3.31.0 之前,这些例程仅在 F 是主数据库文件的名称时才有效。当 F 参数是回滚日志或 WAL 文件的名称时,它可以访问与在主数据库文件中找到的所有相同的查询参数。

    有关其他信息,请参阅URI 文件名文档。


    获取 SQL 值

    const void *sqlite3_value_blob(sqlite3_value*);
    double sqlite3_value_double(sqlite3_value*);
    int sqlite3_value_int(sqlite3_value*);
    sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
    void *sqlite3_value_pointer(sqlite3_value*, const char*);
    const unsigned char *sqlite3_value_text(sqlite3_value*);
    const void *sqlite3_value_text16(sqlite3_value*);
    const void *sqlite3_value_text16le(sqlite3_value*);
    const void *sqlite3_value_text16be(sqlite3_value*);
    int sqlite3_value_bytes(sqlite3_value*);
    int sqlite3_value_bytes16(sqlite3_value*);
    int sqlite3_value_type(sqlite3_value*);
    int sqlite3_value_numeric_type(sqlite3_value*);
    int sqlite3_value_nochange(sqlite3_value*);
    int sqlite3_value_frombind(sqlite3_value*);
    

    概括:

    sqlite3_value_blobBLOB值
    sqlite3_value_double真正的价值
    sqlite3_value_int32 位整数值
    sqlite3_value_int6464 位整数值
    sqlite3_value_pointer指针值
    sqlite3_value_textUTF-8 文本值
    sqlite3_value_text16本机字节顺序中的 UTF-16 TEXT 值
    sqlite3_value_text16beUTF-16be 文本值
    sqlite3_value_text16leUTF-16le TEXT 值
       
    sqlite3_value_bytes以字节为单位的 BLOB 或 UTF-8 TEXT 的大小
    sqlite3_value_bytes16   →  UTF-16 TEXT 的字节大小
    sqlite3_value_type值的默认数据类型
    sqlite3_value_numeric_type   →  值的最佳数字数据类型
    sqlite3_value_nochange   →  如果列在针对虚拟表的 UPDATE 中未更改,则为真。
    sqlite3_value_frombind   →  如果值源自绑定参数则为真

    细节:

    这些例程从受保护的 sqlite3_value对象中提取类型、大小和内容信息 。受保护的 sqlite3_value 对象用于将参数信息传递到实现应用程序定义的 SQL 函数虚拟表的函数中。

    这些例程仅适用于受保护的 sqlite3_value对象。任何在未受保护的 sqlite3_value上使用这些例程的尝试 都不是线程安全的。

    这些例程就像相应的列访问函数一样工作, 除了这些例程采用单个受保护的 sqlite3_value对象指针而不是sqlite3_stmt*指针和整数列号。

    sqlite3_value_text16() 接口以主机的本机字节顺序提取 UTF-16 字符串。sqlite3_value_text16be() 和 sqlite3_value_text16le() 接口分别将 UTF-16 字符串提取为大端和小端。

    如果sqlite3_value对象 V 是使用sqlite3_bind_pointer(S,I,P,X,D)sqlite3_result_pointer(C,P,X,D)初始化的, 并且如果 X 和 Y 是根据 strcmp(X,Y) 比较相等的字符串,则sqlite3_value_pointer(V,Y) 将返回指针 P。否则,sqlite3_value_pointer(V,Y) 返回 NULL。sqlite3_bind_pointer() 例程是为 SQLite 3.20.0 添加的指针传递接口的一部分。

    sqlite3_value_type(V) 接口返回 sqlite3_value对象 V的初始数据类型的 数据类型代码。返回值是SQLITE_INTEGERSQLITE_FLOATSQLITE_TEXTSQLITE_BLOBSQLITE_NULL 之一其他接口可能会更改 sqlite3_value 对象的数据类型。例如,如果数据类型最初是 SQLITE_INTEGER 并且调用 sqlite3_value_text(V) 来提取该整数的文本值,那么对 sqlite3_value_type(V) 的后续调用可能会返回 SQLITE_TEXT。是否发生持久性内部数据类型转换是未定义的,可能会从一个 SQLite 版本到下一个版本发生变化。

    sqlite3_value_numeric_type() 接口尝试对值应用数字关联。这意味着尝试将值转换为整数或浮点数。如果可以在不丢失信息的情况下进行此类转换(换句话说,如果该值是一个看起来像数字的字符串),则执行转换。否则不会发生转换。返回转换后的数据类型

    虚拟表的xUpdate方法中,sqlite3_value_nochange(X) 接口返回 true 当且仅当与 X 对应的列未被调用 xUpdate 方法调用以实现的 UPDATE 操作更改,并且如果和先前的xColumn方法调用被调用以提取未设置结果而返回的该列的值(可能是因为它查询了sqlite3_vtab_nochange()并发现该列未更改)。xUpdate方法中,sqlite3_value_nochange(X) 为真的任何值在所有其他方面都将显示为 NULL 值。如果在xUpdate以外的任何地方调用 sqlite3_value_nochange(X)方法调用 UPDATE 语句,则返回值是任意且无意义的。

    如果值 X 源自sqlite3_bind()接口之一,则 sqlite3_value_frombind(X) 接口返回非零如果 X 来自 SQL 文字值、表列或表达式,则 sqlite3_value_frombind(X) 返回零。

    请特别注意,从 sqlite3_value_blob() 、 sqlite3_value_text() 或 sqlite3_value_text16() 返回的指针可能随后 调用 sqlite3_value_bytes()sqlite3_value_bytes16()sqlite3_value_text()sqlite3_value_text16 ()而失效。

    这些例程必须从与提供sqlite3_value*参数的 SQL 函数相同的线程中调用。

    只要输入参数正确,这些例程只有在格式转换期间发生内存不足错误时才会失败。只有以下接口子集会出现内存不足错误:

    • sqlite3_value_blob()
    • sqlite3_value_text()
    • sqlite3_value_text16()
    • sqlite3_value_text16le()
    • sqlite3_value_text16be()
    • sqlite3_value_bytes()
    • sqlite3_value_bytes16()

    如果发生内存不足错误,则这些例程的返回值与该列包含 SQL NULL 值一样。有效的 SQL NULL 返回可以与内存不足错误区分开来,方法是在获得可疑返回值之后和在同一数据库连接上调用任何其他 SQLite 接口之前立即调用sqlite3_errcode()


    复制和释放 SQL 值

    sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
    void sqlite3_value_free(sqlite3_value*);
    

    sqlite3_value_dup(V) 接口复制了sqlite3_value 对象 D 并返回指向该副本的指针。返回的sqlite3_value受保护的 sqlite3_value对象,即使输入不是。如果 V 为 NULL 或内存分配失败,则 sqlite3_value_dup(V) 接口返回 NULL。如果 V 是指针值,则 sqlite3_value_dup(V) 的结果是 NULL 值。

    sqlite3_value_free(V) 接口释放先前从sqlite3_value_dup()获得的sqlite3_value对象。如果 V 是 NULL 指针,则 sqlite3_value_free(V) 是无害的空操作。


    虚拟文件系统对象

    sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
    int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
    int sqlite3_vfs_unregister(sqlite3_vfs*);
    

    虚拟文件系统 (VFS) 是SQLite 用来与底层操作系统交互的sqlite3_vfs对象。大多数 SQLite 构建都带有一个适用于主机的默认 VFS。可以注册新的 VFS,也可以注销现有的 VFS。提供了以下接口。

    sqlite3_vfs_find() 接口返回一个指向给定名称的 VFS 的指针。名称区分大小写。名称是以零结尾的 UTF-8 字符串。如果没有匹配,则返回 NULL 指针。如果 zVfsName 为 NULL,则返回默认 VFS。

    新的 VFS 用 sqlite3_vfs_register() 注册。如果设置了 makeDflt 标志,则每个新 VFS 都会成为默认 VFS。同一个 VFS 可以注册多次而不会受伤。要使现有 VFS 成为默认 VFS,请使用设置的 makeDflt 标志再次注册它。如果注册了两个具有相同名称的不同 VFS,则行为未定义。如果 VFS 使用 NULL 或空字符串的名称注册,则行为未定义。

    使用 sqlite3_vfs_unregister() 接口注销 VFS。如果默认 VFS 未注册,则选择另一个 VFS 作为默认值。新 VFS 的选择是任意的。


    查找 IN 约束右侧的所有元素。

    int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
    int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
    

    这些接口仅在 虚拟表实现的xFilter() 方法中有用。从任何其他上下文调用这些接口的结果是未定义的并且可能是有害的。

    调用 sqlite3_vtab_in_first(X,P) 或 sqlite3_vtab_in_next(X,P) 的 X 参数必须是调用这些例程的 xFilter 方法的参数之一,特别是之前为 all-at-once IN 选择的参数约束处理使用xBestIndex 方法中的sqlite3_vtab_in()接口 如果 X 参数不是为一次性 IN 约束处理选择的 xFilter 参数,则这些例程返回SQLITE_MISUSE或者可能表现出一些其他未定义或有害的行为。

    使用这些例程访问 IN 约束右侧的所有值,代码如下:

       for(rc=sqlite3_vtab_in_first(pList, &pVal);
           rc==SQLITE_OK && pVal
           rc=sqlite3_vtab_in_next(pList, &pVal)
       ){
         // do something with pVal
       }
       if( rc!=SQLITE_OK ){
         // an error has occurred
       }
    

    成功时,sqlite3_vtab_in_first(X,P) 和 sqlite3_vtab_in_next(X,P) 例程返回 SQLITE_OK 并将 *P 设置为指向 IN 约束 RHS 上的第一个或下一个值。如果 IN 约束的右侧没有更多值,则 *P 设置为 NULL 并且这些例程返回SQLITE_DONE如果发生故障,返回值可能是其他值,例如 SQLITE_NOMEM。

    这些例程返回的 *ppOut 值仅在下一次调用这些例程或调用这些例程的 xFilter 方法结束之前有效。如果虚拟表实现需要更长时间地保留 *ppOut 值,则它必须制作副本。*ppOut 值受保护


    Win32 特定接口

    int sqlite3_win32_set_directory(
      unsigned long type, /* Identifier for directory being set or reset */
      void *zValue        /* New value for directory being set or reset */
    );
    int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
    int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
    

    这些界面仅在 Windows 上可用。sqlite3_win32_set_directory接口用于将与 sqlite3_temp_directory 或 sqlite3_data_directory 变量关联的值设置zValue具体取决于类型参数的值。zValue 参数应为 NULL 以通过sqlite3_free释放先前的值;在使用之前,非 NULL 值将被复制到从sqlite3_malloc获得的内存 中。sqlite3_win32_set_directory接口返回 SQLITE_OK表示成功,SQLITE_ERROR如果类型不受支持,或者SQLITE_NOMEM如果无法分配内存。sqlite3_data_directory变量的值 旨在替代不存在该概念的 Win32 子平台上的当前目录,例如 WinRT 和 UWP。sqlite3_win32_set_directory8sqlite3_win32_set_directory16接口的行为与 sqlite3_win32_set_directory 接口完全相同,除了字符串参数必须分别为 UTF-8 或 UTF-16。


    将值绑定到准备好的语句

    int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
    int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
                            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, sqlite3_int64);
    int sqlite3_bind_null(sqlite3_stmt*, int);
    int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
    int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
    int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
                             void(*)(void*), unsigned char encoding);
    int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
    int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
    int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
    int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
    

    sqlite3_prepare_v2()及其变体的 SQL 语句文本输入中,文字可能会被匹配以下模板之一的参数替换:

    • ?NNN
    • :VVV
    • @VVV
    • $VVV

    在上面的模板中,NNN 表示整数文字,VVV 表示字母数字标识符。这些参数的值(也称为“主机参数名称”或“SQL 参数”)可以使用此处定义的 sqlite3_bind_*() 例程进行设置。

    sqlite3_bind_*() 例程的第一个参数始终是指向从sqlite3_prepare_v2()或其变体返回 的sqlite3_stmt对象的指针。

    第二个参数是要设置的 SQL 参数的索引。最左边的 SQL 参数的索引为 1。当多次使用同名 SQL 参数时,第二次和后续出现的索引与第一次出现的索引相同。如果需要,可以使用sqlite3_bind_parameter_index() API查找命名参数的索引 。“?NNN”参数的索引是 NNN 的值。NNN 值必须介于 1 和sqlite3_limit() 参数SQLITE_LIMIT_VARIABLE_NUMBER(默认值:32766)之间。

    第三个参数是绑定到参数的值。如果 sqlite3_bind_text() 或 sqlite3_bind_text16() 或 sqlite3_bind_blob() 的第三个参数是 NULL 指针,那么第四个参数将被忽略,最终结果与 sqlite3_bind_null() 相同。如果 sqlite3_bind_text() 的第三个参数不是 NULL,那么它应该是一个指向格式良好的 UTF8 文本的指针。如果 sqlite3_bind_text16() 的第三个参数不是 NULL,那么它应该是一个指向格式良好的 UTF16 文本的指针。如果 sqlite3_bind_text64() 的第三个参数不是 NULL,那么它应该是一个指向格式正确的 unicode 字符串的指针,如果第六个参数是 SQLITE_UTF8,则它是 UTF8,否则是 UTF16。

    UTF16 输入文本的字节顺序由第一个字符中的字节顺序标记(BOM、U+FEFF)确定,该标记已被删除,或者在没有 BOM 的情况下,字节顺序是主机的本机字节顺序sqlite3_bind_text16() 的机器或 sqlite3_bind_text64() 的第 6 个参数中指定的字节顺序。如果 UTF16 输入文本包含无效的 unicode 字符,则 SQLite 可能会将这些无效字符更改为 unicode 替换字符:U+FFFD。

    在那些有第四个参数的例程中,它的值是参数中的字节数。要清楚:该值是字节数在值中,而不是字符数。如果 sqlite3_bind_text() 或 sqlite3_bind_text16() 的第四个参数是负数,则字符串的长度是第一个零终止符之前的字节数。如果 sqlite3_bind_blob() 的第四个参数为负,则行为未定义。如果向 sqlite3_bind_text() 或 sqlite3_bind_text16() 或 sqlite3_bind_text64() 提供了一个非负的第四个参数,那么该参数必须是假设字符串以 NUL 终止的情况下 NUL 终止符出现的字节偏移量。如果任何 NUL 字符出现在小于第四个参数值的字节偏移处,则生成的字符串值将包含嵌入的 NUL。涉及嵌入 NUL 的字符串的表达式的结果是未定义的。

    BLOB 和字符串绑定接口的第五个参数控制或指示第三个参数引用的对象的生命周期。存在这三个选项:(1) 可以传递在 SQLite 完成处理后处理 BLOB 或字符串的析构函数。即使对绑定 API 的调用失败,也会调用它来处理 BLOB 或字符串,除非如果第三个参数是 NULL 指针或第四个参数为负,则不会调用析构函数。(2) 特殊常量,SQLITE_STATIC, 可能会被传递以指示应用程序仍然负责处理对象。在这种情况下,对象和提供的指向它的指针必须保持有效,直到准备好的语句完成或相同的 SQL 参数绑定到其他东西,以先发生者为准。(3)可以传递常量SQLITE_TRANSIENT以指示对象将在从 sqlite3_bind_*() 返回之前被复制。对象和指向它的指针必须在此之前保持有效。然后 SQLite 将管理其私有副本的生命周期。

    sqlite3_bind_text64() 的第六个参数必须是 SQLITE_UTF8SQLITE_UTF16SQLITE_UTF16BESQLITE_UTF16LE 之一, 以指定第三个参数中文本的编码。如果 sqlite3_bind_text64() 的第六个参数不是上面显示的允许值之一,或者如果文本编码与第六个参数指定的编码不同,则行为未定义。

    sqlite3_bind_zeroblob() 例程绑定了一个长度为 N 并用零填充的 BLOB。zeroblob 在处理时使用固定数量的内存(只是一个整数来保存它的大小)。Zeroblob 旨在用作 BLOB 的占位符,其内容稍后使用 增量 BLOB I/O例程写入。zeroblob 的负值会导致长度为零的 BLOB。

    sqlite3_bind_pointer(S,I,P,T,D) 例程导致 准备语句S 中的第 I 个参数具有 NULL 的 SQL 值,但也与类型 T 的指针 P 相关联。D 是 NULL指针或指向 P 的析构函数的指针。当 SQLite 完成使用 P 时,它将使用 P 的单个参数调用析构函数 D。T 参数应该是静态字符串,最好是字符串文字。sqlite3_bind_pointer() 例程是 为 SQLite 3.20.0 添加的指针传递接口的一部分。

    如果调用任何 sqlite3_bind_*() 例程时使用准备语句的 NULL 指针或使用 最近调用 sqlite3_step() 的准备语句而不是sqlite3_reset (),则调用将返回SQLITE_MISUSE如果任何 sqlite3_bind_() 例程被传递一个已经完成的准备好的语句,结果是未定义的并且可能是有害的。

    sqlite3_reset()例程不会清除绑定。未绑定的参数被解释为 NULL。

    sqlite3_bind_* 例程在成功 时返回SQLITE_OK或在出现任何问题时 返回错误代码。如果字符串或 BLOB 的大小超过sqlite3_limit ( SQLITE_LIMIT_LENGTH ) 或 SQLITE_MAX_LENGTH施加的限制,则可能会返回SQLITE_TOOBIG如果参数索引超出范围,则返回 SQLITE_RANGE 。如果 malloc() 失败,则返回SQLITE_NOMEM 。

    另请参阅:sqlite3_bind_parameter_count()sqlite3_bind_parameter_name()sqlite3_bind_parameter_index()


    编译 SQL 语句

    int sqlite3_prepare(
      sqlite3 *db,            /* Database handle */
      const char *zSql,       /* SQL statement, UTF-8 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const char **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    int sqlite3_prepare_v2(
      sqlite3 *db,            /* Database handle */
      const char *zSql,       /* SQL statement, UTF-8 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const char **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    int sqlite3_prepare_v3(
      sqlite3 *db,            /* Database handle */
      const char *zSql,       /* SQL statement, UTF-8 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const char **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    int sqlite3_prepare16(
      sqlite3 *db,            /* Database handle */
      const void *zSql,       /* SQL statement, UTF-16 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const void **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    int sqlite3_prepare16_v2(
      sqlite3 *db,            /* Database handle */
      const void *zSql,       /* SQL statement, UTF-16 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const void **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    int sqlite3_prepare16_v3(
      sqlite3 *db,            /* Database handle */
      const void *zSql,       /* SQL statement, UTF-16 encoded */
      int nByte,              /* Maximum length of zSql in bytes. */
      unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
      sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
      const void **pzTail     /* OUT: Pointer to unused portion of zSql */
    );
    

    要执行 SQL 语句,必须首先使用这些例程之一将其编译成字节代码程序。或者,换句话说,这些例程是准备好的语句对象的构造函数。

    首选例程是sqlite3_prepare_v2()sqlite3_prepare()接口是遗留的 ,应该避免。 sqlite3_prepare_v3()有一个额外的“prepFlags”选项,用于特殊目的。

    首选使用 UTF-8 接口,因为 SQLite 目前使用 UTF-8 进行所有解析。UTF-16 接口是为方便起见而提供的。UTF-16 接口的工作方式是将输入文本转换为 UTF-8,然后调用相应的 UTF-8 接口。

    第一个参数“db”是从先前成功调用sqlite3_open()sqlite3_open_v2()sqlite3_open16()获得的数据库连接数据库连接一定没有关闭。

    第二个参数“zSql”是要编译的语句,编码为 UTF-8 或 UTF-16。sqlite3_prepare()、sqlite3_prepare_v2()和sqlite3_prepare_v3()接口使用UTF-8,sqlite3_prepare16()、sqlite3_prepare16_v2()和sqlite3_prepare16_v3()使用UTF-16。

    如果 nByte 参数为负数,则读取 zSql 直到第一个零终止符。如果 nByte 为正数,则它是从 zSql 读取的字节数。如果 nByte 为零,则不会生成准备好的语句。如果调用者知道提供的字符串以 nul 终止,则传递一个 nByte 参数会有一个小的性能优势,该参数是输入字符串中的字节数,包括 nul 终止符。

    如果 pzTail 不为 NULL,则 *pzTail 指向 zSql 中第一个 SQL 语句结束后的第一个字节。这些例程仅编译 zSql 中的第一条语句,因此 *pzTail 仍指向未编译的部分。

    *ppStmt 指向编译好的准备语句,可以使用sqlite3_step()执行。如果出现错误,*ppStmt 将设置为 NULL。如果输入文本不包含 SQL(如果输入是空字符串或注释),则 *ppStmt 设置为 NULL。调用过程负责在完成后使用sqlite3_finalize()删除已编译的 SQL 语句。ppStmt 不能为 NULL。

    成功时,sqlite3_prepare() 例程系列返回SQLITE_OK否则返回错误代码

    建议所有新程序使用 sqlite3_prepare_v2()、sqlite3_prepare_v3()、sqlite3_prepare16_v2() 和 sqlite3_prepare16_v3() 接口。保留旧接口(sqlite3_prepare() 和 sqlite3_prepare16())是为了向后兼容,但不鼓励使用它们。在“vX”接口中,返回的准备好的语句(sqlite3_stmt对象)包含原始 SQL 文本的副本。这导致sqlite3_step()接口以三种方式表现不同:

    1. 如果数据库模式发生变化,sqlite3_step()将自动重新编译 SQL 语句并尝试再次运行,而不是像往常一样返回SQLITE_SCHEMA 。 在 sqlite3_step() 放弃并返回错误之前,将发生 SQLITE_MAX_SCHEMA_RETRY一样多的重试。
    2. 当发生错误时,sqlite3_step()将返回详细 错误代码扩展错误代码之一。遗留行为是 sqlite3_step()只会返回一个通用的SQLITE_ERROR结果代码,应用程序必须再次调用sqlite3_reset() 才能找到问题的根本原因。使用“v2”准备接口,会立即返回错误的根本原因。
    3. 如果 WHERE 子句中绑定到主机参数的特定值可能会影响语句查询计划的选择,那么语句将自动重新编译,就好像在任何之后的第一个sqlite3_step()调用中发生了模式更改一样更改为该参数的绑定如果参数是LIKEGLOB运算符的左侧,或者如果参数与索引列进行比较并且启用了SQLITE_ENABLE_STAT4编译时选项,则WHERE 子句参数的特定值可能会影响查询计划的选择.

    sqlite3_prepare_v3() 与 sqlite3_prepare_v2() 的不同之处仅在于具有额外的 prepFlags 参数,该参数是由零个或多个SQLITE_PREPARE_*标志组成的位数组。sqlite3_prepare_v2() 接口的工作方式与带有零 prepFlags 参数的 sqlite3_prepare_v3() 完全相同。


    编译时授权回调

    int sqlite3_set_authorizer(
      sqlite3*,
      int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
      void *pUserData
    );
    

    此例程使用第一个参数中提供 的特定 数据库连接注册授权回调。当 SQL 语句由sqlite3_prepare()或其变体sqlite3_prepare_v2()sqlite3_prepare_v3()sqlite3_prepare16()sqlite3_prepare16_v2()sqlite3_prepare16_v3()编译时调用授权回调。在编译过程中的不同时间点,当创建逻辑以执行各种操作时,将调用授权方回调以查看是否允许这些操作。授权回调应该返回SQLITE_OK以允许操作,SQLITE_IGNORE禁止特定操作但允许继续编译 SQL 语句,或者SQLITE_DENY导致整个 SQL 语句被错误拒绝。如果授权方回调返回SQLITE_IGNORESQLITE_OKSQLITE_DENY以外的任何值, 则触发授权方的sqlite3_prepare_v2()或等效调用将失败并显示错误消息。

    当回调返回SQLITE_OK时,这意味着请求的操作是正确的。当回调返回SQLITE_DENY时,触发授权方的 sqlite3_prepare_v2()或等效调用将失败,并显示一条错误消息,说明访问被拒绝。

    授权回调的第一个参数是 sqlite3_set_authorizer() 接口的第三个参数的副本。回调的第二个参数是一个整数操作代码,指定要授权的特定操作。回调的第三到第六个参数是 NULL 指针或以零结尾的字符串,其中包含有关要授权的操作的其他详细信息。应用程序必须始终准备好在授权回调的第三个到第六个参数中的任何一个中遇到 NULL 指针。

    如果操作代码是SQLITE_READ 并且回调返回SQLITE_IGNORE,那么 准备好的语句语句被构造为用 NULL 值代替如果返回SQLITE_OK将被读取的表列。SQLITE_IGNORE返回 可用于拒绝不受信任的用户访问表的各个列。当一个表被SELECT引用但没有从该表中提取列值时(例如在像“SELECT count(*) FROM tab”这样的查询中),然后为该表调用一次SQLITE_READ授权回调,其列名是是一个空字符串。如果操作代码是SQLITE_DELETE并且回调返回 SQLITE_IGNORE然后DELETE操作继续但 截断优化被禁用并且所有行被单独删除。

    在准备来自不受信任来源的 SQL 语句时使用授权程序 ,以确保 SQL 语句不会尝试访问它们不允许查看的数据,或者它们不会尝试执行破坏数据库的恶意语句。例如,应用程序可能允许用户输入任意 SQL 查询以供数据库评估。但是应用程序不希望用户能够对数据库进行任意更改。然后可以在准备用户输入的 SQL 时放置一个授权器,该 SQL不允许除SELECT语句之外的所有内容。

    需要处理来自不受信任来源的 SQL 的应用程序还可以考虑使用sqlite3_limit()降低资源限制,并使用max_page_count PRAGMA 除了使用授权程序之外还可以 限制数据库大小。

    一个数据库连接上一次只能有一个授权方。每次调用 sqlite3_set_authorizer 都会覆盖之前的调用。通过安装 NULL 回调来禁用授权方。默认情况下禁用授权方。

    授权回调不能做任何会修改调用授权回调的数据库连接的事情。注意,sqlite3_prepare_v2()sqlite3_step()都针对本段“修改”的意思修改了自己的数据库连接。

    当使用sqlite3_prepare_v2()准备语句时,由于架构更改,可能会在sqlite3_step()期间重新准备语句。因此,应用程序应确保正确的授权回调在sqlite3_step()期间保持不变。

    请注意,授权回调仅在 sqlite3_prepare()或其变体期间被调用。在sqlite3_step()中的语句评估期间不执行授权,除非如前一段所述,sqlite3_step() 调用 sqlite3_prepare_v2() 以在模式更改后重新准备语句。


    测试自动提交模式

    int sqlite3_get_autocommit(sqlite3*);
    

    如果给定的数据库连接处于或不处于自动提交模式,则 sqlite3_get_autocommit() 接口分别返回非零或零。默认情况下,自动提交模式处于启用状态。BEGIN语句禁用自动提交模式。自动提交模式由COMMITROLLBACK重新启用。

    如果在多语句事务中的语句上发生某些类型的错误(错误包括SQLITE_FULLSQLITE_IOERRSQLITE_NOMEMSQLITE_BUSYSQLITE_INTERRUPT),则事务可能会自动回滚。找出 SQLite 是否在出错后自动回滚事务的唯一方法是使用此函数。

    如果在此例程运行时另一个线程更改了数据库连接的自动提交状态,则返回值未定义。


    注册回调以处理 SQLITE_BUSY 错误

    int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
    

    sqlite3_busy_handler(D,X,P) 例程设置了一个回调函数 X,当另一个线程或进程锁定了与数据库连接D 关联的数据库表时,每当尝试访问与数据库连接 D 关联的数据库表时,都可以使用参数 P 调用该回调函数 。sqlite3_busy_handler() 接口用于实现 sqlite3_busy_timeout()PRAGMA busy_timeout

    如果忙回调为 NULL,则 在遇到锁时立即返回SQLITE_BUSY 。如果忙回调不为 NULL,则可以使用两个参数调用回调。

    busy 处理程序的第一个参数是 void* 指针的副本,它是 sqlite3_busy_handler() 的第三个参数。繁忙处理程序回调的第二个参数是先前为同一锁定事件调用繁忙处理程序的次数。如果忙回调返回 0,则不会再尝试访问数据库,SQLITE_BUSY将返回给应用程序。如果回调返回非零值,则会再次尝试访问数据库并重复循环。

    繁忙处理程序的存在并不能保证它会在存在锁争用时被调用。如果 SQLite 确定调用繁忙处理程序可能导致死锁,它将继续并将SQLITE_BUSY返回 给应用程序,而不是调用繁忙处理程序。考虑这样一种情况,其中一个进程持有一个试图提升为保留锁的读锁,而另一个进程持有一个它试图提升为独占锁的保留锁。第一个进程无法继续,因为它被第二个进程阻塞,第二个进程无法继续,因为它被第一个进程阻塞。如果两个进程都调用繁忙的处理程序,那么它们都不会取得任何进展。因此,SQLite 返回SQLITE_BUSY对于第一个进程,希望这会导致第一个进程释放其读锁并允许第二个进程继续。

    默认忙回调为 NULL。

    只能为每个 数据库连接定义一个繁忙的处理程序。设置一个新的繁忙处理程序会清除任何以前设置的处理程序。请注意,调用sqlite3_busy_timeout() 或评估PRAGMA busy_timeout=N将更改繁忙处理程序,从而清除任何先前设置的繁忙处理程序。

    繁忙回调不应采取任何修改调用繁忙处理程序的数据库连接的操作。换句话说,繁忙的处理程序是不可重入的。任何此类操作都会导致未定义的行为。

    繁忙的处理程序不得关闭调用繁忙处理程序 的数据库连接或准备好的语句。


    查询的结果值

    const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
    double sqlite3_column_double(sqlite3_stmt*, int iCol);
    int sqlite3_column_int(sqlite3_stmt*, int iCol);
    sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
    const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
    const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
    sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
    int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
    int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
    int sqlite3_column_type(sqlite3_stmt*, int iCol);
    

    概括:

    sqlite3_column_blobBLOB 结果
    sqlite3_column_double真正的结果
    sqlite3_column_int32 位整数结果
    sqlite3_column_int6464 位整数结果
    sqlite3_column_textUTF-8 文本结果
    sqlite3_column_text16UTF-16 文本结果
    sqlite3_column_value作为 未受保护的 sqlite3_value对象的结果。
       
    sqlite3_column_bytesBLOB 或 UTF-8 TEXT 结果的大小(以字节为单位)
    sqlite3_column_bytes16   →  UTF-16 TEXT 的字节大小
    sqlite3_column_type结果的默认数据类型

    细节:

    这些例程返回有关查询当前结果行的单个列的信息。在每种情况下,第一个参数是指向正在评估的准备语句的指针( 从sqlite3_prepare_v2()或其变体之一返回的sqlite3_stmt* ),第二个参数是应返回信息的列的索引. 结果集最左边的列的索引为 0。结果中的列数可以使用 sqlite3_column_count()确定。

    如果 SQL 语句当前未指向有效行,或者列索引​​超出范围,则结果未定义。这些例程只能在最近调用 sqlite3_step()返回SQLITE_ROW并且随后既没有 调用 sqlite3_reset( )也没有调用sqlite3_finalize()时调用。如果在sqlite3_reset()sqlite3_finalize()之后或在sqlite3_step()返回SQLITE_ROW以外的内容之后调用这些例程中的任何一个,则结果是不确定的。如果sqlite3_step()sqlite3_reset()sqlite3_finalize() 当这些例程中的任何一个挂起时从不同的线程调用,那么结果是未定义的。

    前六个接口(_blob、_double、_int、_int64、_text 和 _text16)均以特定数据格式返回结果列的值。如果结果列最初不是请求的格式(例如,如果查询返回一个整数但 sqlite3_column_text() 接口用于提取值)则执行自动类型转换。

    sqlite3_column_type() 例程返回 结果列的初始数据类型的数据类型代码返回值是SQLITE_INTEGERSQLITE_FLOATSQLITE_TEXTSQLITE_BLOBSQLITE_NULL 之一. sqlite3_column_type() 的返回值可用于决定应使用前六个接口中的哪一个来提取列值。sqlite3_column_type() 返回的值只有在相关值没有发生自动类型转换时才有意义。类型转换后,调用 sqlite3_column_type() 的结果是未定义的,但无害。SQLite 的未来版本可能会在类型转换后更改 sqlite3_column_type() 的行为。

    如果结果是 BLOB 或 TEXT 字符串,则可以使用 sqlite3_column_bytes() 或 sqlite3_column_bytes16() 接口来确定该 BLOB 或字符串的大小。

    如果结果是 BLOB 或 UTF-8 字符串,则 sqlite3_column_bytes() 例程返回该 BLOB 或字符串中的字节数。如果结果是 UTF-16 字符串,则 sqlite3_column_bytes() 会将字符串转换为 UTF-8,然后返回字节数。如果结果是一个数值,则 sqlite3_column_bytes() 使用 sqlite3_snprintf()将该值转换为 UTF-8 字符串并返回该字符串中的字节数。如果结果为 NULL,则 sqlite3_column_bytes() 返回零。

    如果结果是 BLOB 或 UTF-16 字符串,则 sqlite3_column_bytes16() 例程返回该 BLOB 或字符串中的字节数。如果结果是 UTF-8 字符串,则 sqlite3_column_bytes16() 会将字符串转换为 UTF-16,然后返回字节数。如果结果是数值,则 sqlite3_column_bytes16() 使用 sqlite3_snprintf()将该值转换为 UTF-16 字符串并返回该字符串中的字节数。如果结果为 NULL,则 sqlite3_column_bytes16() 返回零。

    sqlite3_column_bytes()sqlite3_column_bytes16()返回的值不包括字符串末尾的零终止符。为清楚起见: sqlite3_column_bytes()sqlite3_column_bytes16()返回的值是字符串中的字节数,而不是字符数。

    sqlite3_column_text() 和 sqlite3_column_text16() 返回的字符串,即使是空字符串,也始终以零结尾。零长度 BLOB 的 sqlite3_column_blob() 的返回值是 NULL 指针。

    sqlite3_column_text16() 返回的字符串始终具有平台原生的字节序,无论数据库的文本编码设置如何。

    警告:sqlite3_column_value()返回的对象是一个 不受保护的 sqlite3_value对象。在多线程环境中,未受保护的 sqlite3_value 对象只能安全地与 sqlite3_bind_value()sqlite3_result_value()一起使用。如果以任何其他方式使用sqlite3_column_value()返回的未受保护的 sqlite3_value对象 ,包括调用sqlite3_value_int()sqlite3_value_text()sqlite3_value_bytes()等例程,则该行为不是线程安全的。因此,sqlite3_column_value() 接口通常只在实现中有用 应用程序定义的 SQL 函数虚拟表,不在顶级应用程序代码中。

    这些例程可能会尝试转换结果的数据类型。例如,如果内部表示是 FLOAT 并且请求文本结果,则在内部使用sqlite3_snprintf()自动执行转换。下表详细说明了应用的转换:

    Internal
    Type
    Requested
    Type
    Conversion

    NULL INTEGER Result is 0
    NULL FLOAT Result is 0.0
    NULL TEXT Result is a NULL pointer
    NULL BLOB Result is a NULL pointer
    INTEGER FLOAT Convert from integer to float
    INTEGER TEXT ASCII rendering of the integer
    INTEGER BLOB Same as INTEGER->TEXT
    FLOAT INTEGER CAST to INTEGER
    FLOAT TEXT ASCII rendering of the float
    FLOAT BLOB CAST to BLOB
    TEXT INTEGER CAST to INTEGER
    TEXT FLOAT CAST to REAL
    TEXT BLOB No change
    BLOB INTEGER CAST to INTEGER
    BLOB FLOAT CAST to REAL
    BLOB TEXT CAST to TEXT, ensure zero terminator

    请注意,当发生类型转换时,先前调用 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 之间的转换总是就地完成,不会使先前的指针无效,当然,先前指针引用的缓冲区内容将被修改。其他类型的转换在可能的情况下就地完成,但有时它们是不可能的,在这些情况下,先前的指针将无效。

    最安全的策略是以下列方式之一调用这些例程:

    • sqlite3_column_text() 后跟 sqlite3_column_bytes()
    • sqlite3_column_blob() 后跟 sqlite3_column_bytes()
    • sqlite3_column_text16() 后跟 sqlite3_column_bytes16()

    换句话说,您应该首先调用 sqlite3_column_text()、sqlite3_column_blob() 或 sqlite3_column_text16() 以将结果强制为所需的格式,然后调用 sqlite3_column_bytes() 或 sqlite3_column_bytes16() 来查找结果的大小。不要将对 sqlite3_column_text() 或 sqlite3_column_blob() 的调用与对 sqlite3_column_bytes16() 的调用混合使用,也不要将对 sqlite3_column_text16() 的调用与对 sqlite3_column_bytes() 的调用混合使用。

    返回的指针在如上所述发生类型转换之前有效,或者直到调用sqlite3_step()sqlite3_reset()sqlite3_finalize()用于保存字符串和 BLOB 的内存空间会自动释放。不要将从sqlite3_column_blob()sqlite3_column_text()等 返回的指针传递给sqlite3_free()

    只要输入参数正确,这些例程只有在格式转换期间发生内存不足错误时才会失败。只有以下接口子集会出现内存不足错误:

    • sqlite3_column_blob()
    • sqlite3_column_text()
    • sqlite3_column_text16()
    • sqlite3_column_bytes()
    • sqlite3_column_bytes16()

    如果发生内存不足错误,则这些例程的返回值与该列包含 SQL NULL 值一样。有效的 SQL NULL 返回可以与内存不足错误区分开来,方法是在获得可疑返回值之后和在同一数据库连接上调用任何其他 SQLite 接口之前立即调用sqlite3_errcode()


    数据库文件的低级控制

    int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
    

    sqlite3_file_control()接口直接调用与第二个参数标识的特定数据库关联的sqlite3_io_methods对象 的xFileControl 方法。数据库的名称对于主数据库是“main”,对于 TEMP 数据库是“temp”,或者对于使用ATTACH SQL 命令添加的数据库,名称是出现在 AS 关键字之后的名称。可以使用 NULL 指针代替“main”来引用主数据库文件。此例程的第三个和第四个参数直接传递给 xFileControl 方法的第二个和第三个参数。xFileControl 方法的返回值成为该例程的返回值。

    sqlite3_file_control()的一些操作码由 SQLite 核心直接处理,从不调用 sqlite3_io_methods.xFileControl 方法。op 参数的SQLITE_FCNTL_FILE_POINTER值导致指向底层sqlite3_file对象的指针被写入第 4 个参数指向的空间。SQLITE_FCNTL_JOURNAL_POINTER工作方式类似,只是它返回与日志文件而不是主数据库关联的sqlite3_file对象。SQLITE_FCNTL_VFS_POINTER操作码返回指向文件底层sqlite3_vfs对象的指针。SQLITE_FCNTL_DATA_VERSION _从寻呼机返回数据版本计数器。

    如果第二个参数 (zDbName) 与任何打开的数据库文件的名称不匹配,则返回 SQLITE_ERROR。此错误代码不会被记住,也不会被sqlite3_errcode()sqlite3_errmsg()调用。底层 xFileControl 方法也可能返回 SQLITE_ERROR。无法区分不正确的 zDbName 和底层 xFileControl 方法返回的 SQLITE_ERROR。

    另见:文件控制操作码


    创建或重新定义 SQL 函数

    int sqlite3_create_function(
      sqlite3 *db,
      const char *zFunctionName,
      int nArg,
      int eTextRep,
      void *pApp,
      void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
      void (*xStep)(sqlite3_context*,int,sqlite3_value**),
      void (*xFinal)(sqlite3_context*)
    );
    int sqlite3_create_function16(
      sqlite3 *db,
      const void *zFunctionName,
      int nArg,
      int eTextRep,
      void *pApp,
      void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
      void (*xStep)(sqlite3_context*,int,sqlite3_value**),
      void (*xFinal)(sqlite3_context*)
    );
    int sqlite3_create_function_v2(
      sqlite3 *db,
      const char *zFunctionName,
      int nArg,
      int eTextRep,
      void *pApp,
      void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
      void (*xStep)(sqlite3_context*,int,sqlite3_value**),
      void (*xFinal)(sqlite3_context*),
      void(*xDestroy)(void*)
    );
    int sqlite3_create_window_function(
      sqlite3 *db,
      const char *zFunctionName,
      int nArg,
      int eTextRep,
      void *pApp,
      void (*xStep)(sqlite3_context*,int,sqlite3_value**),
      void (*xFinal)(sqlite3_context*),
      void (*xValue)(sqlite3_context*),
      void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
      void(*xDestroy)(void*)
    );
    

    这些函数(统称为“函数创建例程”)用于添加 SQL 函数或聚合,或者重新定义现有 SQL 函数或聚合的行为。三个“sqlite3_create_function*”例程之间的唯一区别是第二个参数(正在创建的函数的名称)预期的文本编码以及是否存在应用程序数据指针的析构函数回调。函数 sqlite3_create_window_function() 类似,但允许用户提供聚合窗口函数所需的额外回调函数

    第一个参数是要添加 SQL 函数的数据库连接。如果应用程序使用多个数据库连接,则应用程序定义的 SQL 函数必须分别添加到每个数据库连接。

    第二个参数是要创建或重新定义的 SQL 函数的名称。在 UTF-8 表示中,名称的长度限制为 255 个字节,不包括零终止符。请注意,名称长度限制是 UTF-8 字节,而不是字符或 UTF-16 字节。任何尝试创建具有较长名称的函数都将导致返回SQLITE_MISUSE

    第三个参数 (nArg) 是 SQL 函数或聚合采用的参数数量。如果此参数为 -1,则 SQL 函数或聚合可以采用介于 0 和sqlite3_limit ( SQLITE_LIMIT_FUNCTION_ARG ) 设置的限制之间的任意数量的参数。如果第三个参数小于 -1 或大于 127,则行为未定义。

    第四个参数 eTextRep 指定 此 SQL 函数对其参数首选的文本编码。如果函数实现 在输入上调用sqlite3_value_text16le() ,则应用程序应将此参数设置为 SQLITE_UTF16LE;如果实现在输入 上调用sqlite3_value_text16be (),则应用程序应将此参数设置为SQLITE_UTF16BE ;如果使用了 sqlite3_value_text16 ( ),则应用程序应将此参数设置为SQLITE_UTF16;或SQLITE_UTF8 否则。可以使用不同的首选文本编码多次注册相同的 SQL 函数,每种编码都有不同的实现。当同一个函数有多个实现时,SQLite 会选择涉及最少数据转换的那个。

    第四个参数可以选择与SQLITE_DETERMINISTIC进行或运算, 以表示在单个 SQL 语句中给定相同的输入,该函数将始终返回相同的结果。大多数 SQL 函数都是确定性的。内置的random() SQL 函数是一个不确定函数的例子。SQLite 查询规划器能够对确定性函数执行额外的优化,因此建议尽可能使用SQLITE_DETERMINISTIC标志。

    第四个参数还可以选择性地包含SQLITE_DIRECTONLY 标志,如果存在,该标志将阻止从 VIEW、TRIGGER、CHECK 约束、生成的列表达式、索引表达式或部分索引的 WHERE 子句中调用该函数。

    为获得最佳安全性,建议将SQLITE_DIRECTONLY标志用于不需要在触发器、视图、CHECK 约束或数据库模式的其他元素内部使用的所有应用程序定义的 SQL 函数。对于具有副作用或揭示内部应用程序状态的 SQL 函数,特别推荐使用此标志。如果没有此标志,攻击者可能能够修改数据库文件的架构,以包括使用攻击者选择的参数调用函数,然后应用程序将在打开和读取数据库文件时执行这些调用。

    第五个参数是一个任意指针。该函数的实现可以使用sqlite3_user_data()访问该指针

    传递给三个“sqlite3_create_function*”函数 xFunc、xStep 和 xFinal 的第六、第七和第八个参数是指向实现 SQL 函数或聚合的 C 语言函数的指针。标量 SQL 函数只需要执行 xFunc 回调;NULL 指针必须作为 xStep 和 xFinal 参数传递。聚合 SQL 函数需要 xStep 和 xFinal 的实现,并且必须为 xFunc 传递 NULL 指针。要删除现有的 SQL 函数或聚合,请为所有三个函数回调传递 NULL 指针。

    传递给 sqlite3_create_window_function 的第六、第七、第八和第九个参数(xStep、xFinal、xValue 和 xInverse)是指向实现新函数的 C 语言回调的指针。xStep 和 xFinal 都必须是非 NULL。xValue 和 xInverse 可以都为 NULL,在这种情况下会创建一个常规聚合函数,或者都必须为非 NULL,在这种情况下,新函数可以用作聚合函数或聚合窗口函数。有关聚合窗口函数实现的更多详细信息, 请参见此处

    如果 sqlite3_create_function_v2() 或 sqlite3_create_window_function() 的最终参数不为 NULL,则它是应用程序数据指针的析构函数。当函数被删除时调用析构函数,无论是通过重载还是当数据库连接关闭时。如果对 sqlite3_create_function_v2() 的调用失败,也会调用析构函数。调用析构函数回调时,它会传递一个参数,该参数是应用程序数据指针的副本,该指针是 sqlite3_create_function_v2() 的第五个参数。

    允许使用相同的名称注册相同函数的多个实现,但使用不同数量的参数或不同的首选文本编码。SQLite 将使用与 SQL 函数使用方式最匹配的实现。具有非负 nArg 参数的函数实现比具有负 nArg 的函数实现更匹配。首选文本编码与数据库编码匹配的函数比编码不同的函数更匹配。编码差异介于 UTF16le 和 UTF16be 之间的函数比编码差异介于 UTF8 和 UTF16 之间的函数更匹配。

    内置函数可能会被新的应用程序定义的函数重载。

    允许应用程序定义的函数调用其他 SQLite 接口。但是,此类调用不得关闭数据库连接,也不得完成或重置运行函数的准备语句。