网站建设与管理实验目的,企业网络工程建设方案,北京建设信源网站 怎么打不开,建设网站包维护返回目录#xff1a;SQLite—免费开源数据库系列文章目录
上一篇#xff1a;SQLiteC/C接口详细介绍之sqlite3类#xff08;十二#xff09;
下一篇#xff1a;SQLiteC/C接口详细介绍之sqlite3类#xff08;十四#xff09;#xff08;未发表#xff09; 40.sqlite3…返回目录SQLite—免费开源数据库系列文章目录
上一篇SQLiteC/C接口详细介绍之sqlite3类十二
下一篇SQLiteC/C接口详细介绍之sqlite3类十四未发表 40.sqlite3_preupdate_blobwrite
用于将预更新钩子中的列值更改为BLOB值。
SQLite3预更新钩子是一种特殊类型的回调函数在执行INSERT、UPDATE、DELETE语句时触发允许您查看更改之前和之后的列值并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。
sqlite3_preupdate_blobwrite函数是预更新钩子的一种特殊类型允许您将列值更改为BLOB值。这是在预更新钩子中更新大型二进制数据类型例如图像或文件时非常有用的情况。
以下是sqlite3_preupdate_blobwrite函数的声明
void sqlite3_preupdate_blobwrite(sqlite3 *db, void *pAux, int iKey1, int iKey2, int iIdx, const void *pData, int nData);
其中sqlite3是指向SQLite3数据库实例的指针pAux是指向与预更新钩子相关联的自定义数据的指针iKey1、iKey2和iIdx参数指定正在更新的行和列的索引。pData和nData参数指定要写入的BLOB数据以及数据的长度。
注意
sqlite3_preupdate_blobwrite函数需要在预更新钩子中注册使用sqlite3session_preupdate_hook函数将其注册到数据库会话中。
下面是一个简单的示例展示如何使用sqlite3_preupdate_blobwrite函数在SQLite3中预更新BLOB列
#include sqlite3.h
#include stdio.h
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode SQLITE_UPDATE) {printf(PRE-UPDATE HOOK: table%s, rowid%lld\n, tblname, rowid);// 获取预更新钩子上下文sqlite3session *pSession (sqlite3session *)pCtx;sqlite3_preupdate_data *pChanges sqlite3session_changeset(pSession, db, tblname);while (pChanges) {if (pChanges-op SQLITE_UPDATE pChanges-pChanges-nCol 0) {for (int i 0; i pChanges-pChanges-nCol; i) {sqlite3_value *pVal pChanges-pChanges-apNew[i];if (pVal sqlite3_value_type(pVal) SQLITE_BLOB) {printf(COLUMN %s WILL BE UPDATED TO BLOB\n, sqlite3_column_name(pChanges-pStmt, i));// 将列值更改为BLOBsqlite3_preupdate_blobwrite(db, NULL, pChanges-iKey1, pChanges-iKey2, i, sqlite3_value_blob(pVal), sqlite3_value_bytes(pVal));}}}pChanges pChanges-pNext;}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc sqlite3_open(test.db, db);if (rc ! SQLITE_OK) {printf(Cant open database: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc sqlite3session_create(db, temp.session, pSession);if (rc ! SQLITE_OK) {printf(Cant create session: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc sqlite3session_preupdate_hook(pSession, preupdate_callback, pSession);if (rc ! SQLITE_OK) {printf(Cant register preupdate hook: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc sqlite3_exec(db, UPDATE my_table SET my_blob_column?, NULL, NULL, NULL);if (rc ! SQLITE_OK) {printf(Cant execute statement: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}
在上面的示例代码中我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时我们遍历所有正在更新的列并将值为BLOB的列更改为新的BLOB值。在此过程中我们使用sqlite3_preupdate_blobwrite函数将列值更改为新值并打印一条调试消息以示成功。
接着我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后我们执行一个UPDATE查询更新带有一个BLOB列的表的行。更改将被捕获并处理然后将提交到数据库。
注意
预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话则可能会收到错误消息。
41.sqlite3_preupdate_count
sqlite3_preupdate_count是SQLite3 C API提供的一个函数它用于获取当前预更新操作中的更改数量。
SQLite3预更新钩子是一种特殊类型的回调函数在执行INSERT、UPDATE、DELETE语句时触发允许您查看更改之前和之后的列值并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。
sqlite3_preupdate_count函数允许您获取当前预更新操作中的更改数量这对于在预更新钩子中执行特定操作时非常有用。例如您可能需要查看更改的列是否满足特定的条件如果不符合则阻止更改并抛出错误。
以下是sqlite3_preupdate_count函数的声明
int sqlite3_preupdate_count(sqlite3 *db);
其中sqlite3是指向SQLite3数据库实例的指针。该函数返回当前预更新操作中更改的列数。
注意sqlite3_preupdate_count函数必须在预更新钩子中调用。预更新钩子由sqlite3session_preupdate_hook函数注册并在执行预更新操作时调用。
下面是一个简单的示例展示如何在SQLite3预更新钩子中使用sqlite3_preupdate_count函数
#include sqlite3.h
#include stdio.h
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode SQLITE_UPDATE) {printf(PRE-UPDATE HOOK: table%s, rowid%lld\n, tblname, rowid);// 获取预更新操作中更改的列数int nChanges sqlite3_preupdate_count(db);printf(NUMBER OF CHANGES: %d\n, nChanges);// 遍历预更新操作中的列for (int i 0; i nChanges; i) {sqlite3_preupdate_data const *p sqlite3_preupdate_data_get(db, i);if (p p-op SQLITE_UPDATE sqlite3_column_type(p-pStmt, p-iNew) SQLITE_INTEGER) {int newValue sqlite3_column_int(p-pStmt, p-iNew);printf(COLUMN #%d WILL BE UPDATED TO %d\n, i, newValue);// 检查更改的列是否符合特定条件if (newValue 0 || newValue 100) {printf(INVALID VALUE FOR COLUMN #%d\n, i);// 阻止更改并抛出错误sqlite3_preupdate_rollback(db);printf(ROLLBACK PRE-UPDATE\n);return SQLITE_ERROR;}}}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc sqlite3_open(test.db, db);if (rc ! SQLITE_OK) {printf(Cant open database: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc sqlite3session_create(db, temp.session, pSession);if (rc ! SQLITE_OK) {printf(Cant create session: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc sqlite3session_preupdate_hook(pSession, preupdate_callback, NULL);if (rc ! SQLITE_OK) {printf(Cant register preupdate hook: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc sqlite3_exec(db, UPDATE my_table SET my_columnmy_column1, NULL, NULL, NULL);if (rc ! SQLITE_OK) {printf(Cant execute statement: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}
在上面的示例代码中我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时我们使用sqlite3_preupdate_count函数获取当前预更新操作中的更改数量。然后我们遍历所有更改的列并检查它们是否符合特定条件如果不符合则阻止更改并抛出错误。在此过程中我们还使用sqlite3_preupdate_rollback函数阻止更改并恢复当前事务的其他更改。需
注意
如果在预更新钩子中使用sqlite3_preupdate_rollback函数则必须返回SQLITE_ERROR以指示错误。接着我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后我们执行一个UPDATE查询将带有一个整数列的表的行添加1。所有更改将被捕获并处理然后将提交到数据库。预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话则可能会收到错误消息。
42.sqlite3_preupdate_depth
用于获取当前预更新操作的嵌套深度。
SQLite3预更新钩子是一种特殊类型的回调函数在执行INSERT、UPDATE、DELETE语句时触发允许您查看更改之前和之后的列值并且可以修改列值、阻止更改、执行额外的更新并执行其他自定义操作。
sqlite3_preupdate_depth函数允许您获取当前预更新操作中的嵌套深度也就是当前预更新的预更新操作的数量。这对于在嵌套的预更新操作中执行特定操作时非常有用。例如当更改发生时您可能需要查找更改的列所依赖的其他列这可能需要深入预更新操作树来查找列。
以下是sqlite3_preupdate_depth函数的声明
int sqlite3_preupdate_depth(sqlite3 *db);
其中sqlite3是指向SQLite3数据库实例的指针。该函数返回当前预更新操作的嵌套深度如果没有嵌套操作则返回0。
需要注意的是sqlite3_preupdate_depth函数必须在预更新钩子中调用。预更新钩子由sqlite3session_preupdate_hook函数注册并在执行预更新操作时调用。
下面是一个简单的示例展示如何在SQLite3预更新钩子中使用sqlite3_preupdate_depth函数
#include sqlite3.h
#include stdio.h
static int preupdate_callback(void *pCtx, sqlite3 *db, int opcode, char const *dbname, char const *tblname, sqlite3_int64 rowid) {if (opcode SQLITE_UPDATE) {printf(PRE-UPDATE HOOK: table%s, rowid%lld\n, tblname, rowid);// 获取预更新操作的嵌套深度int depth sqlite3_preupdate_depth(db);printf(PRE-UPDATE DEPTH: %d\n, depth);// 检查更改的列是否依赖于其他列sqlite3_preupdate_data const *p sqlite3_preupdate_data_get(db, 0);if (depth 0 p-op SQLITE_UPDATE sqlite3_column_type(p-pStmt, p-iNew) SQLITE_INTEGER) {int newValue sqlite3_column_int(p-pStmt, p-iNew);printf(COLUMN WILL BE UPDATED TO %d\n, newValue);// 获取依赖列的值sqlite3_preupdate_data const *pDep sqlite3_preupdate_data_get_parent(db, 0);if (pDep pDep-op SQLITE_UPDATE sqlite3_column_type(pDep-pStmt, pDep-iNew) SQLITE_INTEGER) {int depValue sqlite3_column_int(pDep-pStmt, pDep-iNew);printf(COLUMN DEPENDS ON ANOTHER COLUMN WITH VALUE %d\n, depValue);}}}return SQLITE_OK;
}
int main(int argc, char* argv[]) {sqlite3* db;sqlite3_session *pSession;int rc;// 打开数据库rc sqlite3_open(test.db, db);if (rc ! SQLITE_OK) {printf(Cant open database: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 创建数据库会话rc sqlite3session_create(db, temp.session, pSession);if (rc ! SQLITE_OK) {printf(Cant create session: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 注册预更新钩子rc sqlite3session_preupdate_hook(pSession, preupdate_callback, NULL);if (rc ! SQLITE_OK) {printf(Cant register preupdate hook: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 执行UPDATE语句rc sqlite3_exec(db, UPDATE my_table SET my_columnmy_column1, NULL, NULL, NULL);if (rc ! SQLITE_OK) {printf(Cant execute statement: %s\n, sqlite3_errmsg(db));sqlite3_close(db);return 1;}// 关闭数据库和会话sqlite3session_delete(pSession);sqlite3_close(db);return 0;
}
在上面的示例代码中我们首先定义了一个预更新钩子回调函数preupdate_callback。当SQLITE_UPDATE操作码被传递给钩子时我们使用sqlite3_preupdate_depth函数获取当前预更新操作中的嵌套深度。然后如果更改的列依赖于其他列则我们获取依赖列的值并打印一条调试消息。
在此过程中我们还使用sqlite3_preupdate_data_get_parent函数获取当前预更新操作的父级预更新操作。需要注意的是只有在预更新操作嵌套时该函数才返回非空值。
接着我们创建一个SQLite3会话并将预更新钩子注册到会话中。最后我们执行一个UPDATE查询将带有一个整数列的表的行添加1。所有更改将被捕获并处理然后将提交到数据库。
需要注意的是预更新钩子仅在SQLite3的session扩展模块中可用。如果尝试将预更新钩子用于普通的SQLite3会话则可能会收到错误消息。