【问题标题】:Postgresql ADD SERIAL COLUMN IF NOT EXISTS still creating sequencesPostgresql ADD SERIAL COLUMN IF NOT EXISTS 仍在创建序列
【发布时间】:2018-11-06 06:59:14
【问题描述】:

我调用命令

ALTER TABLE tableName ADD COLUMN IF NOT EXISTS columnName SERIAL

在 postgresql 中。第一次运行时,会根据需要创建一个具有相应序列的新列。但是,当再次运行时,会在数据库中创建另一个序列,即使该列已经存在。有谁知道阻止这个新序列创建的任何修复?

【问题讨论】:

  • 在执行alter table 之前检查列是否存在。据推测,序列是在检查表是否存在列之前创建的。
  • 戈登是对的。见"8.1.4. Serial Types"

标签: sql postgresql


【解决方案1】:

您可以使用以下步骤,效果相同:

ALTER TABLE tablename ADD COLUMN IF NOT EXISTS columnname integer;

现在,如果未创建列并且您收到通知,那么您就完成了。否则继续:

CREATE SEQUENCE IF NOT EXISTS tablename_columnname_seq
   OWNED BY tablename.columnname;
ALTER TABLE tablename ALTER COLUMN columnname
   SET DEFAULT nextval('tablename_columnname_seq');

或者,您可以在创建列之前检查列是否存在:

SELECT count(*) FROM information_schema.columns
   WHERE table_name = 'tablename' AND column_name = 'columnname';

您可能希望将架构名称添加到条件中。

【讨论】:

    【解决方案2】:

    您似乎发现了一个小错误。我可以在 Postgres 9.6 和 10 中重新创建它:

    db小提琴here

    事实上,it has been reported in Sept 2017。到目前为止,修复的尝试已被拒绝,因为它会引入其他奇怪的东西。

    规避,请考虑 Laurenz 回答中的建议。也许可以使用 DO 命令自动化,例如:

    DO
    $do$
    BEGIN
    IF NOT EXISTS (SELECT FROM pg_attribute
                   WHERE  attrelid = 'public.tblname'::regclass  -- table name here 
                   AND    attname = 'colname'                    -- column name here
                   AND    NOT attisdropped
                  ) THEN
       ALTER TABLE public.tblname ADD COLUMN IF NOT EXISTS colname serial;
    ELSE
       RAISE NOTICE 'column "colname" of relation "public.tblname" already exists, skipping';
    END IF;
    END
    $do$;
    
    

    如果多个事务可以同时更改同一个表结构,则检查和创建之间的竞争条件是可能的

    生成的通知与IF NOT EXISTS 完全相同。

    使用动态 SQL 将其包装到一个 plpgsql 函数中,该函数采用参数以与任意表和列名重复使用。

    相关:

    模式限定表名以避免歧义。字符串在这里不区分大小写。您不能在问题中使用 CaMeL-case 拼写。见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 2012-06-08
      • 2018-07-17
      • 2012-01-03
      • 2015-03-29
      相关资源
      最近更新 更多