返回:SQLite—系列文章目录
上一篇:SQLite如何处理CSV 虚拟表
下一篇:SQLite—系列文章目录
1. 概述
Carray()是一个具有单列的表值函数(名为 “value”)和零行或多行。 carray() 中每一行的“值”取自 C 语言数组 由应用程序通过参数绑定提供。 这样,carray()函数提供了一种方便的机制来 将 C 语言数组绑定到 SQL 查询。
2. 可用性
默认情况下,carray()函数不会编译为 SQLite。 它可作为 ext/misc/carray.c 源文件中的可加载扩展名使用。
carray()函数在 3.14 版中首次添加到 SQLite 中(2016-08-08). sqlite3_carray_bind() 接口和 在 SQLite 版本 3.34.0 中添加了 carray()的单参数变体(2020-12-01). 在 SQLite 版本 3.41.0 中添加了绑定被解释为 BLOB 的 struct iovec 对象数组的功能 (2023-02-21).
3. 详情
carray()函数接受一个、两个或三个参数。
对于 carray()的 2 个和 3 个参数版本, 第一个参数是指向数组的指针。由于指针值不能 直接在 SQL 中指定,第一个参数必须是 使用 sqlite3_bind_pointer()接口绑定到指针值 使用指针类型“Carray”。 第二个参数是数组中的元素数。可选的 第三个参数是确定元素数据类型的字符串 在 C 语言数组中。第三个参数允许的值为:
- 'int32'
- “int64”
- “双倍”
- 'char*'
- 'struct iovec'
默认数据类型为“int32”。
用于 BLOB 数据的“struct iovec”类型是标准的 Posix 数据 结构,通常使用“#include < sys/uio.h>”声明。 格式为:
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes to transfer */
};
3.1. 单参数CARRAY
carray()的单参数形式需要特殊的 C 语言 名为“sqlite3_carray_bind()”的接口,以便附加值:
int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement containing the CARRAY */
int idx, /* Parameter number for CARRAY argument */
void *aData, /* Data array */
int nData, /* Number of entries in the array */
int mFlags, /* Datatype flag */
void (*xDestroy)(void*) /* Destructor for aData */
);
sqlite3_carray_bind() 的 mFlags 参数必须是以下参数之一:
#define CARRAY_INT32 0
#define CARRAY_INT64 1
#define CARRAY_DOUBLE 2
#define CARRAY_TEXT 3
#define CARRAY_BLOB 4
mFlags 参数的高阶位现在必须全部为零, 尽管它们可能会在将来的增强功能中使用。的定义 指定数据类型和 原型的常量 sqlite3_carray_bind()函数在辅助函数中都可用 头文件 ext/misc/carray.h。
sqlite3_carray_bind()例程的 xDestroy 参数是一个指针 到释放输入数组的函数。SQLite 将调用此 函数。xDestroy 参数 可以是 “sqlite3.h”:
-
SQLITE_STATIC → 这意味着调用 sqlite3_carray_bind()维护数据数组的所有权,并且 应用程序向 SQLite 承诺它不会更改或解除分配 在预处理的语句最终化之前的数据。
-
SQLITE_TRANSIENT → 此特殊值指示 SQLite 使 它自己的数据的私有副本之前 sqlite3_carray_bind()接口返回。
4. 用法
carray()函数可用于查询的 FROM 子句。 例如,使用 rowids 从 OBJ 表中查询两个条目 取自地址 $PTR 处的 C 语言数组。
SELECT obj.* FROM obj, carray($PTR, 10) AS x
WHERE obj.rowid=x.value;
此查询给出相同的结果:
SELECT * FROM obj WHERE rowid IN carray($PTR, 10);
5.例程
以下是一个使用Carray()函数的简单示例:
#include <stdio.h>
#include <sqlite3.h>
/* 回调函数 */
static int callback(void * data, int argc, char ** argv, char ** colName) {
int i;
for (i = 0; i < argc; i++) {
printf("%s = %s\n", colName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
/* 主函数 */
int main(int argc, char ** argv) {
sqlite3 * db;
char *errmsg = 0;
int ret;
char * select = "SELECT * FROM Company;";
char * data[10][3]; // 用于存储SQLite的查询结果(Company表)
/* 打开SQLite数据库 */
ret = sqlite3_open("Test.db", &db);
if (ret) {
fprintf(stderr, "无法打开数据库:%s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
/* 执行SQLite查询语句并将结果存储在已分配的内存空间中 */
ret = sqlite3_exec(db, select, callback, data, &errmsg);
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL语句执行失败:%s\n", errmsg);
sqlite3_free(errmsg);
sqlite3_close(db);
return 1;
}
/* 打印查询结果 */
int i;
for(i=0; i<10; i++) {
printf("%s %s %s\n", data[i][0], data[i][1], data[i][2]);
}
/* 关闭SQLite数据库 */
sqlite3_close(db);
return 0;
}
在这个示例中,我们使用Carray()函数将SQLite表(Company表)的结果读取到预分配好的容器数组(包含3个字段和10个记录)data中。回调函数callback被频繁调用,用于将结果集中的字段和值复制到容器数据中。最后,我们打印了结果以确认它已成功地读取到了容器数组中。
这个示例可以帮助你更好地理解Carray()函数和回调函数的用法。