Seite 1 von 1
Nummernkreise automatisiert. [erledigt]
Verfasst: Fr, 02. Jun 2023 11:16
von Manfred
ich habe eine Kundendatei, in der es ein Feld gibt für Kundennummern. Dieses Feld soll jedesmal um 1 hochgezählt werden bei einem Insert. Es muß aber unterschieden werden in verschiedene Kategorien. Ist es die Kundenart "A", dann bitte aus dem Nummernkreis die nächsthöhere nehmen, ist es die Kundenart "B", dann bitte aus dem anderen Nummerkreis die nächsthöhere Nummer nehmen. usw. natürlich darf keine Nummer doppelt vergeben werden. Wie könnte man sowas elegant lösen? Wenn es nur 1 Kreis wäre, wäre es ja mit einem autoincrement zu lösen, aber bei verschiedenen Nummernkreisen? Schön wäre es, wenn der ADS es auch verwalten würde, das bei Parallelerfassungen keine Nummer doppelt vergeben wird.
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 12:18
von nightcrawler
Hier aus meinen Trainings der Code zur Erstellung eines Generators. Die Werte für die Nummernkreise werden in einer Tabelle verwaltet. Bei Abruf wird Transaktionssicher der Wert um eins erhöht.
Code: Alles auswählen
CREATE FUNCTION gen_id(cname cichar(255))
RETURNS integer
BEGIN
declare @numrows integer;
declare @nextid integer;
declare @rv integer;
--create generator table if not exists
if not exists(select * from system.tables where name like 'tb_generator') then
create table tb_generator(id autoinc, name cichar(255), lastid integer, rv rowversion);
endif;
--check if there's already a generator for that name
MERGE tb_generator ON name LIKE cname
WHEN NOT MATCHED THEN INSERT(name,lastid) VALUES(cname,0);
--now update that record until you got it (concurrency!)
@numrows=0;
while @numrows=0 do
@rv=(select rv from tb_generator where name like cname);
@nextid=(select lastid+1 from tb_generator where name like cname);
try
update tb_generator set lastid=@nextid where name like cname and rv=@rv;
--if there's no update, another user already updated that record
@numrows=(select ::stmt.UpdateCount from system.iota);
catch all
@numrows=0;
end try;
end while;
return @nextid;
END;
Verwendung:
Das kannst Du entweder direkt verwenden (im Insert) oder in einem Trigger. Als Text gibst Du den Nummernkreis an.
Edit: Falls es Dir bekannt vorkommt. Du hast auch am ADS Workshop in Willingen am 4.5.2017 teilgenommen. Einfach nochmals das Script lesen;)
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 12:42
von Manfred
auh man,
jetzt hast Du ordentlich Salz in die Wunde gestreut. Meine Erinnerung daran sind etwas dünn. Ich habe auch keine Ahnung, wo das Script sein könnte. Hast Du das noch irgendwo?
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 12:44
von nightcrawler
ja.
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 14:18
von Tom
Manfred war in Willingen auch NUR AM FEIERN. Dass er sich überhaupt noch daran erinnert, mal dort gewesen zu sein, grenzt an ein Wunder.
Ich hätte ihm das Script aus dem Kopf aufschreiben können.
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 14:34
von Manfred
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 15:12
von Tom
Das war natürlich nur ein Witz.
Re: Nummernkreise automatisiert.
Verfasst: Fr, 02. Jun 2023 15:50
von Manfred
Re: Nummernkreise automatisiert.
Verfasst: Do, 08. Jun 2023 11:44
von Manfred
nightcrawler hat geschrieben: ↑Fr, 02. Jun 2023 12:18
Verwendung:
Das kannst Du entweder direkt verwenden (im Insert) oder in einem Trigger. Als Text gibst Du den Nummernkreis an.
Die Funktion habe ich angelegt. Es kommt auch was zurück. Aber was meinst Du mit "als Text". oder meinst Du damit den Wert 'test' ?
da habe ich folgendes gemacht
hier bekomme ich aber nur ab 1 hochgezählt jedesmal zurück.
Re: Nummernkreise automatisiert.
Verfasst: Do, 08. Jun 2023 13:58
von nightcrawler
Name des Generators
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Do, 08. Jun 2023 15:44
von Martin Altmann
Manfreds Problem: er möchte eine noch nicht vergebene Nummer - wobei der Generator beginnen soll bei 4.000.000 - also die nächste unbenutzte Nummer ab 4 Millionen liefern soll.
Nur damit ihr nicht wieder aneinander vorbei schreibt...
Viele Grüße
Martin
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Do, 08. Jun 2023 15:50
von Manfred
OK,
ich glaube ich habe es kapiert.
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Do, 08. Jun 2023 16:13
von Manfred
ich hatte den Zusammenhang überhaupt nicht erkannt. Es wird eine weitere Tabelle im DD angelegt, in der die Werte gespeichert werden. Die Function (könnte ja auch eine eigene im programm sein, ist aber dann nicht zählsicher) im DD wird aufgerufen und erzeugt dann immer wieder die benötigten Zahlen. Mir ist trotz mehrmaligen Schauen nicht aufgefallen, das eine neue Tabelle im DD erzeugt wurde. (in dem Falle tb_generator) ich nhabe sie einfach übersehen. Weil nicht erwartet. Jetzt ist alles klar. Die Werte werden einfach in die Tabelle eingetragen und dann macht die Function den Rest. War mal wieder zu einfach um es sofort zu erkennen..... menno.
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Do, 08. Jun 2023 17:21
von nightcrawler
Manfred hat geschrieben: ↑Do, 08. Jun 2023 16:13
ich hatte den Zusammenhang überhaupt nicht erkannt. Es wird eine weitere Tabelle im DD angelegt, in der die Werte gespeichert werden.
wie in meinem ersten Post genannt:
Die Werte für die Nummernkreise werden in einer Tabelle verwaltet.
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Fr, 09. Jun 2023 6:35
von Manfred
Hatte ich total überlesen, bzw. nicht registriert. Ich hatte das Konzept zu dem Zeitpunkt überhaupt nicht verinnerlicht.
Meine Frage wäre aber noch, wie sicher ist das gegen doppelte Vergabe von Nummern? So ein Konzept hatte ich früher ohne ADS auch und da habe ich jedesmal die Nummerntabelle exklusiv geöffnet und somit verhindert, das Nummern doppelt vergeben werden konnten.
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Sa, 10. Jun 2023 12:08
von nightcrawler
100% sicher bei bei remote server, da rowversion abgefragt wird.
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Sa, 22. Jul 2023 8:46
von Manfred
und wo liegt hier der Denkfehler?
Code: Alles auswählen
UPDATE mandanten SET kundennummer=(SELECT gen_id('Schüler') from system.iota)
hier wird nicht bei jedem Satz hochgezählt nur beim ersten Mal. Wird das nicht bei jedem Satz erneut aufgerufen, oder nur 1x und dann für alle restlchen so übernommen?
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Sa, 22. Jul 2023 11:51
von nightcrawler
Hallo Manfred,
genauso ist es. Du legst einmal den Wert fest und änderst alle Datensätze auf genau diesen Wert.
Besser: Trigger erstellen und dann bei Nichtvorhandensein der Nummer, diese einfügen:
Code: Alles auswählen
CREATE TRIGGER upd_mandanten ON mandanten AFTER UPDATE
BEGIN
UPDATE mandanten SET kundennummer=gen_id('Schüler') WHERE kundennummer IS NULL and ROWID=::stmt.TrigRowid;
END
Dan ein Update über alle Datensätze
Re: Nummernkreise automatisiert. [erledigt]
Verfasst: Sa, 22. Jul 2023 12:08
von Manfred
Danke Joachim,
war mal wieder mein Denkfehler. Habe den Ablauf falsch erkannt. Select hat da nichts zu suchen.