【问题标题】:postgresql, deferred constraint not working as I expectpostgresql,延迟约束没有像我预期的那样工作
【发布时间】:2022-08-02 15:43:06
【问题描述】:

我正在努力理解 DEFERRED 约束在 postgres 中的工作方式(如果重要,v13)。

我有以下架构和数据:

CREATE TEMP TABLE t1 (
  id int,
  CONSTRAINT unique_id PRIMARY KEY (id)
);

CREATE TEMP TABLE t2 (
  id int,
  ref int,
  CONSTRAINT fk FOREIGN KEY (ref) REFERENCES t1 (id) ON DELETE SET NULL DEFERRABLE INITIALLY IMMEDIATE
);

INSERT INTO t1 VALUES (1);
INSERT INTO t2 (id,ref) VALUES (1,1);

然后我执行以下指令:

BEGIN;
SET CONSTRAINTS ALL DEFERRED;

DELETE FROM t1;
INSERT INTO t1 VALUES (1);
COMMIT;

因为约束被延迟,我希望 ON DELETE SET NULL 在事务结束时触发并保留从t1t2 的链接。然而事实并非如此。

SELECT * FROM t2;
 id | ref 
----+-----
  1 |    
(1 row)

我在这里想念什么?

    标签: postgresql


    【解决方案1】:

    DEFERRABLE 仅意味着查看如果没有行违反约束,则推迟到事务提交为止。它确实不是意味着影响您运行的 DML 将被推迟到事务结束。

    在事务结束时的示例中,t2 中的任何行都没有违反外键约束。所以 COMMIT 是成功的。

    此外:DELETE FROM t1 会将包含已删除 ID 的表 t2 中的所有 ref 列设置为 NULL。如果你在t1 中插入一个新行,Postgres 应该如何知道ref 的哪些(可能是数百万个)为NULL 的列重置为初始值?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-19
      • 2013-04-11
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      • 1970-01-01
      • 2023-01-01
      • 2014-06-28
      相关资源
      最近更新 更多