Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich? (https://www.delphipraxis.net/182653-wie-fortlaufende-nr-db-taballe-erzeugen-generator-nicht-moeglich.html)

BlueStarHH 7. Nov 2014 15:23

Datenbank: Firebird • Version: 2 • Zugriff über: IBDAC

Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Hallo,

ich habe eine Firebird-Tabelle mit Buchungen:

Code:
Konto   BuchungNr  Text           usw.
------  ---------  -------------
4600    1          Reise München
4600    2          Reise Berlin
4930    1          Büroklammern
Jedes Konto hat seine eigene Buchungsnummer von 1 bis n. Wie kann ich nun die nächste Buchungsnummer für ein bestimmtes Konto ermitteln? Die nächste BuchungNr für Konto 4600 wäre hier also die 3 und für Konto 4930 die 2.

Es soll in einer Client/Server Umgebung keine doppelten Nummern geben. Auf dem Client den Max-Wert der BuchungNr für ein bestimmtes Konto mit SQL holen scheidet wohl aus, da in der Zeit wo die Abfrage ausgeführt wird, ein anderer Client dazwischenfunken könnte. Ein Generator scheidet wohl auch aus, da ich nicht für jedes Konto einen eigenen Generator anlegen kann. Es sind hunderte von Konten. Ab und zu kommen neue dazu.

Was also tun?

HPB 7. Nov 2014 15:37

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Guten Tag,
Wie wäre es mit
Delphi-Quellcode:
Select count(*) as AnzBuchungen from Table
 where kontonr = :pKontoNr
Allerding hättest Du wieder doppelte Nummern wenn ein Datensatz für ein Konto gelöscht wird.
Dies kann aber übergangen werden, wenn Du in der Tabelle eine Spalte "geloescht = J/N' führst
Sollte eine Buchung gelöscht werden dann setzt Du den Wert auf "J".
Damit kannst Du ja die Daten so selektieren:
Delphi-Quellcode:
select * from table where geloescht = 'N'
Für die nächste Nummer wäre so ein Konstrukt evtl hilfreich:
Delphi-Quellcode:
select count(*) as Anzahl from table where geloescht = 'N'
and KontoNr = :pKontoNr
Gruß HPB

BlueStarHH 7. Nov 2014 15:41

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Zitat:

Zitat von HPB (Beitrag 1279066)
Guten Tag,
Wie wäre es mit
Delphi-Quellcode:
Select count(*) as AnzBuchungen from Table
 where kontonr = :pKontoNr
Allerding hättest Du wieder doppelte Nummern wenn ein Datensatz für ein Konto gelöscht wird.
Dies kann aber übergangen werden, wenn Du in der Tabelle eine Spalte "geloescht = J/N' führst
Sollte eine Buchung gelöscht werden dann setzt Du den Wert auf "J".
Damit kannst Du ja die Daten so selektieren:
Delphi-Quellcode:
select * from table where geloescht = 'N'
Für die nächste Nummer wäre so ein Konstrukt evtl hilfreich:
Delphi-Quellcode:
select count(*) as Anzahl from table where geloescht = 'N'
and KontoNr = :pKontoNr
Gruß HPB

Hi HPB,

danke, das geht aber nicht denn es gibt beim "count" das selbe Problem wie beim "max-Wert":

Zitat:

Auf dem Client den Max-Wert der BuchungNr für ein bestimmtes Konto mit SQL holen scheidet wohl aus, da in der Zeit wo die Abfrage ausgeführt wird, ein anderer Client dazwischenfunken könnte.
Ich versuche es nochmal deutlicher zu machen. Client A fragt per SQL den count/max-Wert ab. Bevor er den neuen Datensatz posten kann, haben die Clients B und C ebenfalls den count/max-Wert abgefrag. Alle 3 Clients haben dann den selben count/max-Wert und wollen den selben Wert posten. Wer dann zuerst posted hat gewonnen und bei den anderen beiden Clients gibt es eine Fehlermeldung der Art "Buchungsnummer nicht eindeutig"

Medium 7. Nov 2014 15:42

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
SQL-Code:
SELECT MAX(BuchungsNr) FROM Tabelle WHERE Konto = :GewünschtesKonto GROUP BY Konto
gibt dir die derzeit höchste Buchunsnummer für ein bestimmts Konto. Lücken bei mitten drin gelöschten Datensätzen verbleiben dann. Wenn dies nicht gewünscht ist, dann bleibt nicht viel mehr als manuell alle Sätze sortiert durchzuiterieren bis eine nicht vergebene Nummer gefunden wurde.

Edit: Aha, jetzt erst das Timingproblem gesehen. Dann bleiben nur Serverseitige Ansätze. Vielleicht ließe sich da ein Trigger für bauen, da bin ich allerdings nicht fit genug drin hierfür. Sorry.

Lemmy 7. Nov 2014 15:47

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Hi,

das Problem kannst Du nur über eine Tabellensperre lösen, d.h. einer schreibt, alle anderen dürfen nur noch lesen.

Je nachdem was Du mit den fortlaufenden Nummer machen willst, könnte dir da aber schon ein Generator helfen - aber kommt halt darauf an ob die nur der Ordnung dienen oder sonst noch eine Funktion übernehmen...

Grüße

himitsu 7. Nov 2014 15:50

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Wenn man nicht ständig suchen will, auch gelöschte Datensätze keine doppelte ID erzeugen sollen, dann könntest du dir auch mehrere "Generatoren" erstellen und je nach Konto den passenden/zugehörigen Generator verwenden.
Bzw. das halt in einer eigenen kleinen Tabelle (Konto, LastNumber) verwalten, oder gibt es schon eine Tabelle mit den Konten?

Selbst wenn man nun alles löscht, blieben due Nummern eindeutig.

DeddyH 7. Nov 2014 16:06

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Zitat:

Zitat von himitsu (Beitrag 1279071)
Wenn man nicht ständig suchen will, auch gelöschte Datensätze keine doppelte ID erzeugen sollen, dann könntest du dir auch mehrere "Generatoren" erstellen und je nach Konto den passenden/zugehörigen Generator verwenden.

Wenn das jemand hinbekommt, würde mich die Umsetzung interessieren.

Jasocul 7. Nov 2014 16:18

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Da sehe ich jetzt nicht so das Problem.
Generatoren kann man auch zur Laufzeit erzeugen. Also beim Anlegen eines Kontos einen Generator mit einem passenden Namen anlegen und diesen dann bei den Buchungen entsprechend benutzen.
Generatoren in Firebird erzeugen

DeddyH 7. Nov 2014 16:50

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Wenn man das aber nicht dem Frontend überlassen will, wird es etwas komplizierter. Sofern mein Gedankengang richtig ist, bräuchte man 2 SPs: eine für das Erzeugen eines neuen Kontos (legt den Generator an) und eine für das Erzeugen einer neuen Buchung (holt sich den aktuellen Generatorwert und trägt ihn ein). Dann müsste man nur noch sicherstellen, dass das Einfügen von Datensätzen nicht mehr direkt, sondern nur noch über diese SPs möglich ist. So könnte es funktionieren, wenn ich mich nicht irre.

mjustin 7. Nov 2014 16:55

AW: Wie fortlaufende Nr. in DB-Taballe erzeugen? Generator nicht möglich?
 
Zitat:

Zitat von himitsu (Beitrag 1279071)
... dann könntest du dir auch mehrere "Generatoren" erstellen und je nach Konto den passenden/zugehörigen Generator verwenden.

Einzige Einschränkung:
immer wenn eine neue Nummer generiert, aber (weil ein Fehler auftritt) nicht beim INSERT verwendet wird, wird diese Nummer unbenutzt und es bleibt eine "Lücke". (Da Generatoren ihre Werte ausserhalb von Transaktionen erhalten, können diese nicht durch ein Rollback verhindert werden.)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:45 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz