我有一個像這樣的簡單表:
CREATE TABLE IF NOT EXISTS myval
(
id integer NOT NULL DEFAULT nextval('myval_myval_id_seq'::regclass),
name character varying(255),
CONSTRAINT "PK_aa671c3359a0359082a84ecb801" PRIMARY KEY (id)
)
序列定義為:
CREATE SEQUENCE IF NOT EXISTS myval_myval_id_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 2147483647
CACHE 1
OWNED BY myval.myval_id;
當我與主鍵一起插入資料時:
INSERT INTO myval(id, name) VALUES (1, 'sdf');
INSERT INTO myval(id, name) VALUES (2, 'sdf');
INSERT INTO myval(id, name) VALUES (3, 'sdf');
INSERT INTO myval(id, name) VALUES (4, 'sdf');
然后,我在沒有 PK 的情況下插入它:
INSERT INTO myval(name) VALUES ('new sdf');
它給出了一個錯誤說:
重復鍵值違反唯一約束“PK_aa671c3359a0359082a84ecb801”,詳細資訊:鍵 (myval_id)=(1) 已存在。
我希望它以 PK 值 5 開始,但它卻給出了錯誤。我們可以將 postgres 配置為跳過沖突的值并從最接近的可用值生成而不是拋出錯誤嗎?
uj5u.com熱心網友回復:
避免這種沖突的最好方法是使用標識列——在這種情況下,aGENERATED ALWAYS AS IDENTITY似乎是正確的選擇。
CREATE TABLE IF NOT EXISTS myval
(
id integer GENERATED ALWAYS AS IDENTITY,
name character varying(255),
CONSTRAINT "PK_aa671c3359a0359082a84ecb801" PRIMARY KEY (id)
);
這將像一個序列(串行)一樣作業,但是如果用戶嘗試在此列中手動插入一個值,它將失敗
INSERT INTO myval (id,name)
VALUES (1,'foor');
ERROR: cannot insert a non-DEFAULT value into column "id"
DETAIL: Column "id" is an identity column defined as GENERATED ALWAYS.
TIP: Use OVERRIDING SYSTEM VALUE to override.
如果出于某種原因您必須在某個INSERT陳述句中覆寫此行為,您可以使用 來執行此操作OVERRIDING SYSTEM VALUE,如上面的錯誤訊息所示
INSERT INTO myval (id,name) OVERRIDING SYSTEM VALUE
VALUES (1,'foo');
serial即使用戶用插入物搞砸了,例如使用觸發器功能,您也可以使用來實作順序值。但是這樣的架構很難維護,恕我直言,絕對不值得麻煩。
演示:db<>fiddle
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497098.html
標籤:sql PostgreSQL
