我想删除包含外键的行,但是当我尝试这样的事情时:
DELETE FROM osoby WHERE id_osoby='1'
我得到这个声明:
错误:表“osoby”上的更新或删除违反表“kontakty”上的外键约束“kontakty_ibfk_1”DETAIL:键(id_osoby)=(1)仍然从表“kontakty”引用。
如何删除这些行?
要自动执行此操作,您可以使用ON DELETE CASCADE
定义外键约束。
我引用the manual of foreign key constraints:
CASCADE
指定当删除引用的行时,也应自动删除引用它的行。
查找当前的FK定义,如下所示:
SELECT pg_get_constraintdef(oid) AS constraint_def
FROM pg_constraint
WHERE conrelid = 'public.kontakty'::regclass -- assuming pubic 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
(每次)删除是剩余的选项。
如果外键仍引用另一个表,则无法删除该外键。首先删除引用
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/有一些很好的相关讨论
自问这个问题以来已经有一段时间了,希望能有所帮助。因为您无法更改或更改数据库结构,所以可以执行此操作。根据postgresql docs。
TRUNCATE - 清空一个表或一组表。
TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
描述
TRUNCATE快速删除一组表中的所有行。它与每个表上的非限定DELETE具有相同的效果,但由于它实际上不扫描表,因此速度更快。此外,它立即回收磁盘空间,而不是需要后续的VACUUM操作。这对大型表最有用。
截断表othertable,并级联到任何通过外键约束引用其他表的表:
TRUNCATE othertable CASCADE;
相同,并重置任何相关的序列生成器:
TRUNCATE bigtable, fattable RESTART IDENTITY;
截断并重置任何关联的序列生成器:
TRUNCATE revinfo RESTART IDENTITY CASCADE ;
这意味着在表kontakty
中,您有一行引用要删除的osoby
中的行。您必须先删除该行,或者在表之间的关系上设置级联删除。
祝你好运!