Freie ID in Tabelle ermitteln

Status
Nicht offen für weitere Antworten.

foobar

Top Contributor
Hi,

wie kann man am einfachsten in einer Tabelle eine nicht verwendete ID ermitteln? Das ganze dient dazu dem Benutzer die Möglichkeit zu geben, die verwendete ID selbst zu bestimmen z.b. eine neue ID > 500.

Bisher habe ich nur sowas zu Stande gebracht:

Code:
select a.kdnr+1 
from rechkd a
where a.kdnr+1 not in (select b.kdnr
                       from rechkd b
                       where a.kdnr+1 = b.kdnr)
order by 1

Das funktioniert zwar ist aber nicht besonders performant. Geht das nicht einfacher?

Viele Grüße,
foobar
 
reicht nicht schon
where a.kdnr+1 not in (select b.kdnr from rechkd b )
?
dann muss die Subquery nur einmal berechnet werden,

aber kann wieder langsam sein, wenn die DB das 'in' nicht gut prüft und die Liste lang ist,

-------------
dann noch ein Left Join mit sich selbst und der Bedingung kndr+1?
wenn null, dann Wert nicht vorhanden
 
Stimmt die Wehreklausel ist obsolet:

Code:
select min(a.kdnr+1)
from rechkd a
where a.kdnr+1 not in (select b.kdnr
                       from rechkd b)
and a.kdnr+1 > 100                       
order by 1

Das liefert mir die kleinste freie ID größer als 100.

Danke SlaterB 🙂
 
Das hängt ganz stark von der DB ab, zuverlässig weiss ich dass es mit Oracle möglich ist.

Bei den hier vorgestellten Lösungen sollte man tunlichst darauf achten dass nicht ein anderer Thread zwischen der Abfrage und dem anlegen noch einen Datensatz ablegt.
 
Ja, das Verfahren ist nicht ganz unproblematisch. Man muß eben einfach vor dem eigentlichen Insert nochmals prüfen, ob die Id noch vorhanden ist, weil zwischen dem Berechnen der ID und dem eigentlichen Anlegen des Datensatzes jede Menge Zeit verstreichen kann.
Mit einem Left-Selfjoin habe ich das Problem bisher nicht lösen können. Ist es eigentlich Möglich jede Subselectquery auch mit einem Join abzubilden? Gibt es dazu eine Regel? Ich habe das mal so gelernt, aber eine Regel, die das beweist, ist mir nicht bekannt.
 
Hallo,

bei Oracle fallen mir zwei Möglichkeiten ein:

1. eine Sequenz
oder
2. select max(id)+1 as neuer_index from tabelle

Bei der max-Abfrage gibt es aber wieder das Problem konkurrierender Zugriffe.
Die Sequenz hingegegen ist sicher.
 
max(id)+1 liefert aber nicht das gewünschte Ergebnis. Der benutzer kann sich aussuchen, ob er eine freie, möglichste kleine Id oder max(id(+1) oder eine Id seiner Wahl verwenden möchte.

Sequenzen gibt es bei Informix leider nicht :-(
 
Sequenzen würden auch nicht helfen, Lücken in der Id-Liste zu finden,
sondern liefern nur immer quasi max(id)+1 auf performant einfache Weise,
ohne gelöschte rauszurechnen, ein einfacher Zähler,

wenn man parallel manuell Ids vergibt, dann kann auch eine Sequenz-Id zu einem Fehler führen
 
SlaterB hat gesagt.:
Sequenzen würden auch nicht helfen, Lücken in der Id-Liste zu finden,
sondern liefern nur immer quasi max(id)+1 auf performant einfache Weise,
ohne gelöschte rauszurechnen, ein einfacher Zähler,
Wenn die ID ausschließlich DB-intern Bedeutung hat, sind Lücken nicht schlimm.

wenn man parallel manuell Ids vergibt, dann kann auch eine Sequenz-Id zu einem Fehler führen
Klar, das ist "tödlich". Man muss als Entwickler auf jeden Fall entscheiden, ob man einen Einfluss des Endanwenders auf die ID-Vergabe zulässt oder nicht. Wenn ersteres der Fall ist, sind mehr oder wenige aufwändige Prüfungen inkl. GUI-Feedback zu realisieren.

Wenn man programmintern konsequent mit Sequenzen (Oracle) oder Auto-Increments arbeitet, hat man keine Probleme, die durch parallele Sessions entstehen können.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben