在sqlite_trace回调函数上没有名字的触发器

问题描述:

以下观察结果在大型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

此处没有人知道您定义了什么触发器。 –

未命名的触发器是因为一个表与另一个表的引用完整性(外键)关系。

重现步骤:

第一步:创建两个表,其中一个表引用其他表,并创建这些表在一​​些测试行。 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),则不会看到此行为。