插入带有标识列的多个字段不起作用

Posted

技术标签:

【中文标题】插入带有标识列的多个字段不起作用【英文标题】:Insert multiple fields with identity column doesn't work 【发布时间】:2021-10-20 08:23:36 【问题描述】:

我今天可能工作过度,但我没有遇到这种情况。一定是我忽略了一些愚蠢的事情。

表结构如下:

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 版本:x86_64-pc-linux-gnu 上的 PostgreSQL 11.13 (Debian 11.13-1.pgdg100+1),由 gcc (Debian 8.3.0-6) 8.3.0 编译,64 位

更新:

它被 PGSQL 团队接受为一个错误 a 已在 v14 中修复..希望他们将其传播到所有其他稳定版本..对此进行了激烈的讨论:))

【问题讨论】:

好的,我把它报告给了 pgsql 团队......会在这里让你更新......真的看起来像一个错误 对我来说,这看起来是在去年 11 月修复的 Identity patch。嗯,我只在版本14的笔记里看到One page notes。 @AdrianKlaver 不错的一个...将考虑升级到一些新版本... 据我所知,它只出现在仍处于测试阶段的第 14 版中。 我刚刚在 x86_64-pc-linux-gnu 上尝试了另一个 DB (PostgreSQL 12.8 (Ubuntu 12.8-0ubuntu0.20.04.1),由 gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3 编译.0, 64 位),它在那里也不起作用 【参考方案1】:

你需要OVERRIDING SYSTEM VALUE:

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

【讨论】:

问题是:为什么插入两行时需要这样做,而插入一行时不需要。 For an identity column defined as GENERATED ALWAYS, it is an error to insert an explicit value (other than DEFAULT) without specifying either OVERRIDING SYSTEM VALUE or OVERRIDING USER VALUE. (For an identity column defined as GENERATED BY DEFAULT, OVERRIDING SYSTEM VALUE is the normal behavior and specifying it does nothing, but PostgreSQL allows it as an extension.) 引用自文档 @Mr.P 似乎 other than DEFAULT 不正确。您应该将其发送到他们的错误邮件列表。他们可能会认为将其从文档中删除并保留该行为会更容易。 SQL标准中规定了此处允许默认,所以文档是正确的,这是实现中的一个bug。 @coladict:我认为这不是 PostgreSQL 中的错误,它在 DB2 和 SAP HANA 中的工作方式完全相同。【参考方案2】:

这是 known PostgreSQL bug 和 has been fixed in v14(感谢发现它的 Adrian Klaver)。

错误修复没有被向后移植到旧版本,因为它具有相当的侵入性,并且 PostgreSQL 试图避免向后移植此类补丁以避免在次要版本中引入新错误;见 Tom Lane 对your bug report 的回答:

是的,根据规范,您不必说 OVERRIDING SYSTEM VALUE 对于这种情况,但似乎不值得冒回补的风险 在稳定的分支中改善这一点。

【讨论】:

这很奇怪,因为它以前可以正常工作.. 现在它不能...必须检查版本是否没有更新 - 这可以解释它(=> 错误) 好的,DevOps 更新了数据库,所以它看起来真的像一个错误.. 我要报告它:) thx 查看我对原始问题的评论。 @AdrianKlaver 我认为你是对的。 Mr.P,您能告诉我们没有受此错误影响的 PostgreSQL 版本吗?

以上是关于插入带有标识列的多个字段不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如果特定列的字段存在,如何更新

重力形式总字段在 Wordpress 页面中不起作用

为啥我的 Pandas 引用多个列的“应用”函数不起作用? [关闭]

TableColumn setPreferredWidth不起作用

插入带有参数MYSQL的存储过程不起作用

带有内部查询的 SQL 插入语句不起作用