Mam tabelę, która jest tworzona w ten sposób:
--
-- 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")
);
Później wstawiane są niektóre wiersze określające identyfikator:
INSERT INTO "jos_content" VALUES (1,36,'About',...)
W późniejszym momencie niektóre rekordy są wstawiane bez identyfikatora i one niepowodzeniem z błędem:
Error: duplicate key value violates unique constraint
.
Najwyraźniej identyfikator został zdefiniowany jako sekwencja:
Każde nieudane wstawienie zwiększa wskaźnik w sekwencji, aż zwiększy się do wartości, która już nie istnieje, a zapytania zakończą się powodzeniem.
SELECT nextval('jos_content_id_seq'::regclass)
Co jest złego w definicji tabeli? Jaki jest sprytny sposób to naprawić?
postgresql
database-design
insert
auto-increment
sequence
Valentin Despa
źródło
źródło
Odpowiedzi:
W definicji tabeli nie ma nic złego.
(Z wyjątkiem kapelusz użyłbym
jos_content_id
lub coś zamiast non-opisowej nazwy kolumnyid
.I prawdopodobnie używać
text
zamiastvarchar(50)
.Twoje
INSERT
oświadczenie stanowi problem.Po
id
zdefiniowaniu kolumny jakoserial
nie należy wstawiać wartości ręcznych dlaid
. Mogą one kolidować z następną wartością z powiązanej sekwencji.Podaj wyraźną listę kolumn docelowych (co prawie zawsze jest dobrym pomysłem dla utrwalonych
INSERT
instrukcji) i całkowicie pomiń kolumny szeregowe .Jeśli potrzebujesz natychmiastowych wartości automatycznie generowanych kolumn, skorzystaj z
RETURNING
klauzuli :Więcej szczegółów w tej pokrewnej odpowiedzi na temat SO:
Jeśli masz ręczne wpisy w
serial
kolumnach, które mogą później spowodować konflikt, ustaw sekwencję na bieżące maksimum,id
aby to naprawić raz :Gdzie
jos_content_id_seq
jest domyślną nazwą sekwencji należącej dojos_content.id
, którą już znalazłeś w kolumnie domyślnej. Wydaje się, że tak jestxhzt8_content_id_seq
w twoim przypadku;Aktualizacja: Podobny problem pojawił się na SO i wymyśliłem nowe rozwiązanie:
źródło