与文档一致的命令中的Postgres语法错误

时间:2018-08-02 03:28:37

标签: postgresql postgresql-9.4 postgresql-9.6

我正在尝试在postgres版本9.6.2中向表中添加列。

$ psql --version
psql (PostgreSQL) 9.6.2

因此,我指的是ALTER TABLE documentation for postgres 9.6

文档说:

  

更改表[如果存在] [仅]名称[*]       动作[,...]

     

其中动作是以下之一:

ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]

我有一张桌子task

=> select * from task;
 id | name
----+------
(0 rows)
我要使用幂等命令在其上插入列state

(即,它检查state列是否已经创建)。该命令是:

ALTER TABLE task ADD COLUMN IF NOT EXISTS state BIGINT NOT NULL;

但是,这会在NOT处出现语法错误:

=> ALTER TABLE task ADD COLUMN IF NOT EXISTS state BIGINT NOT NULL;
ERROR:  syntax error at or near "NOT"
LINE 1: ALTER TABLE task ADD COLUMN IF NOT EXISTS state BIGINT NOT N...

此命令与文档不一致吗?如何解决语法错误?

注意:当我删除IF NOT EXISTS短语时,该命令可以正常工作,但是在这种情况下,生成的命令并不是所需的幂等。

1 个答案:

答案 0 :(得分:3)

您可以在Postgres <9.6中编写一个存储函数,以便以故障安全的方式添加列。这是一个非常简单的版本:

CREATE OR REPLACE FUNCTION add_column(in_statement TEXT, in_table TEXT, in_column TEXT, in_schema TEXT DEFAULT 'public') RETURNS BOOLEAN AS $_$
BEGIN
    PERFORM * FROM information_schema.columns WHERE table_name = in_table AND column_name = in_column AND table_schema = in_schema;
    IF FOUND THEN
        RETURN FALSE;
    ELSE
        EXECUTE in_statement;
        RETURN TRUE;
    END IF;
END
$_$ LANGUAGE plpgsql VOLATILE;

您可以通过添加列;

SELECT add_column('ALTER TABLE task ADD COLUMN state BIGINT NOT NULL', 'task', 'state');

模式名称是可选的,仅当模式不是public时才需要指定。