我正在寻找一种方法将
on delete cascade
添加到我的 PostgreSQL 数据库中的所有外键(最好仅限于模式)。我找到了一个脚本here,但它似乎不适用于 PostgreSQL。该解决方案不必使用脚本,GUI 工具也可以。
谢谢你。
建议和支持的方法是添加具有相同定义和
ON DELETE CASCADE
的新约束,然后删除原始约束。
如果您准备好冒险通过目录修改来破坏数据库,并且您信任来自互联网的随机 SQL 语句,您可以尝试
WITH tables(oid) AS (
UPDATE pg_constraint
SET confdeltype = 'c'
WHERE contype = 'f'
AND confdeltype <> 'c'
AND connamespace = 'myschema'::regnamespace
RETURNING confrelid
)
UPDATE pg_trigger
SET tgfoid = '"RI_FKey_cascade_del"()'::regprocedure
FROM tables
WHERE tables.oid = pg_trigger.tgrelid
AND tgtype = 9;
使用前请先测试!
无需更改数据库目录,此函数应该以一种不那么可怕的方式完成任务。
create function "UpdateAllForeignKeys"(on_delete varchar)
returns void
language plpgsql
as
$$
declare
rec record;
drop_statement varchar;
add_statement varchar;
begin
for rec in
select
tc.table_schema,
tc.constraint_name,
tc.table_name,
kcu.column_name,
ccu.table_schema as foreign_table_schema,
ccu.table_name as foreign_table_name,
ccu.column_name as foreign_column_name
from information_schema.table_constraints as tc
join information_schema.key_column_usage as kcu
on tc.constraint_name = kcu.constraint_name
and tc.table_schema = kcu.table_schema
join information_schema.constraint_column_usage as ccu
on ccu.constraint_name = tc.constraint_name
where tc.constraint_type = 'FOREIGN KEY'
and tc.table_schema = 'my_schema'
and ccu.table_schema = 'my_foreign_schema'
LOOP
execute 'alter table only ' || rec.table_schema || '.' || rec.table_name || ' drop constraint ' || rec.constraint_name || ';';
execute 'alter table only ' || rec.table_schema || '.' || rec.table_name || ' add constraint ' || rec.constraint_name || ' foreign key (' || rec.column_name || ') references ' || rec.foreign_table_schema || '.' || rec.foreign_table_name || ' (' || rec.foreign_column_name || ') on delete ' || on_delete || ';';
end loop;
end;
$$;
select "UpdateAllForeignKeys"('cascade');