Postgresql

使用預設關鍵字插入多行時,PostgreSQL 10 標識列獲得“空值”

  • December 30, 2017

我最近從 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

使用關鍵字插入單行DEFAULT似乎工作正常。

INSERT INTO test (id, t) VALUES (DEFAULT, 'a');
INSERT 0 1

插入多行不會。

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).

使用隱式預設值插入多行也可以。

INSERT INTO test (t) VALUES ('d'), ('e');
INSERT 0 2

SERIAL使用列偽類型時,上面指定的問題似乎不存在。

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

INSERT INTO test2 (id, t) VALUES (DEFAULT, 'a'), (DEFAULT, 'b');
INSERT 0 2

所以我的問題是:我錯過了什麼嗎?關鍵字是否DEFAULT不能與新的標識列一起使用?或者這是一個錯誤?

這實際上是一個錯誤。我驗證過了。我去看看它是否被歸檔,似乎它已經被歸檔了。它不只是送出,送出就在那裡。

你可以看到他們的測試,就像你的一樣

+-- VALUES RTEs
+INSERT INTO itest3 VALUES (DEFAULT, 'a');
+INSERT INTO itest3 VALUES (DEFAULT, 'b'), (DEFAULT, 'c');
+SELECT * FROM itest3;

所以請稍等,它適用於 PostgreSQL 10.2。

PostgreSQL < 10.2 的可能解決方法

如果您絕對必須擁有它,並且使用隱式列是不可接受的。一種簡單的解決方案是使用目錄資訊功能檢索序列

pg_get_serial_sequence(table_name, column_name) 

我認為應該可以,並將其設置為預設值。

ALTER TABLE ONLY test
 ALTER COLUMN id
 DEFAULT nextval('seqname');

引用自:https://dba.stackexchange.com/questions/194222