Postgres动态更新约束外键

时间:2012-05-30 12:17:15

标签: postgresql postgresql-8.4

我有很多带有很多外键的表,而且所有表都是UPDATE NO ACTION和DELETE NO ACTION。

是否可以将所有这些外键动态更新为CASCADE而不是NO ACTION或RESTRICT?

例如:

ALTER TABLE * ALTER FOREIGN KEY * SET ON UPDATE CASCADE ON DELETE CASCADE;

此致, 迪奥戈

2 个答案:

答案 0 :(得分:4)

不,这是不可能的。

您将需要删除并重新创建所有约束,因为外键约束不能像这样改变。

以下语句将生成必要的alter table语句以删除并重新创建外键:

select 'alter table '||pgn.nspname||'.'||tbl.relname||' drop constraint '||cons.conname||';'
from pg_constraint cons
  join pg_class tbl on cons.confrelid = tbl.oid
  join pg_namespace pgn on pgn.oid = tbl.relnamespace
where contype = 'f'

union all 

select 'alter table '||pgn.nspname||'.'||tbl.relname||' add constraint '||cons.conname||' '||pg_get_constraintdef(cons.oid, true)||' ON UPDATE CASCADE ON DELETE CASCADE;'
from pg_constraint cons
  join pg_class tbl on cons.confrelid = tbl.oid
  join pg_namespace pgn on pgn.oid = tbl.relnamespace
where contype = 'f'

将此语句的输出保存到文件并运行它。

确保在运行之前验证生成的语句!

答案 1 :(得分:0)

我将使用以下代码生成必要的alter table SQL语句以删除并重新创建外键(按顺序):

    select 'ALTER TABLE '||pgn.nspname||'.'||tbl.relname||' DROP CONSTRAINT '||cons.conname||';' as sqlstr
    from pg_constraint cons
      join pg_class tbl on cons.conrelid = tbl.oid
      join pg_namespace pgn on pgn.oid = tbl.relnamespace
    where contype = 'f' 
    union
    select 'ALTER TABLE '||pgn.nspname||'.'||tbl.relname||' ADD CONSTRAINT '||cons.conname||' FOREIGN KEY ('||(select attname from pg_attribute where attrelid=cons.conrelid and attnum = ANY(cons.conkey))||') REFERENCES '||tblf.relname||' ('||(select attname from pg_attribute where attrelid=cons.confrelid and attnum = ANY(cons.confkey))||')  ON UPDATE CASCADE ON DELETE CASCADE;'  as sqlstr
    from pg_constraint cons
      join pg_class tbl on cons.conrelid = tbl.oid
      join pg_namespace pgn on pgn.oid = tbl.relnamespace
      join pg_class tblf on cons.confrelid = tblf.oid
    where contype = 'f' 

    ORDER BY sqlstr desc