Grunden til, at dette føles underligt for dig, er, at du tænker på stigningen på tælleren som en del af indsættelsesoperationen, og derfor burde "GØR INGENTING" betyde "forøg ikke noget". Du forestiller dig dette:
- Tjek værdier, der skal indsættes, mod begrænsninger
- Hvis duplikat opdages, skal du afbryde
- Forøg sekvens
- Indsæt data
Men faktisk skal stigningen ske før indsættelsen forsøges . En SERIAL
kolonne i Postgres er implementeret som en DEFAULT
som udfører nextval()
funktion på en bundet SEQUENCE
. Før DBMS kan gøre noget med dataene, skal det have et komplet sæt kolonner, så rækkefølgen af operationer er som denne:
- Løs standardværdier, herunder forøgelse af sekvensen
- Tjek værdier, der skal indsættes, mod begrænsninger
- Hvis duplikat opdages, skal du afbryde
- Indsæt data
Dette kan ses intuitivt, hvis duplikatnøglen er i selve autoincrement-feltet:
CREATE TABLE foo ( id SERIAL NOT NULL PRIMARY KEY, bar text );
-- Insert row 1
INSERT INTO foo ( bar ) VALUES ( 'test' );
-- Reset the sequence
SELECT setval(pg_get_serial_sequence('foo', 'id'), 0, true);
-- Attempt to insert row 1 again
INSERT INTO foo ( bar ) VALUES ( 'test 2' )
ON CONFLICT (id) DO NOTHING;
Dette kan tydeligvis ikke vide, om der er en konflikt uden at øge sekvensen, så "gør ingenting" skal komme efter denne stigning.