#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 使用 SQLITE_ENABLE_PREUPDATE_HOOK 編譯時選項編譯時才可用。
sqlite3_preupdate_hook() 介面會註冊一個回呼函式,該函式會在資料庫表格上的每個 INSERT、UPDATE 和 DELETE 操作之前被呼叫。在單個 資料庫連線 上一次最多可以註冊一個更新前掛鉤;每次呼叫 sqlite3_preupdate_hook() 都會覆蓋先前的設定。透過使用 NULL 指標作為第二個參數呼叫 sqlite3_preupdate_hook() 可以停用更新前掛鉤。sqlite3_preupdate_hook() 的第三個參數會作為回呼的第一個參數傳遞。
更新前掛鉤僅針對實際資料庫表格的變更觸發;對於 虛擬表格 或 sqlite_sequence 或 sqlite_stat1 等系統表格的變更,不會呼叫更新前掛鉤。
更新前回呼的第二個參數是指向註冊更新前掛鉤的 資料庫連線 的指標。更新前回呼的第三個參數是常數 SQLITE_INSERT、SQLITE_DELETE 或 SQLITE_UPDATE 之一,用於識別即將發生的更新操作類型。更新前回呼的第四個參數是被修改的資料庫連線中資料庫的名稱。對於主資料庫,它將是 "main";對於 TEMP 表格,它將是 "temp";對於附加資料庫,它將是 ATTACH 陳述式中 AS 關鍵字後面的名稱。更新前回呼的第五個參數是被修改的表格的名稱。
對於 rowid 表格 上的 UPDATE 或 DELETE 操作,傳遞給更新前回呼的第六個參數是被修改或刪除的列的初始 rowid。對於 rowid 表格上的 INSERT 操作,或 WITHOUT ROWID 表格上的任何操作,第六個參數的值未定義。對於 rowid 表格上的 INSERT 或 UPDATE,第七個參數是被插入或更新的列的最終 rowid 值。對於 WITHOUT ROWID 表格上的操作或 rowid 表格上的 DELETE 操作,傳遞給回呼函式的第七個參數的值未定義。
sqlite3_preupdate_hook(D,C,P) 函式會傳回在同一個 資料庫連線 D 上先前呼叫的 P 參數,或者對於 D 上的第一次呼叫,則傳回 NULL。
sqlite3_preupdate_old()、sqlite3_preupdate_new()、sqlite3_preupdate_count() 和 sqlite3_preupdate_depth() 介面提供關於更新前事件的額外資訊。這些常式只能在更新前回呼內呼叫。從更新前回呼外部呼叫這些常式,或使用與提供給更新前回呼的 資料庫連線 指標不同的指標,將導致未定義且可能不理想的行為。
sqlite3_preupdate_count(D) 介面會傳回被插入、更新或刪除的列中的欄位數。
sqlite3_preupdate_old(D,N,P) 介面會將一個指向 受保護的 sqlite3_value 的指標寫入 P 中,該 sqlite3_value 包含表格列中第 N 個欄位在更新前的值。參數 N 必須介於 0 到欄位數減 1 之間,否則行為將未定義。這只能在 SQLITE_UPDATE 和 SQLITE_DELETE 的 preupdate 回呼函式中使用;如果在 SQLITE_INSERT 回呼函式中使用,則行為未定義。P 指向的 sqlite3_value 將在 preupdate 回呼函式返回時被銷毀。
sqlite3_preupdate_new(D,N,P) 介面會將一個指向 受保護的 sqlite3_value 的指標寫入 P 中,該 sqlite3_value 包含表格列中第 N 個欄位在更新後的值。參數 N 必須介於 0 到欄位數減 1 之間,否則行為將未定義。這只能在 SQLITE_INSERT 和 SQLITE_UPDATE 的 preupdate 回呼函式中使用;如果在 SQLITE_DELETE 回呼函式中使用,則行為未定義。P 指向的 sqlite3_value 將在 preupdate 回呼函式返回時被銷毀。
sqlite3_preupdate_depth(D) 介面會返回 0,如果 preupdate 回呼函式是由直接插入、更新或刪除操作所觸發;返回 1 表示由頂層觸發器觸發的插入、更新或刪除;返回 2 表示由頂層觸發器呼叫的觸發器所造成的變更,依此類推。
當使用 sqlite3_blob_write() API 更新 BLOB 欄位時,preupdate 鉤子會以 SQLITE_DELETE 觸發。這是因為在這種情況下,新值不可用。在這種情況下,當 op==SQLITE_DELETE 的回呼實際上是使用 sqlite3_blob_write() API 進行寫入時,sqlite3_preupdate_blobwrite() 會返回正在寫入的欄位的索引。在其他情況下,當 preupdate 鉤子因其他原因(包括一般的 DELETE)被觸發時,sqlite3_preupdate_blobwrite() 會返回 -1。