插入多个带有标识列的字段无法工作

4

今天我可能工作过度,但我还是不理解这种情况。一定是我简单地忽略了某些愚蠢的东西。

表格结构如下:

CREATE TABLE sample_table (
    id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
    name varchar(255) NOT NULL,
    description text NOT NULL,
    CONSTRAINT sample_table_pk PRIMARY KEY (id)
);

当我尝试插入单个值时,它能够正常工作:

INSERT INTO sample_table (id, name, description)
VALUES (DEFAULT, 'John Doe', 'Test description');

然而,当插入多个值时,会失败:

INSERT INTO sample_table (id, name, description)
VALUES (DEFAULT, 'John Doe', 'Test description')
, (DEFAULT, 'Jane Eod', 'Not working');

为什么?如果我省略DEFAULT值和PK(=id),它运行得很好。
INSERT INTO sample_table (name, description)
VALUES ('John Doe', 'Test description')
, ('Jane Eod', 'Not working');

为什么批量插入中DEFAULT无法工作?
PSQL版本:PostgreSQL 11.13(Debian 11.13-1.pgdg100+1)在x86_64-pc-linux-gnu上,由gcc(Debian 8.3.0-6)编译的8.3.0,64位。
更新:
已由PGSQL团队接受为错误,并在v14中修复..希望他们会传播到所有其他稳定版本..关于此事有激烈的讨论 :))

好的,我已经向pgsql团队报告了这个问题...会在这里继续更新大家...看起来确实像是一个bug。 - Mr.P
2
在我看来,这个问题似乎在去年11月份就被修复了 身份补丁。嗯,我只在14版本的说明中看到了它 单页说明 - Adrian Klaver
@AdrianKlaver 不错...我会考虑升级到一些更新的版本... - Mr.P
除了我所知道的,它只出现在仍处于测试版的第14个版本中。 - Adrian Klaver
我刚刚在另一个数据库上尝试了一下(PostgreSQL 12.8(Ubuntu 12.8-0ubuntu0.20.04.1)在x86_64-pc-linux-gnu上编译,由gcc(Ubuntu 9.3.0-17ubuntu1~20.04)9.3.0编译,64位),但那里也不起作用。 - Mr.P
这就是我所说的,它似乎没有出现在任何当前的生产发布版中,包括刚于8月12日发布的那些版本。 - Adrian Klaver
2个回答

0

你需要覆盖系统值

INSERT INTO sample_table (id, name, description) 
OVERRIDING SYSTEM VALUE
VALUES (DEFAULT, 'John Doe', 'Test description')
, (DEFAULT, 'Jane Eod', 'Now working fine');

4
为什么在插入两行时需要这样做,而插入一行时则不需要? - user330315
对于定义为 GENERATED ALWAYS 的标识列,如果在没有指定 OVERRIDING SYSTEM VALUE 或 OVERRIDING USER VALUE 的情况下插入显式值(除了 DEFAULT),则会出现错误。(对于定义为 GENERATED BY DEFAULT 的标识列,OVERRIDING SYSTEM VALUE 是正常行为,并且指定它不起作用,但 PostgreSQL 允许其作为扩展。)——摘自文档 - Mr.P
1
@Mr.P 看起来 other than DEFAULT 是不正确的。你应该将其发送到他们的错误邮件列表中。他们可能会决定从文档中删除它并保留行为。 - coladict
允许在此处使用默认值是SQL标准中指定的,因此文档是正确的,这是实现中的一个错误。 - Mark Rotteveel
@coladict:我认为这不是PostgreSQL的bug,在DB2和SAP HANA中它的工作方式完全相同。 - Frank Heikens
之前它能够正常工作,现在却不能...从逻辑上讲,我不能说这是一个特性 :) 这毫无意义。 - Mr.P

0

这是一个已知的PostgreSQL bug,在v14中已经修复(感谢Adrian Klaver发现了这个问题)。

由于修复该漏洞相当具有侵入性,而且PostgreSQL试图避免在次要版本中回溯此类补丁以避免引入新的错误;请参见Tom Lane对您的错误报告的回答:

是的,按规范,您不应该为此情况说OVERRIDING SYSTEM VALUE,但是在稳定分支中改进它似乎不值得冒风险进行回溯。


很奇怪,之前它运行得很好,现在却不行了...得检查一下是否有版本更新-这可能会解释它(=>错误)。 - Mr.P
好的,DevOps 更新了数据库,所以它看起来确实像一个 bug。我要报告一下 :) 谢谢 - Mr.P
请查看我对原问题的评论。 - Adrian Klaver
@AdrianKlaver 我认为你是对的。P先生,您能告诉我们哪个PostgreSQL版本 没有 受到这个bug的影响吗? - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接