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

时间:2016-07-22 19:13:16

标签: triggers sqlite trace

以下观察是在一个大型的sqlite3数据库上。

设定: 我有一个视图,它有一个字段的udpate触发器。此视图的此触发器在不同的基础表上具有多个更新语句。这些表还具有更新相应字段的触发器。

此外,在我们的生产代码上使用sqlite_trace方法进行了注册回调。此方法仅在此给定数据库上打印活动。

观察:

  1. 为此给定字段更新此视图时,它会更新基础表的字段。
  2. 更新基础表上的字段会触发各自的触发器。
  3. 调用已注册的回调方法,该方法使用触发器名称打印在数据库上调用TRIGGER。
  4. 但是,有一些没有名字的触发器。或者回调方法只打印没有名称的TRIGGER。例如:

    - 更新View V1

    - TRIGGER T1

    - TRIGGER T2

    - TRIGGER

    - TRIGGER T3

    - TRIGGER

    - TRIGGER T4

    我的问题是:这些未命名的触发器是什么?它们何时被调用?这是因为某些字段在表上有UPDATE RESTRICT / DELETE RESTRICT / CASCADE吗?我无法从这些触发器中获取任何信息。只是试图解开这些未命名的触发器之谜。

1 个答案:

答案 0 :(得分:1)

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

重现的步骤:

Step1:创建两个表,其中一个表引用其他表,并在这些表中创建一些测试行。 T1可以使用CASCADE OR RESTRICT进行删除或更新。

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

第2步:编写一个创建sqlite3连接的测试C ++程序。有关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的UPDATE和T的引用表。在这种情况下,它的T1。表T1上的更新生成未命名的触发器,并在sqlite3_trace上生成回调。回调中的sql没有关于此触发器的信息,因此输出如下所示,即没有名称的触发器:

TRIGGER - 
  

结论:由于外键关系,可以看到未命名的触发器。修改引用的表时,将其关联   尝试更改表,导致sqlite3_trace回调中出现未命名的触发器。

     

注意:每个引用都会有一个未命名的触发器。因此,如果在n个表中引用了一个字段,您将看到n未命名   sqlite3_trace上的触发器和n个回调。此外,数据库应该   有PRAGMA FOREIGN_KEY ON,以便它强制执行参照完整性。   如果PRAGMA FOREIGN_KEY为OFF(0),则不会看到此行为。