postgresql - “不可延迟的约束触发器”和正常的“事件后行级触发器”之间有什么区别吗?
问题描述
当检查约束时,我得到一个正常约束 [NOT] DEFERRABLE {INITIALLY IMMEDIATE/INITIALLY DEFERRED} 更改:在每个操作之后/每个语句之后/每个事务之后。同样对于可延迟触发器,我们可以使用“SET CONSTRAINTS”。
但似乎“不可延迟的约束触发器”在每行的语句末尾触发,就像正常的“事件后行级触发器”一样。同样对于此类触发器,我们不能使用 SET CONSTRAINTS,因为我们已将其声明为 NOT DEFERRABLE。
例如,在此代码中,触发器将所有可见的内容复制到名为“copy_example”的表中
CREATE TABLE example (
ex INT);
CREATE TABLE copy_example (
ex_copy INT);
CREATE FUNCTION save_copy()
RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
INSERT INTO copy_example (SELECT * FROM example);
RETURN NEW;
END;
$$;
CREATE CONSTRAINT TRIGGER execute_copy
AFTER INSERT
ON example
NOT DEFERRABLE
FOR EACH ROW
EXECUTE FUNCTION save_copy();
INSERT INTO example VALUES (1), (2);
SELECT * FROM copy_example;
代码输出一个包含值 (1, 2, 1, 2) 而不是 (1, 1, 2) 的表,就像普通触发器一样。那么为什么要定义一个不可延迟的约束触发器而不是一个正常的触发器呢?他们的行为有什么不同吗?
解决方案
不,定义不可延迟的约束触发器是没有意义的。
该文档准确地描述了该行为:
指定选项时
CONSTRAINT
,此命令会创建一个约束触发器。这与常规触发器相同,只是可以使用 调整触发器触发的时间SET CONSTRAINTS
。约束触发器必须是AFTER ROW
普通表(不是外部表)上的触发器。它们可以在导致触发事件的语句结束时触发,也可以在包含事务结束时触发;在后一种情况下,它们被称为延迟。一个挂起的延迟触发触发也可以通过使用强制立即发生SET CONSTRAINTS
。约束触发器应该在它们实现的约束被违反时引发异常。
推荐阅读
- opengl - 我可以在不计算自己的情况下轻松获得 Uniform Block 的元素对齐偏移量吗?
- ios - SwiftUI导航到详细信息和返回时如何在For Each循环中保持滚动位置
- sql - SQL - 用户统计表?
- javascript - 一个组件中有多个按钮 TypeError: onChange (prop) is not a function (dealing with props) React
- apache-spark - 将大数据从 Hadoop 导入 Spark 的有效方法
- kubernetes - 如何手动检查 k8s 部署是否通过/失败?
- mysql - 节点 Lambda:MySQL 查询从不运行
- python - 在 Python 中输出输入的每个字符的 ASCII 值的总和
- json.net - Newtonsoft JsonConvert DeserializeObject 不能忽略实体错误的默认值?
- python - 如何拆分 Python 代码的输出?