以下两个对象和八个方法构成了 SQLite 接口的基本要素
sqlite3 → 数据库连接对象。由 sqlite3_open() 创建,并由 sqlite3_close() 销毁。
sqlite3_stmt → 预处理语句对象。由 sqlite3_prepare() 创建,并由 sqlite3_finalize() 销毁。
sqlite3_open() → 打开到新的或现有的 SQLite 数据库的连接。是 sqlite3 的构造函数。
sqlite3_prepare() → 将 SQL 文本编译成字节码,用于查询或更新数据库。是 sqlite3_stmt 的构造函数。
sqlite3_bind() → 将应用程序数据存储到原始 SQL 的 参数 中。
sqlite3_step() → 将 sqlite3_stmt 推进到下一行结果或完成。
sqlite3_column() → sqlite3_stmt 当前结果行中的列值。
sqlite3_finalize() → sqlite3_stmt 的析构函数。
sqlite3_close() → sqlite3 的析构函数。
sqlite3_exec() → 一个包装函数,它为一个或多个 SQL 语句的字符串执行 sqlite3_prepare()、sqlite3_step()、sqlite3_column() 和 sqlite3_finalize()。
SQLite 拥有超过 225 个 API。但是,大多数 API 是可选的并且非常专业,初学者可以忽略它们。核心 API 很小、简单且易于学习。本文总结了核心 API。
单独的文档,SQLite C/C++ 接口,提供了 SQLite 所有 C/C++ API 的详细规范。一旦读者了解了 SQLite 的基本操作原理,就应该使用 该文档 作为参考指南。本文仅作为介绍,既不是 SQLite API 的完整参考,也不是权威参考。
SQL 数据库引擎的主要任务是评估 SQL 语句。为了实现这一点,开发人员需要两个对象
严格来说,预处理语句 对象不是必需的,因为可以使用便捷包装器接口 sqlite3_exec 或 sqlite3_get_table,并且这些便捷包装器封装并隐藏了 预处理语句 对象。然而,要充分利用 SQLite,需要了解 预处理语句。
数据库连接 和 预处理语句 对象由下面列出的一小组 C/C++ 接口例程控制。
请注意,以上例程列表是概念性的,而不是实际的。许多这些例程有多个版本。例如,以上列表显示了一个名为 sqlite3_open() 的单个例程,而实际上有三个单独的例程以略微不同的方式完成相同的事情:sqlite3_open()、sqlite3_open16() 和 sqlite3_open_v2()。该列表提到了 sqlite3_column(),但实际上不存在这样的例程。“sqlite3_column()”是整个例程家族的占位符,这些例程以各种数据类型提取列数据。
以下是核心接口的功能摘要
此例程打开到 SQLite 数据库文件的连接,并返回一个 数据库连接 对象。这通常是应用程序发出的第一个 SQLite API 调用,并且是大多数其他 SQLite API 的先决条件。许多 SQLite 接口需要一个指向 数据库连接 对象的指针作为其第一个参数,可以将其视为 数据库连接 对象上的方法。此例程是 数据库连接 对象的构造函数。
此例程将 SQL 文本转换为 预处理语句 对象,并返回指向该对象的指针。此接口需要一个由先前对 sqlite3_open() 的调用创建的 数据库连接 指针,以及包含要准备的 SQL 语句的文本字符串。此 API 实际上并不评估 SQL 语句。它只是准备 SQL 语句以供评估。
将每个 SQL 语句视为一个小型计算机程序。sqlite3_prepare() 的目的是将该程序编译成目标代码。预处理语句 是目标代码。sqlite3_step() 接口然后运行目标代码以获取结果。
新的应用程序应始终调用 sqlite3_prepare_v2() 而不是 sqlite3_prepare()。保留较旧的 sqlite3_prepare() 以实现向后兼容性。但 sqlite3_prepare_v2() 提供了一个更好的接口。
此例程用于评估先前由 sqlite3_prepare() 接口创建的 预处理语句。该语句会评估到第一行结果可用为止。要推进到第二行结果,请再次调用 sqlite3_step()。继续调用 sqlite3_step(),直到语句完成。不返回结果的语句(例如:INSERT、UPDATE 或 DELETE 语句)在对 sqlite3_step() 的一次调用中运行到完成。
此例程从 sqlite3_step() 正在评估的 预处理语句 的结果集的当前行返回单个列。每次 sqlite3_step() 停止并带有新的结果集行时,都可以多次调用此例程以查找该行中所有列的值。
如上所述,SQLite API 中实际上不存在“sqlite3_column()”函数。相反,我们在这里称为“sqlite3_column()”的是整个函数家族的占位符,这些函数以各种数据类型返回结果集中的值。此家族中也有一些例程可以返回结果的大小(如果它是字符串或 BLOB)以及结果集中的列数。
此例程销毁先前由 sqlite3_prepare() 调用创建的 预处理语句。必须使用对该例程的调用销毁每个预处理语句,以避免内存泄漏。
此例程关闭先前由对 sqlite3_open() 的调用打开的 数据库连接。在关闭连接之前,应先 完成 与该连接关联的所有 预处理语句。
应用程序通常会在初始化期间使用 sqlite3_open() 创建单个 数据库连接。请注意,sqlite3_open() 可用于打开现有数据库文件或创建和打开新数据库文件。虽然许多应用程序仅使用单个 数据库连接,但应用程序没有理由不能多次调用 sqlite3_open() 以打开多个 数据库连接 - 无论是到同一个数据库还是到不同的数据库。有时,多线程应用程序会为每个线程创建单独的 数据库连接。请注意,单个 数据库连接 可以使用 ATTACH SQL 命令访问两个或多个数据库,因此无需为每个数据库文件都使用单独的数据库连接。
许多应用程序在关闭时使用对 sqlite3_close() 的调用来销毁其 数据库连接。或者,例如,将 SQLite 作为其 应用程序文件格式 的应用程序可能会响应“文件/打开”菜单操作打开 数据库连接,然后响应“文件/关闭”菜单销毁相应的 数据库连接。
要运行 SQL 语句,应用程序需要执行以下步骤
上述内容是有效使用 SQLite 所真正需要知道的全部内容。其余都是优化和细节。
sqlite3_exec() 接口是一个便捷包装器,它通过单个函数调用执行上述所有四个步骤。传递到 sqlite3_exec() 中的回调函数用于处理结果集的每一行。sqlite3_get_table() 是另一个便捷包装器,它执行上述所有四个步骤。sqlite3_get_table() 接口与 sqlite3_exec() 的区别在于它将查询结果存储在堆内存中,而不是调用回调函数。
重要的是要意识到,sqlite3_exec() 和 sqlite3_get_table() 都没有做任何使用核心例程无法完成的事情。事实上,这些包装器完全是用核心例程实现的。
在之前的讨论中,假设每个 SQL 语句都准备一次、评估一次,然后销毁。但是,SQLite 允许多次评估相同的 预处理语句。这是通过以下例程完成的
当一个预处理语句已经被一个或多个对sqlite3_step()的调用执行后,可以通过调用sqlite3_reset()将其重置以便再次执行。可以将sqlite3_reset()理解为将预处理语句程序回退到起始位置。对于现有的预处理语句使用sqlite3_reset()而不是创建一个新的预处理语句可以避免不必要的sqlite3_prepare()调用。对于许多SQL语句,运行sqlite3_prepare()所需的时间等于或超过sqlite3_step()所需的时间。因此,避免调用sqlite3_prepare()可以显著提高性能。
重复执行**完全相同**的SQL语句通常没有意义。更常见的情况是需要执行类似的语句。例如,您可能希望使用不同的值多次执行INSERT语句。或者,您可能希望使用WHERE子句中的不同键多次执行相同的查询。为了满足这一需求,SQLite允许SQL语句包含参数,这些参数在执行前会绑定到值上。之后可以更改这些值,并使用新值再次执行相同的预处理语句。
SQLite允许在查询或数据修改语句中任何允许使用字符串字面量、blob字面量、数值常量或NULL的地方使用参数。(DQL或DML)(参数不能用于列名或表名,也不能用作约束或默认值。(DDL))参数采用以下形式之一
在上面的示例中,NNN是一个整数值,AAA是一个标识符。参数最初的值为NULL。在第一次调用sqlite3_step()之前或立即在sqlite3_reset()之后,应用程序可以调用sqlite3_bind()接口将值绑定到参数。每次调用sqlite3_bind()都会覆盖同一参数上的先前绑定。
应用程序可以预先准备多个SQL语句,并在需要时执行它们。对未完成的预处理语句的数量没有任意限制。一些应用程序在启动时多次调用sqlite3_prepare()来创建所有它们将需要使用的预处理语句。其他应用程序会缓存最近使用的预处理语句,然后在可用时重用缓存中的预处理语句。另一种方法是在循环内部仅重用预处理语句。
SQLite的默认配置对于大多数应用程序来说都非常适用。但有时开发人员希望调整设置,以尝试榨取更多性能,或利用某些鲜为人知的功能。
可以使用sqlite3_config()接口对SQLite进行全局的、进程范围的配置更改。sqlite3_config()接口必须在创建任何数据库连接之前调用。sqlite3_config()接口允许程序员执行以下操作
在完成进程范围的配置并创建数据库连接之后,可以使用对sqlite3_limit()和sqlite3_db_config()的调用来配置各个数据库连接。
SQLite包含可用于扩展其功能的接口。这些例程包括
可以使用sqlite3_create_collation()接口创建用于对文本进行排序的新排序规则。可以使用sqlite3_create_module()接口注册新的虚拟表实现。可以使用sqlite3_vfs_register()接口创建新的VFS。
可以使用sqlite3_create_function()接口创建新的SQL函数 - 标量函数或聚合函数。新的函数实现通常会使用以下附加接口
SQLite的所有内置SQL函数都是使用完全相同的接口创建的。请参考SQLite源代码,特别是date.c和func.c源文件以获取示例。
共享库或DLL可以用作SQLite的可加载扩展。
本文仅提及了SQLite中最重要的和最常用的接口。SQLite库包含许多其他实现有用功能的API,此处未作描述。在函数完整列表中可以找到构成SQLite应用程序编程接口的所有函数,该列表位于C/C++接口规范中。请参考该文档以获取有关所有SQLite接口的完整和权威信息。
此页面上次修改于2023-10-10 17:29:48 UTC