Einzelnen Beitrag anzeigen

Delphi.Narium

Registriert seit: 27. Nov 2017
2.508 Beiträge
 
Delphi 7 Professional
 
#15

AW: Letzte vergebene Nummer speichern

  Alt 5. Aug 2022, 15:35
Was heißt denn das?

Dieser wird aber von Zeit zu Zeit auch wieder auf 1 gesetzt.
Mit System, eher zufällig?

Wenn der Generator zurückgesetzt wird, müssen zeitgleich auch alle Datensätze aus der Tabelle entfernt werden. Zur Erkennung des neuesten Satzes benötigst Du einen eindeutigen Wert, der die korrekte Erkennung sicherstellt. Wenn dieser Wert allerdings "wahlfrei" zurückgesetzt oder verändert wird, ist eine eindeutige Erkennung nicht mehr gegeben. Das spricht ganz klar für ein Designproblem.

Einen Generator, den man für die eindeutige Kennzeichnung von Werten nutzt, setzt man nicht zurück. Allenfalls dann, wenn die Gefahr eines Überlaufes besteht.

Der Wertebereich von Generatoren bei FireBird liegt zwischen
Code:
-2^63 .. 2^63
-9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807
Wenn man nach dem Erstellen eines Generators den Wert auf -2^63 setzt, kann man damit schon 'ne ganze Weile auskommen. Selbst bei 1.000.000 IDs pro Sekunde könnte das dann mit fast 584.942,41735507203247082699137494 Jahren, auch bei optimistischer Betrachtung, die Laufzeit heutiger Software deutlich übersteigen

Wenn Du also heute einen entsprechenden Generator (wie im obigen Post bechrieben) erstellst, darfst Du ihn in ca. 584.000 Jahren auf -2^63 setzen.

Und: Derartige generatorgenerierte IDs werden nie, nie und nochmals nie für was anderes verwendet, als für die Feststellung, welches ist der neueste Wert. Es gibt also (für meine Begriffe) keinen vernunftbegabten Grund, weshalb man einen für diese Aufgabe genutzten Generator jemals wieder auf 1 setzen sollte. (Ok, ist etwas arg überspitzt formuliert )

---

Du kannst einen Generator nutzen:
...
Wenn Du eine neue ID erstellt hast, schreibst Du diese per Insert insert into LastID (DeineID) values (DerWertDerID); in diese Tabelle.
Wann rufe ich das insert into auf? Wie ist sichergestellt, dass das insert into mit der zuletzt erzeugten ID aufgerufen wird? So klappt das z.B. *nicht*:


Code:
procedure GetNextID
  a := ErzeugePrefix;
 
  if Bedingung then
    b := gen_id(MeinGenerator, 1);
  else
    b := '';

  c := ErzeugeSuffix;

  result := a+b+c;

  insert into LastID (DeineID) values (DerWertDerID)
end;
Beispiel: Benutzer A erzeugt mit gen_id die Nr 1. Jetzt kommt schon Benutzer B und erzeugt die Nr 2 mit gen_id und schreibt diese mit insert into in die LastID-Tabelle. Nun wird erst die letzte Zeile der SP vom Benutzer A aufgerufen und schon steht die 1 als falsche letzte ID in der LastID-Tabelle.
Hier haben wir genau das Problem, nach dem Uwe Raabe soeben gefragt hat.

Was ist jetzt die letzte ID. Die, die beim letzten Aufruf der SP (durch wen auch immer) generiert wird, oder die, die beim letzten Beenden der SP (durch wen auch immer) erstellt wird.

Ruft Benutzer A die SP auf und die dauert 1 Stunde und dazwischen rufen Benutzer B bis Z die SP auf, mit 'ner Laufzeit von 1 Sekunde, wobei der letzte Aufruf von B bis Z garantiert vor dem Aufruf von A beendet wird. Was ist jetzt die letzte ID? Die von A, weil zuletzt fertig oder die von dem Benutzter, die zuletzt gestartet wurde, unabhängig vom Zeitpunkt der Beendigung?

Oder insert into LastID (GeneratorID, DeineID) values (Gen_ID(GEN_LastID, 1),Result)

Ist das immernoch nicht so ganz das, was gewünscht wurde, dann kannst Du Dir auch am Beginn der SP per SQL den nächsten Wert des Generators in einer Variabel speichern und dann diesen Wert am Ende beim Insert in die Tabelle schreiben.

Sinngemäß, ohne irgendwie auf korrekte Syntax zu achten:
SQL-Code:
procedure GetNextID
  select (Gen_ID(GEN_LastID, 1) into v_GenLastID; -- Zeile ggfls. dahin verschieben, wo sie im Ablauf korrekt positioniert ist.

  a := ErzeugePrefix;
 
  if Bedingung then
    b := gen_id(MeinGenerator, 1);
  else
    b := '';

  c := ErzeugeSuffix;

  result := a+b+c;

  insert into LastID (GeneratorID, DeineID) values (v_GenLastID, Result);
end;
Da die Fachlichkeit nicht wirklich bekannt ist, eventuell auch in der Form:
SQL-Code:
procedure GetNextID
 
  a := ErzeugePrefix;
  c := ErzeugeSuffix;
 
  if Bedingung then
    select (Gen_ID(GEN_LastID, 1) into v_GenLastID; -- je nach Fachlichkeit
    b := gen_id(MeinGenerator, 1); -- ggfls. Zeilen vertauschen
    insert into LastID (GeneratorID, DeineID) values (v_GenLastID, a+b+c);
  else
    b := '';

  result := a+b+c;
end;

Geändert von Delphi.Narium ( 5. Aug 2022 um 15:38 Uhr) Grund: Schreibfehler
  Mit Zitat antworten Zitat