【问题标题】:Removing COMMENT ON from all objects in PostgreSQL从 PostgreSQL 中的所有对象中删除 COMMENT ON
【发布时间】:2017-11-15 23:59:57
【问题描述】:

pg_dump without comments on objects? 一样,有没有人知道一个命令可以立即删除所有对象上的 cmets(使用COMMENT ON 创建)?

目前,我求助于 bash 生成一个 SQL 脚本,该脚本将一个一个地取消每个表/视图/列上的 cmets,但它非常慢,尤其是在 >4000 列的情况下。
示例:

COMMENT ON COLUMN table1.column1 IS NULL;
COMMENT ON COLUMN table1.column2 IS NULL;
COMMENT ON COLUMN table1.column3 IS NULL;
...

【问题讨论】:

  • 尝试编写一个 PL/SQL 函数,查询 pg_description 并使用动态 SQL 删除评论。它比任何 bash 脚本都要快。

标签: postgresql ddl


【解决方案1】:

我前段时间遇到了一个非常相似的问题,想出了一个非常简单的解决方案:从系统目录表中删除pg_description直接。注释只是“附加”到对象上,不会干扰其他对象。

DELETE FROM pg_description WHERE description = 'something special';

免责声明:
直接操作目录表是危险的,是不得已而为之的措施。您必须知道自己在做什么,而且风险自负!如果你搞砸了,你可能会搞砸你的数据库(集群)。

我在 pgsql-admin 列表上询问了这个想法,得到了一个encouraging answer from Tom Lane

> DELETE FROM pg_description WHERE description = 'My very special
> totally useless comment.';

> AFAICS, there are no side-effects. Are there any?

It's safe enough, as long as you don't delete the wrong comments.
There's no hidden infrastructure for a comment.

            regards, tom lane

您应该确保没有任何您想保留的 cmets。 首先检查您要删除的内容。请注意,许多内置 Postgres 对象也有 cmets。

例如,仅删除表列上的所有 cmets,您可以使用:

SELECT *
-- DELETE
FROM   pg_description
WHERE  objsubid > 0;

The manual informs about the column objsubid:

对于表格列的注释,这是列号(objoidclassoid 参考表格本身)。对于所有其他对象类型,此列为零。

【讨论】:

    【解决方案2】:

    好的,感谢您的帮助,我发现以下命令非常有用:

    要从特定对象(此处为 mytable)的给定列位置删除评论,您可以:

    DELETE FROM pg_description WHERE (SELECT relname FROM pg_class WHERE oid=objoid)='mytable' AND objsubid=2;
    

    ...但请注意,它并不比在 mytable.myfield IS NULL 上使用 COMMENT 更有效;

    现在,要从我的用户定义视图和基础列中删除所有 cmets,以下是非常有效的方法:

    DELETE FROM pg_description WHERE (SELECT relkind FROM pg_class WHERE oid=objoid)='v' AND (SELECT relname FROM pg_class WHERE oid=objoid) ~ 'v_';
    

    在哪里:

    • (SELECT relkind FROM pg_class WHERE oid=objoid)='v': 所有视图
    • (SELECT relname FROM pg_class WHERE oid=objoid) ~ 'v_' : 额外的安全性,我的视图名称都以'v_'开头

    【讨论】:

      【解决方案3】:

      如果您想在不破解系统表的情况下执行此操作,那么这将为您生成语句:

      SELECT 'COMMENT ON COLUMN ' || quote_ident(pg_namespace.nspname) || '.' || quote_ident(pg_class.relname) || '.' || quote_ident(columns.column_name) || ' IS NULL;'
      FROM   pg_description
      JOIN pg_class ON pg_class.oid = pg_description.objoid
      JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
      JOIN information_schema.columns 
        ON columns.table_schema = pg_namespace.nspname
       AND columns.table_name = pg_class.relname
       AND columns.ordinal_position = pg_description.objsubid
      

      您可能应该添加一个 WHERE 子句,将其限制在您的架构中。

      【讨论】:

        猜你喜欢
        • 2016-01-13
        • 1970-01-01
        • 2017-11-05
        • 2015-06-07
        • 1970-01-01
        • 2012-08-18
        • 2021-12-03
        • 2017-03-23
        相关资源
        最近更新 更多