尝试修改 PostgreSQL 中的约束

发布于 2024-12-18 14:31:28 字数 740 浏览 2 评论 0原文

我检查了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;

I have checked the documentation provided by Oracle and found a way to modify a constraint without dropping the table. Problem is, it errors out at modify as it does not recognize the keyword.

Using EMS SQL Manager for PostgreSQL.

Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1
    deferrable, initially deferred;

I was able to work around it by dropping the constraint using :

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

趁微风不噪 2024-12-25 14:31:28

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

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

There is no ALTER command for constraints in Postgres. The easiest way to accomplish this is to drop the constraint and re-add it with the desired parameters. Of course any change of the constraint will be run against the current table data.

BEGIN;
ALTER TABLE t1 DROP CONSTRAINT ...
ALTER TABLE t1 ADD CONSTRAINT ...
COMMIT;
ζ澈沫 2024-12-25 14:31:28

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

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

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

As of version 9.4, PostgreSQL supports ALTER TABLE ... ALTER CONSTRAINT for foreign keys.

This features will "Allow constraint attributes to be altered,
so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back."
Looking at your question I think that is (kind of) what you have been looking for.

More detailed information and an example can be found here:
http://www.depesz.com/2013/06/30/waiting-for-9-4-alter-table-alter-constraint-for-fks/

放低过去 2024-12-25 14:31:28

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

以下是正确手册的链接:

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

According to the correct manual (which is supplied by PostgreSQL, not by Oracle), there is no modify constraint available in the ALTER TABLE statement:

Here is the link to the correct manual:

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

今天小雨转甜 2024-12-25 14:31:28

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

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

select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE');

功能:

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;

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

ALTER CONSTRAINT would require knowing of foreign key name, which is not always convenient.

Here is function, where you need to know only table and column names.
Usage:

select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE');

Function:

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;

Be aware: this function won't copy attributes of initial foreign key.
It only takes foreign table name / column name, drops current key and replaces with new one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文