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

Posted

技术标签:

【中文标题】命令中的 Postgres 语法错误与文档一致【英文标题】:Postgres syntax error in command consistent with documentation 【发布时间】:2018-08-02 03:28:37 【问题描述】:

我正在尝试在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 短语时,该命令可以正常工作,但在这种情况下生成的命令不是所需的幂等。

【问题讨论】:

select version(); 说什么?仅仅因为 psql 来自 9.6.2 并不意味着您要连接的服务器是 9.6.2。 @muistooshort 你是对的。 select version() 显示版本为 9.4,并且 9.4 的文档未显示已创建列的 IF NOT EXISTS 选项。看来我必须考虑如何在没有该选项的情况下使命令具有幂等性。 【参考方案1】:

您可以在 Postgres

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时才需要指定。

【讨论】:

以上是关于命令中的 Postgres 语法错误与文档一致的主要内容,如果未能解决你的问题,请参考以下文章

UPDATE 查询中的 FROM 后的 Postgres 语法错误

带有程序代码的 Postgres 语句中的语法错误 [重复]

使用gorm的postgres中的“$ 1”或附近的golang语法错误

Postgres 查询在控制台上工作,但将其用作视图中的范围会呈现语法错误

为啥在我的 Postgres 函数中使用 IF 语句时出现语法错误?

将 Csv 文件导入到 postgres Cloud SQL 实例无效输入语法错误