试图修改PostgreSQL中的约束

试图修改PostgreSQL中的约束,sql,postgresql,alter,Sql,Postgresql,Alter,我查看了Oracle提供的文档,找到了一种在不删除表的情况下修改约束的方法。问题是,它在修改时出错,因为它无法识别关键字 对PostgreSQL使用EMS SQL管理器 Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1 deferrable, initially deferred; 我可以通过使用以下方法删除约束来解决此问题: ALTER TABLE "public"

我查看了Oracle提供的文档,找到了一种在不删除表的情况下修改约束的方法。问题是,它在修改时出错,因为它无法识别关键字

对PostgreSQL使用EMS SQL管理器

Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1
    deferrable, initially deferred;
我可以通过使用以下方法删除约束来解决此问题:

ALTER TABLE "public"."public_insurer_credit"
  DROP CONSTRAINT "public_insurer_credit_fk1" RESTRICT;

ALTER TABLE "public"."public_insurer_credit"
  ADD CONSTRAINT "public_insurer_credit_fk1" FOREIGN KEY ("branch_id", "order_id", "public_insurer_id")
    REFERENCES "public"."order_public_insurer"("branch_id", "order_id", "public_insurer_id")
    ON UPDATE CASCADE
    ON DELETE NO ACTION
    DEFERRABLE 
    INITIALLY DEFERRED;

根据正确的手册(由PostgreSQL提供,由Oracle提供),ALTER TABLE语句中没有可用的修改约束:

以下是正确手册的链接:


Postgres中没有用于约束的
ALTER
命令。实现这一点的最简单方法是删除约束,并使用所需参数重新添加约束。当然,约束的任何更改都将针对当前表数据运行

BEGIN;
ALTER TABLE t1 DROP CONSTRAINT ...
ALTER TABLE t1 ADD CONSTRAINT ...
COMMIT;

从9.4版开始,PostgreSQL支持
ALTERTABLE。。。更改外键的约束

此功能将
“允许更改约束属性,
因此,可以将“不可延迟”的默认设置更改为“可延迟”并返回。”
看看你的问题,我认为这就是你一直在寻找的

更多详细信息和示例可在此处找到:

ALTER约束需要知道外键名,这并不总是方便的

这里是函数,您只需要知道表名和列名。 用法:

功能:

CREATE OR REPLACE FUNCTION 
    replace_foreign_key(f_table VARCHAR, f_column VARCHAR, new_options VARCHAR) 
RETURNS VARCHAR
AS $$
DECLARE constraint_name varchar;
DECLARE reftable varchar;
DECLARE refcolumn varchar;
BEGIN

SELECT tc.constraint_name, 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
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' 
   AND tc.table_name= f_table AND kcu.column_name= f_column
INTO constraint_name, reftable, refcolumn;

EXECUTE 'alter table ' || f_table || ' drop constraint ' || constraint_name || 
', ADD CONSTRAINT ' || constraint_name || ' FOREIGN KEY (' || f_column || ') ' ||
' REFERENCES ' || reftable || '(' || refcolumn || ') ' || new_options || ';';

RETURN 'Constraint replaced: ' || constraint_name || ' (' || f_table || '.' || f_column ||
 ' -> ' || reftable || '.' || refcolumn || '); New options: ' || new_options;

END;
$$ LANGUAGE plpgsql;
注意:此函数不会复制初始外键的属性。
它只接受外部表名/列名,删除当前键并用新键替换。

在使用PostgreSQL时,为什么要检查Oracle文档(并用“plsql”标记此问题)?确切的错误是什么(哪个关键字无法识别)?错误:在“修改”第1行或其附近出现语法错误:Alter table public.public_Insurance_credit MODIFY CONSTRAINT p.^(0.359秒)为博士后检查Oracle文档,然后指责博士后。Epic.我是一个noob,正在检查提供给我的文档。我从未想到DBA会给我错误的文档。评论是当之无愧的。@developerways每个人都曾经是一个傻瓜,唯一的耻辱就是忘记了这一点。至少你提到了它们是Oracle文档,所以很容易理解。该评论是不值得的。感谢您提供正确文档的链接。我们的DBA向我提供了Oracle PL/SQL文档。Oracle和Oracle的PL/SQL是完全不同的东西。他们这样做的唯一可能原因是因为您使用的是EnterpriseDB的高级服务器,它支持Oracle的PL/SQL(以及其他Oracle兼容性功能)。但是他们应该给你EnterpriseDB手册,而不是Oracle手册Best guess at downvote,答案只是链接到外部站点,而没有向未来的读者提供如何正确更改约束的解释。注意:如果我理解正确,DDL语句会在表上使用AccessExclusive锁,因此,如果这些命令需要很长时间,您的站点将停止运行,直到命令完成。有更多的细节,包括如何显式指定索引,而不是自动生成索引。一个事务就可以了。一个命令就更好了。示例:请注意,9.4文档中说,
当前只能更改外键约束。
!非常有趣的解决方案
CREATE OR REPLACE FUNCTION 
    replace_foreign_key(f_table VARCHAR, f_column VARCHAR, new_options VARCHAR) 
RETURNS VARCHAR
AS $$
DECLARE constraint_name varchar;
DECLARE reftable varchar;
DECLARE refcolumn varchar;
BEGIN

SELECT tc.constraint_name, 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
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' 
   AND tc.table_name= f_table AND kcu.column_name= f_column
INTO constraint_name, reftable, refcolumn;

EXECUTE 'alter table ' || f_table || ' drop constraint ' || constraint_name || 
', ADD CONSTRAINT ' || constraint_name || ' FOREIGN KEY (' || f_column || ') ' ||
' REFERENCES ' || reftable || '(' || refcolumn || ') ' || new_options || ';';

RETURN 'Constraint replaced: ' || constraint_name || ' (' || f_table || '.' || f_column ||
 ' -> ' || reftable || '.' || refcolumn || '); New options: ' || new_options;

END;
$$ LANGUAGE plpgsql;