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

trigger with no name on sqlite_trace callback function

下面的观察是在大型 sqlite3 数据库上进行的。

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

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

观察:

  1. 当针对此给定字段更新此视图时,它会更新基础表的字段。
  2. 更新基础表上的字段会触发它们各自的触发器。
  3. 注册的回调方法被调用,它打印出在数据库上使用触发器名称调用了 TRIGGER。

但是,有些触发器没有名称。或者回调方法只打印不带名称的 TRIGGER。例如:

-- 更新视图 V1

-- 触发 T1

-- 触发 T2

--触发

-- 触发 T3

--触发

-- 触发 T4

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

未命名的触发器是因为一个 table 与另一个 table.

的引用完整性(外键)关系

重现步骤:

第 1 步: 创建两个 table,其中一个 table 引用另一个 table 并在这些 table 中创建一些测试行]s。 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

第五步:调用execute方法更新tableT的id。

输出: 上面的语句将执行 table T 的 UPDATE 和 T 的引用 tables。在这种情况下,它的 T1。 table T1 上的更新生成未命名的触发器,并在 sqlite3_trace 上生成回调。回调中的 sql 没有关于此触发器的信息,因此输出如下,即没有名称的触发器:

TRIGGER - 

Conclusion : The un-named triggers are seen because of the foreign key relationship. When a referenced table is modified, its associated tables are attempted to change causing un-named triggers in sqlite3_trace callbacks.

Note : There will be an un-named trigger for each reference. So, if a field is referenced in n tables , you will see n un-named triggers and n callbacks on sqlite3_trace. Also, the database should have PRAGMA FOREIGN_KEY ON so that it enforces referential integrity. You will not see this behavior if PRAGMA FOREIGN_KEY is OFF ( 0 ).