この方法で作成されたテーブルがあります。
_--
-- 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)
テーブル定義の何が問題になっていますか?これを修正するスマートな方法は何ですか?
テーブルの定義に問題はありません。
(ただし、説明のない列名id
の代わりに_jos_content_id
_などを使用します)。
そして、おそらく varchar(50)
の代わりにtext
を使用します。
あなたの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
にfix thisに設定します1回:
_SELECT setval('jos_content_id_seq', max(id))
FROM jos_content;
_
ここで、_jos_content_id_seq
_は、_jos_content.id
_が所有するシーケンスのデフォルト名であり、列のデフォルトですでに見つかりました。あなたの場合は_xhzt8_content_id_seq
_のようです。
Update:同様の問題がSOでポップアップし、新しい解決策が思い付きました: