Forum: PC-Programmierung PostgreSQL SEQUENCE zählt auch wenn Sie nicht zählen soll


von baer (Gast)


Lesenswert?

Hi,

ich habe eine einfache Tabelle mit einer einfachen SEQUENCE
1
CREATE SEQUENCE grp_id;
2
3
CREATE TABLE GROUPS (
4
  ID integer NOT NULL DEFAULT nextval('grp_id'),
5
  "GROUP" varchar NOT NULL UNIQUE,
6
  FLD1 integer,
7
  FLD2 integer,
8
  FLD3 integer,
9
  PRIMARY KEY(ID, "GROUP")
10
)
11
;

soweit funktioniert das auch... aber wenn ich jetzt einen INSERT mit 
CONFLICT mache, zählt die SEQUENCE auch, wenn ich gar keinen INSERT 
sondern nur das "UPDATE" mache <- was ich natürlich nicht möchte.

Hat da jemand eine Idee, wie man das "umgehen" kann?
1
INSERT INTO GROUPS ("GROUP", FLD1, FLD2, FLD3) 
2
VALUES ('ABC4', 41, 42, 43)
3
ON CONFLICT ("GROUP") DO UPDATE 
4
  SET FLD1 = 41, 
5
      FLD2 = 42,
6
      FLD3 = 43
7
;

dankeschön

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Hallo,
Nur eine Vermutung:

Das Insert wird durchgeführt und schlägt auf Grund des Constraint fehl.
Da das Insert aber durchgeführt wird, wird auch Deine Sequenz 
hochgezählt.

Gruß
Frank

von Klaus P. (Gast)


Lesenswert?

baer schrieb:
> Hat da jemand eine Idee, wie man das "umgehen" kann?

Das ist so "by design" - eventuell kannst Du das mit einem AFTER UPDATE 
Trigger umgehen.
Da könntest Du ein

SELECT setval('sometable_id_seq', MAX(id), true) FROM sometable;

ausführen (siehe hier: 
https://stackoverflow.com/questions/37204749/serial-in-postgres-is-being-increased-even-though-i-added-on-conflict-do-nothing 
und hier: 
https://www.postgresql.org/message-id/9545.1471737989%40sss.pgh.pa.us)

von andreasgf (Gast)


Lesenswert?

baer schrieb:
> Hat da jemand eine Idee, wie man das "umgehen" kann?

Vorher prüfen ob "Group" schon vorhanden ist,
wenn ja Update
wenn nein Insert

von Ergo (Gast)


Lesenswert?

Was ist denn genau das Problem damit? Löcher in der Sequenz sind kein 
Problem, solange sie nur monoton bleibt. Als sprechenden Schlüssel 
sollte man automatische IDs sowieso nicht verwenden. Was willst Du denn 
z.B. machen, wenn zwei Transaktionen die selbe Sequenz nutzen? Das ist 
schon okay so und die haben sich dabei auch was gedacht:

Can There Be "Gaps" In The Values Generated By A Sequence?
Yes, there can. Sequences are intended for generating unique identifiers 
— not necessarily identifiers that are strictly sequential. If two 
concurrent database clients both attempt to get a value from a sequence 
(using nextval()), each client will get a different sequence value. If 
one of those clients subsequently aborts their transaction, the sequence 
value that was generated for that client will be unused, creating a gap 
in the sequence.

This can't easily be fixed without incurring a significant performance 
penalty.

http://www.neilconway.org/docs/sequences/

von c-hater (Gast)


Lesenswert?

Ergo schrieb:

> Was ist denn genau das Problem damit? Löcher in der Sequenz sind kein
> Problem, solange sie nur monoton bleibt. Als sprechenden Schlüssel
> sollte man automatische IDs sowieso nicht verwenden. Was willst Du denn
> z.B. machen, wenn zwei Transaktionen die selbe Sequenz nutzen? Das ist
> schon okay so und die haben sich dabei auch was gedacht:
[...]

Genau. Und das ist nicht nur bei PostgreSQL so, sondern bei jeder 
sinnvoll konstruierten relationalen DB.

von Stefan F. (Gast)


Lesenswert?

Das muss so sein, sonst könnte man sich nicht mehr darauf verlassen, 
dass die Sequenz immer nur aufsteigend generiert wird.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.