我正在制作一个刷新脚本,我们在
DROP
表约束,TRUNCATE
表格INSERT
数据
ADD
在第一步中删除的约束。我使用动态SQL创建了以下SQL,以控制SQL DROP外键约束,以便我可以针对正在处理的多个表执行
SELECT
'ALTER TABLE SSP2_PCAT.' || TABLE_NAME || ' DROP CONSTRAINT ' || CONSTRAINT_NAME || ';'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE
UPPER(CONSTRAINT_SCHEMA) = 'SSP2_PCAT' AND
UPPER(TABLE_NAME) IN (RATES,.....);
以上SQL的输出将如下所示,
ALTER TABLE SSP2_PCAT.RATES DROP CONSTRAINT fk_rate;
截断上面提到的方法非常简单。
通过启用DBlink将WITH
子句与STRING_AGG
函数一起使用
POSTGRES中的扩展类似地使用动态SQL,以便一次性提供多个表的SQL。
现在我正在研究类似的查询,以添加如下约束(第一步已删除)
SELECT DISTINCT 'ALTER TABLE ' || cs.TABLE_NAME ||
' ADD CONSTRAINT ' ||rc.CONSTRAINT_NAME ||
' FOREIGN KEY ' ||c.COLUMN_NAME ||
' REFERENCES ' ||cs.TABLE_NAME || ' (' || cs.CONSTRAINT_NAME || ') ' || ' ON UPDATE ' || rc.UPDATE_RULE || ' ON DELETE ' || rc.DELETE_RULE
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC, INFORMATION_SCHEMA.TABLE_CONSTRAINTS CS, INFORMATION_SCHEMA.COLUMNS C
WHERE cs.CONSTRAINT_NAME = rc.CONSTRAINT_NAME AND
cs.TABLE_NAME = c.TABLE_NAME AND
UPPER(cs.TABLE_NAME) = 'ADDITIONAL_RULES' AND
UPPER(cs.TABLE_SCHEMA) = 'SSP2_PCAT';
但是不幸的是,该查询未提供期望的结果,似乎我缺少了某些东西,尤其是在选择c.COLUMN_NAME
字段而不是引用字段时,它提供了表中的所有可用字段,也是没有给出Parent_table cs.TABLE_NAME
的名称,而是给出了相同的table_name。如果我从任何其他数据字典表中丢失任何联接,可以有人让我发布吗?
答案 0 :(得分:1)
您不需要删除并重新创建外键。请改用延迟约束。将外键定义为deferrable initially deferred
并在单个事务中执行所有插入就足够了。但是,还有更多选项,因此请阅读文档中有关可延迟约束的信息:
使用系统目录pg_constraint
.
您可以通过以下方式生成脚本以将外键更改为DEFERRABLE INITIALLY DEFERRED
:
select format(
'ALTER TABLE %s ALTER CONSTRAINT %s DEFERRABLE INITIALLY DEFERRED;',
conrelid::regclass::text,
conname)
from pg_constraint
where contype = 'f'
and conrelid = any(array['table1', 'table2', 'table3']::regclass[])
and connamespace = 'ssp2_pcat'::regnamespace;
您可以运行一次脚本。然后,您的导入脚本可能如下所示:
BEGIN;
TRUNCATE table1;
TRUNCATE table2;
...
INSERT INTO table1...
INSERT INTO table2...
...
COMMIT;
如果由于某种原因您不能使用延迟约束,请使用脚本删除约束:
select
format(
'ALTER TABLE %s DROP CONSTRAINT %s;',
conrelid::regclass::text,
conname)
from pg_constraint
where contype = 'f'
and conrelid = any(array['table1', 'table2', 'table3']::regclass[])
and connamespace = 'ssp2_pcat'::regnamespace;
并重新创建它们:
select
format(
'ALTER TABLE %s ADD CONSTRAINT %s %s;',
conrelid::regclass::text,
conname,
pg_get_constraintdef(oid))
from pg_constraint
where contype = 'f'
and conrelid = any(array['table1', 'table2', 'table3']::regclass[])
and connamespace = 'ssp2_pcat'::regnamespace;