SQLite C 接口
预更新挂钩。
#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()接口注册一个回调函数,该函数在数据库表上的每个INSERT、UPDATE和DELETE操作之前调用。一次最多可以在单个 数据库连接上注册一个预更新挂钩;每次调用sqlite3_preupdate_hook()都会覆盖之前的设置。 通过使用 NULL 指针作为第二个参数调用sqlite3_preupdate_hook()来禁用预更新挂钩。sqlite3_preupdate_hook()的第三个参数作为第一个参数传递给回调。
preupdate 挂钩仅在对真实数据库表进行更改时触发;不会调用 preupdate 挂钩来更改虚拟表或系统表,如 sqlite_sequence 或 sqlite_stat1。
预更新回调的第二个参数是指向注册预更新挂钩的数据库连接的指针。preupdate 回调的第三个参数是常量 SQLITE_INSERT、SQLITE_DELETE或SQLITE_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。