以下观察是在一个大型的sqlite3数据库上。
设定: 我有一个视图,它有一个字段的udpate触发器。此视图的此触发器在不同的基础表上具有多个更新语句。这些表还具有更新相应字段的触发器。
此外,在我们的生产代码上使用sqlite_trace方法进行了注册回调。此方法仅在此给定数据库上打印活动。
观察:
但是,有一些没有名字的触发器。或者回调方法只打印没有名称的TRIGGER。例如:
- 更新View V1
- TRIGGER T1
- TRIGGER T2
- TRIGGER
- TRIGGER T3
- TRIGGER
- TRIGGER T4
我的问题是:这些未命名的触发器是什么?它们何时被调用?这是因为某些字段在表上有UPDATE RESTRICT / DELETE RESTRICT / CASCADE吗?我无法从这些触发器中获取任何信息。只是试图解开这些未命名的触发器之谜。
答案 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),则不会看到此行为。