试图修改PostgreSQL中的约束

MIS*_*ays 51 sql postgresql alter

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

使用EMS SQL Manager进行PostgreSQL.

Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1
    deferrable, initially deferred;
Run Code Online (Sandbox Code Playgroud)

我可以通过使用以下方法删除约束来解决它:

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;
Run Code Online (Sandbox Code Playgroud)

Chr*_*ell 88

ALTERPostgres中没有约束命令.完成此操作的最简单方法是删除约束并使用所需参数重新添加约束.当然,约束的任何更改都将针对当前表数据运行.

BEGIN;
ALTER TABLE t1 DROP CONSTRAINT ...
ALTER TABLE t1 ADD CONSTRAINT ...
COMMIT;
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果我理解正确,DDL语句会对表进行AccessExclusive锁定,因此如果这些命令需要很长时间,那么在命令完成之前,您的站点将停止运行.[文档页面](http://www.postgresql.org/docs/current/static/sql-altertable.html)有更多细节,包括如何显式指定索引而不是自动生成索引. (7认同)
  • 单笔交易就好。一个命令甚至更好。示例:/sf/answers/2199383721/ (5认同)

a_h*_*ame 35

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

以下是正确手册的链接:

http://www.postgresql.org/docs/current/static/sql-altertable.html

  • 对downvote的最佳猜测,答案只是链接到外部网站,而不向未来的读者提供如何正确更改约束的解释. (3认同)
  • Oracle和Oracle的PL/SQL完全不同.他们这样做的唯一可能原因是因为您使用的是EnterpriseDB的*Advanced Server*,它支持Oracle的PL/SQL(以及其他Oracle兼容性功能).但是他们应该给你EnterpriseDB手册,而不是Oracle手册 (2认同)

mku*_*urz 32

从版本9.4开始,PostgreSQL支持ALTER TABLE ... ALTER CONSTRAINT外键.

这个功能将会"Allow constraint attributes to be altered, so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back."查看您的问题,我认为这是(有点)您一直在寻找的东西.

更多详细信息和示例可在此处找到:http:
//www.depesz.com/2013/06/30/waiting-for-9-4-alter-table-alter-constraint-for-fks/

  • 请注意,9.4 文档说`目前只有外键约束可以改变。`! (3认同)

Dan*_*hka 5

ALTER CONSTRAINT将需要知道外键名称,这并不总是很方便。

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

select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE');
Run Code Online (Sandbox Code Playgroud)

功能:

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;
Run Code Online (Sandbox Code Playgroud)

请注意:此函数不会复制初始外键的属性。它只需要外表名/列名,删除当前键并替换为新键。