使用默认关键字插入多行时,PostgreSQL 10 标识列获得“空值”

dan*_*woz 7 postgresql identity postgresql-10

我最近从 PostgreSQL 9.5 升级到 PostgreSQL 10。PostgreSQL 10 中的一个漂亮特性是新的标识列类型,它是 PostgreSQL串行伪类型的替代品。身份栏的官方文档可以在CREATE TABLE一页中找到。

但是,当将多行插入到带有GENERATED BY DEFAULT AS IDENTITY列的表中使用关键字DEFAULT获取下一个 ID 值时,默认值返回为null.

例如,假设我有一张桌子

CREATE TABLE test (
  id int GENERATED BY DEFAULT AS IDENTITY,
  t text
);
CREATE TABLE
Run Code Online (Sandbox Code Playgroud)

使用DEFAULT关键字插入单行似乎工作正常。

INSERT INTO test (id, t) VALUES (DEFAULT, 'a');
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)

插入多行不会。

INSERT INTO test (id, t) VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
ERROR:  null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, b).
Run Code Online (Sandbox Code Playgroud)

使用隐式默认值插入多行也有效。

INSERT INTO test (t) VALUES ('d'), ('e');
INSERT 0 2
Run Code Online (Sandbox Code Playgroud)

使用SERIAL列伪类型时,上面指定的问题似乎不存在。

CREATE TABLE test2 (
  id SERIAL,
  t text
);
CREATE TABLE

INSERT INTO test2 (id, t) VALUES (DEFAULT, 'a'), (DEFAULT, 'b');
INSERT 0 2
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:我错过了什么吗?在DEFAULT关键字只是没有预料到的工作与新的身份列?或者这是一个错误?

Eva*_*oll 4

这实际上是一个错误。我验证了一下。我去看看它是否已归档,似乎已经归档了。它不只是提交,而是提交。

你可以看到他们的测试,和你的完全一样

+-- VALUES RTEs
+INSERT INTO itest3 VALUES (DEFAULT, 'a');
+INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
+SELECT * FROM itest3;
Run Code Online (Sandbox Code Playgroud)

所以请稍等,PostgreSQL 10.2 就已经有了。

PostgreSQL < 10.2 的可能解决方法

如果你绝对必须有这个,并且使用隐式列是不可接受的。一种简单的解决方案是使用目录信息函数检索序列

pg_get_serial_sequence(table_name, column_name) 
Run Code Online (Sandbox Code Playgroud)

我认为这应该有效,并将其设置为默认值。

ALTER TABLE ONLY test
  ALTER COLUMN id
  DEFAULT nextval('seqname');
Run Code Online (Sandbox Code Playgroud)

  • 感谢您检查它是否已经提交(并提交)。我的计划是在必要时继续使用序列,直到 10.2 (2认同)