Anmelden

View Full Version : SQL nächste freie Nummer ermitteln



tarkusch
03-06-19, 08:26
Hallo,

ich habe aus dem Forum ein tolle Sql-Routine bekommen und die nächste freie Personalnummer zu ermitteln.
Es wird die nächste freie Nummer zwischen 10000 und 99999 gesucht.
Ich hatte früher nur Penr als Keyfeld.
Wie verknüpfe ich diese Abfrage mit einem zusätzlichen Key (FINR)?
Mein Ziel ist es das die PENR eindeutig und unique ist.
Bei diversen Tests bekomme ich eine Penr zurück die bereits vergeben ist.


WITH LFDNBR (LEVEL)
AS (VALUES(10000)
UNION ALL
SELECT LEVEL + 1 FROM LFDNBR
WHERE LEVEL < 99999)
SELECT IFNULL(LEVEL, 0)
FROM LFDNBR
EXCEPTION JOIN PERP ON LEVEL = PENR
ORDER BY LEVEL
FETCH FIRST ROWS ONLY


Dank im Voraus

Fuerchau
03-06-19, 09:50
EXCEPTION JOIN PERP ON LEVEL = PENR and FINR = 'x'

Sicher und schnell ist das allerdings nicht, da immerhin mehrere 1000 Zugriffe gemacht werden müssen.
Andererseits werden auch Lücken (also Löschungen) wieder verwendet.
Besser ist da schon immer eine eigene Tabelle mit der Nummernvergabe.
Ganz extrem hatte ich mir mal eine Tabelle der Nummern von n bis m erstellt.
Beim Ermitteln die erste Nummer genommen und gelöscht, so dass auch kein 2. Prozess dieselbe Nummer noch mal vergibt.
Beim Löschen (am besten Trigger) wird die freie Nummer in die Tabelle zurückgeschrieben.
Die Vorteile sind da auf meiner Seite;-).

ExAzubi
03-06-19, 09:53
Entweder FiNr in den Group by mit reinbringen, so das du diese mit abfragen kannst. Oder anstatt mit einer CTE zu arbeiten eine Procedure mit FiNr als Eingangsparamter...

tarkusch
03-06-19, 10:15
EXCEPTION JOIN PERP ON LEVEL = PENR and FINR = 'x'


Für was steht 'x'?
Finr sind bei uns 3-stellig.
Wenn ich ein Join auf eine logische Datei die den Key PENR hat und unique ist, würde das funktionieren?

@ExAzubi: Mit Group by habe ich es funktioniert, hat aber nicht das gewünschte Ergebnis gebracht.

xenofob
03-06-19, 10:46
Kommt auch etwas Schlankes in Frage?

SELECT min(a.penr)+1
from PERP a
left outer join PERP
b on a.penr = b.penr +1
where b.penr is null

mit FINR im unique key

SELECT min(a.penr)+1
from PERP a
left outer join PERP
b on a.penr = b.penr +1 and a.finr = b.finr
where b.penr is null and a.finr = '001'

Fuerchau
03-06-19, 10:55
Wie ist dann diese Frage zu verstehen?

"Wie verknüpfe ich diese Abfrage mit einem zusätzlichen Key (FINR)?"

Wenn die PENR bereits unique ist, wozu brauchst du die FINR?
Oder ist die PENR nur incl. FINR unique?

tarkusch
03-06-19, 11:04
Mit dieser Statement habe ich eigentlich angefangen, aber die Nummern von 10475 bis 12000 sind frei und er leifert mir den wert 12002 zurück.


SELECT min(a.penr) + 1
FROM PERP a
left outer join PERP b
on a.penr = b.penr + 1
WHERE b.penr is null
and a.penr > 10000

tarkusch
03-06-19, 11:06
Ich habe die Personaldatei die hat den Key FINR/PENR und ist unique.

Dann gibt es eine Logische die den Key PENR hat und auch unique ist.

xenofob
03-06-19, 11:21
Wenn FINR und PENR unique keys sind, dann ist natürlich der left outer join mit zusätzlich der FINR wichtig.

tarkusch
03-06-19, 11:48
Danke für eure Hilfe und Input.

Ich habe es nun wie folgt gelöst:



WITH LFDNBR (LEVEL)
AS (VALUES(10000)
UNION ALL
SELECT LEVEL + 1 FROM LFDNBR
WHERE LEVEL < 99999)
SELECT IFNULL(LEVEL, 0)
FROM LFDNBR
WHERE LEVEL NOT IN (SELECT PENR FROM PERP)
EXCEPTION JOIN PERP ON LEVEL = PENR
ORDER BY LEVEL
FETCH FIRST ROWS ONLY

lg