删除 Postgres 中表的所有约束

问题描述 投票:0回答:1

我需要以编程方式删除表的所有约束,而不知道所有约束名称,到目前为止我已经想出了这段代码,其中

'book'
是我想要删除所有约束的表。

DO $$
DECLARE i RECORD;
BEGIN
FOR i IN (SELECT conname
    FROM pg_catalog.pg_constraint con
        INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
        INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
        WHERE rel.relname = 'book') LOOP
    EXECUTE format('ALTER TABLE book DROP CONSTRAINT %I', i);
END LOOP;
END $$;

然而,这似乎不仅引用了约束名称(例如

"book_pkey"
),而且还添加了括号(
"(book_pkey)"
)。或者,这可能是迭代约束名称的问题,尽管单独执行
SELECT
查询会给出所有不带括号或引号的约束的列表:

  conname
-----------
 book_pkey
(1 row)

执行整个代码块时,Postgres 给出以下错误:

ERROR:  constraint "(book_pkey)" of relation "book" does not exist
CONTEXT:  SQL statement "ALTER TABLE book DROP CONSTRAINT "(book_pkey)""
PL/pgSQL function inline_code_block line 17 at EXECUTE

对此我能做什么?手动删除括号不可能是正确的答案,不是吗?

postgresql for-loop format execute
1个回答
0
投票

这部分是由于在执行语句中使用了%I,当您在格式函数中使用%I时,PostgreSQL会自动在标识符周围添加双引号,以确保将其视为单个区分大小写的实体。通过在格式函数中使用 %s 而不是 %I,您实际上是在告诉 PostgreSQL 不要添加双引号。

DO $$
DECLARE i RECORD;
BEGIN
FOR i IN (SELECT conname
    FROM pg_catalog.pg_constraint con
        INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
        INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
        WHERE rel.relname = 'book') LOOP
    EXECUTE format('ALTER TABLE book DROP CONSTRAINT %s', i.conname);
END LOOP;
END $$;

这应该有效。

© www.soinside.com 2019 - 2024. All rights reserved.