2016-07-22 30 views
0

以下觀察結果在大型sqlite3數據庫上。在sqlite_trace回調函數上沒有名字的觸發器

設置: 我有一個視圖,它有一個字段的udpate觸發器。這個視圖的這個觸發器在不同的基礎表上有多個更新語句。這些表格還具有更新各個字段的觸發器。

另外,在我們的生產代碼中使用sqlite_trace方法進行註冊回調。此方法僅打印此給定數據庫上的活動。

觀察:

  1. 當這一觀點被該給定的字段更新後,更新基礎表的字段。
  2. 更新基礎表上的字段觸發其各自的觸發器。
  3. 調用了註冊的回調方法,該方法顯示使用觸發器名稱在數據庫上調用TRIGGER。

但是,有一些觸發器沒有名稱。或者回調方法只打印沒有名字的TRIGGER。例如:

- 更新視圖V1

- TRIGGER T1

- TRIGGER T2

- TRIGGER

- TRIGGER T3

- TRIGGER

- TRIGGER T4

我的問題是:這些是什麼未命名的觸發器?他們什麼時候打電話?這是因爲一些字段在表上有UPDATE RESTRICT/DELETE RESTRICT/CASCADE?我無法從這些觸發器獲得任何信息。試圖解決這些未命名的觸發器的奧祕。

+0

此處沒有人知道您定義了什麼觸發器。 –

回答

1

未命名的觸發器是因爲一個表與另一個表的引用完整性(外鍵)關係。

重現步驟:

第一步:創建兩個表,其中一個表引用其他表,並創建這些表在一​​些測試行。 T1可以有CASCADE OR RESTRICT用於刪除或更新。

CREATE TABLE T (id NUMBER); 
CREATE TABLE T1 (id NUMBER REFERENCES T (id) DELETE (CASCADE/RESTRICT) UPDATE (CASCADE /RESTRICT)); 

步驟2:寫測試C++程序,創建一個sqlite3的連接。有關SQLite C/C++接口的更多信息,請參閱https://www.sqlite.org/cintro.html

步驟3:啓用使用sqlite3_exec

PRAGMA FOREIGN_KEY=ON . 

步驟4以下:註冊與sqlite3_trace回調,打印在回調查詢。參見:https://www.sqlite.org/c3ref/profile.html

第5步:調用execute方法來更新表T的ID

輸出:上面的語句將執行表T的更新和T.的被引用的表在這種情況下,它的T1。表T1上的更新生成未命名的觸發器,並在sqlite3_trace上生成回調。在回調的SQL中沒有這個觸發信息,因此輸出如下,即沒有名稱觸發:

TRIGGER - 

結論:的未命名的觸發器,因爲外鍵關係可見。當修改引用的表時,將嘗試更改其關聯的 表,導致在sqlite3_trace回調中導致未命名的觸發器。

注意:每個引用都會有一個未命名的觸發器。所以,如果一個字段在n個表中被引用,你會在sqlite3_trace上看到n個未命名的觸發器和n個回調。此外,數據庫應該具有PRAGMA FOREIGN_KEY ON,以便它強制執行參照完整性。 如果PRAGMA FOREIGN_KEY爲OFF(0),則不會看到此行爲。