我想删除包含外键的行,但是当我尝试这样的事情时:
DELETE FROM osoby WHERE id_osoby='1'
我得到这个声明:
错误:表“osoby”上的更新或删除违反了表“kontakty”上的外键约束“kontakty_ibfk_1”详细信息:键(id_osoby)=(1)仍然从表“kontakty”中引用。
如何删除这些行?
我想删除包含外键的行,但是当我尝试这样的事情时:
DELETE FROM osoby WHERE id_osoby='1'
我得到这个声明:
错误:表“osoby”上的更新或删除违反了表“kontakty”上的外键约束“kontakty_ibfk_1”详细信息:键(id_osoby)=(1)仍然从表“kontakty”中引用。
如何删除这些行?
要自动执行此操作,您可以使用 定义外键约束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
在 table上锁定kontakty
并SHARE ROW EXCLUSIVE
在 table 上锁定osoby
。
如果您不能ALTER
使用该表,则剩下的选项是手动(一次)或触发器BEFORE DELETE
(每次)删除。
如果外键仍然引用另一个表,则不能删除它。首先删除引用
delete from kontakty
where id_osoby = 1;
DELETE FROM osoby
WHERE id_osoby = 1;
不应将此作为一般解决方案推荐,但对于一次性删除数据库中非生产或活动使用的行,您可以暂时禁用相关表上的触发器。
就我而言,我处于开发模式,并且有几个表通过外键相互引用。因此,删除它们的内容并不像先从一个表中删除所有行那么简单。所以,对我来说,删除它们的内容很好,如下所示:
ALTER TABLE table1 DISABLE TRIGGER ALL;
ALTER TABLE table2 DISABLE TRIGGER ALL;
DELETE FROM table1;
DELETE FROM table2;
ALTER TABLE table1 ENABLE TRIGGER ALL;
ALTER TABLE table2 ENABLE TRIGGER ALL;
您应该能够根据需要添加 WHERE 子句,当然要小心避免破坏数据库的完整性。
在http://www.openscope.net/2012/08/23/subverting-foreign-key-constraints-in-postgres-or-mysql/上有一些很好的相关讨论
很久没问这个问题了,希望能帮到你。因为您无法更改或更改 db 结构,所以您可以这样做。根据 postgresql文档。
TRUNCATE -- 清空一个表或一组表。
TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
描述
TRUNCATE 从一组表中快速删除所有行。它与每个表上的非限定 DELETE 具有相同的效果,但由于它实际上并不扫描表,因此速度更快。此外,它会立即回收磁盘空间,而不需要后续的 VACUUM 操作。这在大表上最有用。
截断表 othertable,并级联到通过外键约束引用 othertable 的任何表:
TRUNCATE othertable CASCADE;
同样,也重置任何关联的序列生成器:
TRUNCATE bigtable, fattable RESTART IDENTITY;
截断并重置任何关联的序列生成器:
TRUNCATE revinfo RESTART IDENTITY CASCADE ;
这意味着在表kontakty
中有一行引用了osoby
要删除的行。您必须先删除该行或对表之间的关系设置级联删除。
波沃兹尼亚!