在 PostgreSQL 中使用外键删除行

新手上路,请多包涵

我想删除包含外键的行,但是当我尝试这样的事情时:

 DELETE FROM osoby WHERE id_osoby='1'

我得到这个声明:

错误:表“osoby”上的更新或删除违反了表“kontakty”上的外键约束“kontakty_ibfk_1”详细信息:键(id_osoby)=(1)仍然从表“kontakty”中引用。

如何删除这些行?

原文由 Michal Loksik 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 573
2 个回答

要自动执行此操作,您可以使用 ON DELETE CASCADE 定义外键约束。

我引用了 外键约束的手册

CASCADE 指定当引用的行被删除时,引用它的行也应该被自动删除。

像这样查找当前的 FK 定义:

 SELECT pg_get_constraintdef(oid) AS constraint_def
FROM   pg_constraint
WHERE  conrelid = 'public.kontakty'::regclass  -- assuming public schema
AND    conname = 'kontakty_ibfk_1';

然后在如下语句中添加或修改 ON DELETE ... 部分到 ON DELETE CASCADE (保留其他所有内容):

 ALTER TABLE kontakty
   DROP CONSTRAINT kontakty_ibfk_1
 , ADD  CONSTRAINT kontakty_ibfk_1
   FOREIGN KEY (id_osoby) REFERENCES osoby (id_osoby) ON DELETE CASCADE;

没有 ALTER CONSTRAINT 命令。在单个 ALTER TABLE 语句中删除并重新创建约束以避免并发写访问可能出现的竞争条件。

显然,您需要特权才能这样做。该操作需要一个 ACCESS EXCLUSIVE 锁定表 kontakty 和一个 SHARE ROW EXCLUSIVE 锁定表 osoby

如果您不能 ALTER 表,则手动(一次)或通过触发器删除 BEFORE DELETE (每次)是剩余的选项。

原文由 Erwin Brandstetter 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果外键仍然引用另一个表,则不能删除它。首先删除引用

delete from kontakty
where id_osoby = 1;

DELETE FROM osoby
WHERE id_osoby = 1;

原文由 juergen d 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进