Postgresql

修復表結構以避免“錯誤:重複鍵值違反唯一約束”

  • October 21, 2021

我有一個這樣創建的表:

--
-- Table: #__content
--
CREATE TABLE "jos_content" (
 "id" serial NOT NULL,
 "asset_id" bigint DEFAULT 0 NOT NULL,
  ...
 "xreference" varchar(50) DEFAULT '' NOT NULL,
 PRIMARY KEY ("id")
);

稍後插入一些指定 id 的行:

INSERT INTO "jos_content" VALUES (1,36,'About',...)

稍後插入一些沒有 id 的記錄,它們因錯誤而失敗: Error: duplicate key value violates unique constraint

顯然 id 被定義為一個序列:

在此處輸入圖像描述

每個失敗的插入都會增加序列中的指針,直到它增加到不再存在的值並且查詢成功。

SELECT nextval('jos_content_id_seq'::regclass)

表定義有什麼問題?解決這個問題的聰明方法是什麼?

您的表定義沒有任何問題。

(除了我會使用jos_content_idor 來代替非描述性的列名id

而且我可能會使用text而不是varchar(50).

你的INSERT說法是問題所在。

將您的id列定義為serial,您不應為 插入手動值id。這些可能與相關序列中的下一個值發生衝突。

提供一個明確的目標列列表(這對於持久化INSERT語句幾乎總是一個好主意)並完全省略串列列

INSERT INTO jos_content(asset_id, some_column, ...)
VALUES (36,'About',...);

如果您需要立即自動生成的列的值,請使用**RETURNING**子句

INSERT ...
RETURNING id;  -- possibly more

有關 SO 的相關答案中的更多詳細資訊:

如果您在serial以後可能會發生衝突的列中有手動輸入,請將您的序列設置為目前最大值id修復此問題一次

SELECT setval('jos_content_id_seq', max(id))
FROM   jos_content;

jos_content_id_seq擁有的序列的預設名稱在哪裡jos_content.id,您已經在預設列中找到了該名稱。似乎是xhzt8_content_id_seq你的情況;


更新: SO上出現了類似的問題,我想出了一個新的解決方案:

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