3

假设我有一张schools桌子

CREATE TABLE "public"."schools" (
    "id" text NOT NULL,
    "ancestor_id" text,
    CONSTRAINT "schools_ancestor_id_fkey" FOREIGN KEY ("ancestor_id") REFERENCES "public"."schools"("id"),
    PRIMARY KEY ("id")
);

我想插入多个值schools

INSERT INTO schools (id, ancestor_id) VALUES ('school 1', 'ancestor 1'), ('ancestor 1', NULL)

我预计插入查询会引发外键异常,但它实际上成功插入了 2 行。

有谁知道这是为什么?我查看了插入文档,但没有提到任何类似的情况。

4

2 回答 2

4

外键约束通过 PostgreSQL 中的触发器实现。这没有直接记录,但您可以在此处间接看到

可以禁用或启用由名称指定的单个触发器,或表上的所有触发器,或仅用户触发器(此选项不包括内部生成的约束触发器,例如用于实现外键约束或可延迟唯一性和排除约束的那些)。

你也可以看到它

SELECT * FROM pg_trigger
WHERE tgrelid = 'schools'::regclass;

触发器的触发规则已记录并适用于外键:

行级BEFORE触发器在操作特定行之前立即触发,而行级AFTER触发器在语句结束时触发(但在任何语句级AFTER触发器之前)。

(强调我的)

因此,在完成完整语句后验证外键。

于 2020-11-19T13:05:02.673 回答
3

外键是在语句完成后评估的,而不是在每一行之后。

这就是为什么在单个语句中删除它们也有效的原因:

delete from schools 
where id in ('school 1', 'ancestor 1');
于 2020-11-19T13:03:06.420 回答