【问题标题】:PostgreSQL rename a column only if it existsPostgreSQL 仅在存在时重命名列
【发布时间】:2021-07-04 18:35:49
【问题描述】:

如果有办法运行 ALTER TABLE tablename RENAME COLUMN IF EXISTS colname TO newcolname; 语句,我在 PostgreSQL documentation 中找不到。

我很高兴我们可以这样做,因为我面临的错误取决于谁制作并给了我一个 SQL 脚本,在某些情况下一切都很好(当列的名称错误时,名称将实际上可以使用RENAME 语句进行更改),而在其他情况下则不会(当列已经具有正确的名称时)。

因此在尝试重命名列name 时使用IF EXISTS 语句的想法。如果该列已经有正确的名称(此处为 cust_date_mean),则必须正确跳过必须仅应用于错误名称的重命名命令,并且不会发出以下错误:

db_1   | [223] ERROR: column "cust_mean" does not exist
db_1   | [223] STATEMENT: ALTER TABLE tablename RENAME COLUMN cust_mean TO cust_date_mean;
db_1   | ERROR:  column "cust_mean" does not exist

(与此同时,我会与团队澄清一些事情,所以如果这样的命令不存在也没什么大不了的,但我认为它会有所帮助。

【问题讨论】:

  • 你试过this source的答案吗
  • 这是一个在 SO 上无法实现的功能请求。如果您想提出它,那么合适的位置是Postgres mailing lists、--general 或--hackers 之一。请注意,当前的 Postgres 开发版本 14 处于功能冻结状态。假设有人会接受该提案,那么它最早可以实施的时间是 15 年多后的版本。
  • 是否需要专门为RENAME?其他数据库对象是否依赖于该列?请注意 ADDDROP 带有 IF [NOT] EXISTS 选项,因此您可以使用它们作为解决方法。
  • @Bergi,问题在于提出一种机制来保留已删除列中的值以恢复到添加的列中。
  • @AdrianKlaver 啊,对,that would require an UDPATE statement 你又不知道是否执行它......

标签: postgresql rename


【解决方案1】:

虽然没有内置功能,但您可以使用DO 语句:

DO
$$
DECLARE
   _tbl         regclass := 'public.tbl';      -- not case sensitive unless double-quoted
   _colname     name     := 'cust_mean';       -- exact, case sensitive, no double-quoting
   _new_colname text     := 'cust_date_mean';  -- exact, case sensitive, no double-quoting
BEGIN
   IF EXISTS (SELECT FROM pg_attribute
              WHERE  attrelid = _tbl
              AND    attname  = _colname
              AND    attnum > 0
              AND    NOT attisdropped) THEN
      EXECUTE format('ALTER TABLE %s RENAME COLUMN %I TO %I', _tbl, _colname, _new_colname);
   ELSE
      RAISE NOTICE 'Column % of table % not found!', quote_ident(_colname), _tbl;
   END IF;
END
$$;

完全符合您的要求。在DECLARE 部分中输入表名和列名。
NOTICE 是可选的。
对于重复使用,我会创建一个函数并传递参数而不是变量。

安全地处理变量(无 SQL 注入)。表名可以选择是模式限定的。如果不是,则按照当前的search_path解决,就像ALTER TABLE一样。

相关:

【讨论】:

    猜你喜欢
    • 2018-06-14
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 2020-11-26
    • 2023-03-26
    • 2011-01-05
    • 1970-01-01
    相关资源
    最近更新 更多