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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von baer (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (stefanus)


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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.