当前,我正在尝试截断在Postgresql 11.3上具有外键约束的表。
我尝试这样做
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
TRUNCATE tableA;
COMMIT;
但收到错误
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "xxx" references "tableA".
HINT: Truncate table "xxx" at the same time, or use TRUNCATE ... CASCADE.
SET CONSTRAINTS ALL DEFERRED
会关闭外键约束检查吗?无论如何,有没有在不触发外键约束检查且不涉及CASCADE的情况下截断表?
答案 0 :(得分:1)
您可以执行以下步骤以避免在截断期间出现外键错误
创建删除所有外键和约束(尚未运行)的自动化脚本
创建自动创建所有外键和约束的自动化脚本
运行放置脚本
正常运行TRUNCATE your_table
运行重新创建密钥脚本
通过这些步骤,由于没有外键,因此TRUNCATE命令可以正常运行。
拖放脚本和重新创建脚本取自https://blog.hagander.net/automatically-dropping-and-creating-constraints-131/
拖放脚本:
SELECT 'ALTER TABLE "'||nspname||'"."'||relname||'" DROP CONSTRAINT "'||conname||'";'
FROM pg_constraint
INNER JOIN pg_class ON conrelid=pg_class.oid
INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace
ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END,contype,nspname,relname,conname
重新创建脚本:
SELECT 'ALTER TABLE "'||nspname||'"."'||relname||'" ADD CONSTRAINT "'||conname||'" '||
pg_get_constraintdef(pg_constraint.oid)||';'
FROM pg_constraint
INNER JOIN pg_class ON conrelid=pg_class.oid
INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace
ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END DESC,contype DESC,nspname DESC,relname DESC,conname DESC;
答案 1 :(得分:0)
从一个表中删除所有数据
TRUNCATE TABLE
语句的最简单形式如下:
TRUNCATE TABLE table_name;
从具有外键引用的表中删除所有数据
要从主表和具有主表外键引用的所有表中删除数据,请使用CASCADE
选项,如下所示:
TRUNCATE TABLE table_name CASCADE;
更新:
BEGIN;
ALTER TABLE table_name DISABLE TRIGGER ALL;
TRUNCATE TABLE table_name;
ALTER TABLE table_name ENABLE TRIGGER ALL;
COMMIT;
答案 2 :(得分:0)
我到这里结束是因为我的 Sqitch 数据还原脚本使用了TRUNCATE。一种可能不适合所有人的解决方法(但对我有用):
DELETE FROM tableA WHERE id IN (
'5b50e44a-e8dd-4950-8708-588d6620d578',
'd1857bfa-43bc-4284-8a49-c6ceba80a66f',
'3ddff193-eb9f-495b-b63d-87b4e0637caa'
--etc
);