Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird gen_id() (https://www.delphipraxis.net/56738-firebird-gen_id.html)

CoLT 10. Nov 2005 11:05

Datenbank: Firebird • Version: 1.5 • Zugriff über: dBExpress

Firebird gen_id()
 
Gibt es eine Möglichkeit auf eine generierte ID nach dem Insert zuzugreifen ?

Der Select auf den Generator(tabelle) selber ist keine Lösung, da bei Multiusing die Gefahr besteht, dass ich die ID von einem anderen Insert bekomme.

Bei Informix gibt es die Moeglichkeit den SQLCA Record auszulesen, mit einem Staus der letzten DB-Aktion sozusagen. Dort finde ich auch den Wert der serial Feldes.

Bei MS-SQL gibt es die Methode "SELECT @@IDENTITY" was auch super funktioniert.

Nur bei Firebird sehe ich derzeit keine andere Möglichkeit als mir einen neue ID vor dem INSERT zu reservieren.


Ich hoffe es kann mir jemand helfen ...


mfg CoLT

Jelly 10. Nov 2005 11:21

Re: Firebird gen_id()
 
Da war doch irgendwas in der Art
SQL-Code:
select gen_id (GeneratorName)
wenn ich mich täusche. :gruebel:

CoLT 10. Nov 2005 11:43

Re: Firebird gen_id()
 
das geht nicht wenn 2 inserts gleichzeitig passieren ...(multiusing)

dfried 10. Nov 2005 11:51

Re: Firebird gen_id()
 
Zitat:

Zitat von CoLT
das geht nicht wenn 2 inserts gleichzeitig passieren ...(multiusing)

Warum nicht?!?
Gen_id liefert (soweit ich weis) immer den nächsten Generatorwert unabhängig von einer Transaktion zurück.

Jelly 10. Nov 2005 11:55

Re: Firebird gen_id()
 
Zitat:

Zitat von dfried
Gen_id liefert (soweit ich weis) immer den nächsten Generatorwert unabhängig von einer Transaktion zurück.

Nicht den nächsten, sondern den aktuellen. Und wenn Du ein Insert und die anschliessende gen_id Abfrage innerhalb von einer Transaktion durchführst, kann da nichst passieren.

dfried 10. Nov 2005 12:01

Re: Firebird gen_id()
 
Ich würde das dann eher andersrum machen, sonst kann wirklich ein Problem mit "gleichzeitigen Inserts entstehen.

Also zuerst SELECT GEN_ID(MY_GENERATOR, 1) und dann im INSERT INTO den soeben ermittelten Generatorwert als PK mit reinschreiben.

marabu 10. Nov 2005 12:03

Re: Firebird gen_id()
 
Herzlich willkommen in der Delphi-PRAXiS, CoLT.

Auch in FireBird kannst du - innerhalb einer Transaktion - den Generatorwert nach der Zuweisung im INSERT auslesen. Mehr dazu hier: klick

Grüße vom marabu

Lemmy 10. Nov 2005 12:15

Re: Firebird gen_id()
 
@marabu: Das verhindert aber nicht, dass jemand den Generatorwert inzwischen durhc nen anderen Insert verändert hat!

Die Lösung von dfried ist korrekt. Alternativ könntest Du das ganze dann noch in ne StordeProcedure verlegen (also den Insert) und die Prozedur den Wert zurückgeben lassen....

Grüße
Lemmy

Jelly 10. Nov 2005 12:18

Re: Firebird gen_id()
 
Zitat:

Zitat von dfried
Also zuerst SELECT GEN_ID(MY_GENERATOR, 1) und dann im INSERT INTO den soeben ermittelten Generatorwert als PK mit reinschreiben.

Eben genau nicht. Du fügst ganz normal deinen Record hinzu, und über einen Trigger ermittelst du dir die gen_id. Nach dem Insert ist für dich, und nur für dich, der aktuelle gen_id wert der Wert, den du beim Insert verwendest hast.

Wie Marabu verlinkt hat, lies Dir mal was in Sachen Transaktionen auf DB Server durch.

dfried 10. Nov 2005 12:32

Re: Firebird gen_id()
 
Zitat:

Zitat von Jelly
Eben genau nicht. Du fügst ganz normal deinen Record hinzu, und über einen Trigger ermittelst du dir die gen_id. Nach dem Insert ist für dich, und nur für dich, der aktuelle gen_id wert der Wert, den du beim Insert verwendest hast.

Sorry, komm halt aus der ORACLE-Welt und kenn FB nur am Rande. Und bei ORACLE sind die Sequence-Werte halt vollkommen Transaktionsunabhängig, da würde es so nicht funktionieren, dafür gibts dort wieder andere Möglichkeiten sowas zu machen :-)

Zitat:

Zitat von Jelly
Wie Marabu verlinkt hat, lies Dir mal was in Sachen Transaktionen auf DB Server durch.

Ich glaub das ist nicht unbedingt notwendig, das prinzip von Transaktionen kenn ich glaub ich nach acht Jahren Programmieerfahrung mit ORACLE gut genug. :mrgreen:
Aber wie gesagt, lässt sich nicht für alle "DB-Server" pauschalieren.

Lemmy 10. Nov 2005 12:34

Re: Firebird gen_id()
 
Zitat:

Zitat von Jelly
Wie Marabu verlinkt hat, lies Dir mal was in Sachen Transaktionen auf DB Server durch.

???

wenn ich

SQL-Code:
Select gen_id(generator1,1) AS ID from rdb$database);
und dann das ERGEBNIS DIESER ABFRAGE einer Insert-SQL zuweise

SQL-Code:
INSERT INTO Test VALUS (:ID, :NAME);
da kann nichts schief laufen! Außer dass jemand einen Trigger für die ID-Ermittlung nicht korrekt erzeugt und dieser beim Insert nochmals eine ID anfordert!

Grüße
Lemmy

dfried 10. Nov 2005 12:38

Re: Firebird gen_id()
 
Tja, viele Wege führen nach Rom :)
Besser gesagt, beide Vorschläge würden ohen Probleme auch in Multiuserumgebungen funktionieren!

marabu 10. Nov 2005 12:42

Re: Firebird gen_id()
 
Hallo Lemmy,

ich habe den Eindruck, dass CoLT ein technisches Interesse an der Frage hat, ob auch unter FireBird der Zugriff auf den Generator im nachhinein möglich ist. Ich habe meinen Beitrag zu einer solchen Überlegung bereits in dem verlinkten thread gemacht, aber hier gerne noch einmal mit anderen Worten: Der Generator wird von FireBird nicht relational verwaltet, er kann deshalb auch nicht von einem RollBack erfasst werden - das darf auch gar nicht sein. Niemand kann den Generator zwischen meinem INSERT und dem darauf folgenden Auslesen verändern, solange diese Zugriffskombination durch eine Transaktion serialisiert wird. Durch die Verwendung des Inkrements 0 beim Auslesen kann ich den Generator-Wert vor oder nach dem INSERT bestimmen, wenn ich ihn in meiner Anwendung benötige. Die Vergabe im INSERT selbst überlässt man üblicherweise einem Trigger - siehe Jelly's Beitrag.

Grüße vom marabu

PS: Ich schreibe zu langsam - bereits drei Beiträge haben mich jetzt überholt. Ist aber auch ein schwieriges Thema.

@dfried: Ich glaube nicht, dass dir Tom Nachhilfe verordnen wollte. Es geht hier wohl eher um die spezielle Implementierung der Generatoren unter Interbase bzw. FireBird.

Lemmy 10. Nov 2005 12:51

Re: Firebird gen_id()
 
Zitat:

Zitat von marabu
HDurch die Verwendung des Inkrements 0 beim Auslesen kann ich den Generator-Wert vor oder nach dem INSERT bestimmen, wenn ich ihn in meiner Anwendung benötige. Die Vergabe im INSERT selbst überlässt man üblicherweise einem Trigger - siehe Jelly's Beitrag.

aber es ist nicht sicher gestellt, dass der zurückgegebene Wert mit der Insert-ID übereinstimmt, eben weil Generatoren nicht transaktionsgesteuert sind.
Aus diesem Grund muss man das Zeugs also entweder in eine StoredProc packen oder den Generator-ID auslesen und dann beim Insert manuell setzen - wenn man die ID im Programm benötigt!

Grüße
Lemmy

marabu 10. Nov 2005 12:59

Re: Firebird gen_id()
 
Lemmy, bist jetzt einen ziemlich großen Bogen gelaufen - lies nochmal meinen Beitrag von 13:03.

Freundliche Grüße vom marabu

CoLT 10. Nov 2005 13:16

Re: Firebird gen_id()
 
ein select auf den generator nach dem insert ob transaction oder nicht schlägt fehl... da jeder insert den erhöht ...

ich habs getestet!

so wie es aussieht komme ich nicht drum herum mir die id vorher zu reserveren für meinen insert.

*heul*

Lemmy 10. Nov 2005 13:36

Re: Firebird gen_id()
 
Genau das haben, glaube ich, fast alle in diesem Thread auch gesagt....

@marabu:

Zitat:

Auch in FireBird kannst du - innerhalb einer Transaktion - den Generatorwert nach der Zuweisung im INSERT auslesen
etwas verwirrend der Satz, meinst Du nciht ;-) Vorallem wenn du dann auf das hier linkst:

SQL-Code:
SELECT GEN_ID(DeinGeneratorName, 0) FROM RDB$DATABASE
vorallem weil Du über diese Anweisung nie die ID auslesen kannst, die ein eben ausgeführter Insert erhalten hat.

Grüße
Lemmy

dfried 10. Nov 2005 13:41

Re: Firebird gen_id()
 
Zitat:

Zitat von marabu
@dfried: Ich glaube nicht, dass dir Tom Nachhilfe verordnen wollte. Es geht hier wohl eher um die spezielle Implementierung der Generatoren unter Interbase bzw. FireBird.

Hab ich auch nicht so verstanden, habs ja auch mit nem Smiley kommentiert. :-D
Ausserdem lern ich immer gerne noch was auch über andere DB's dazu, ORACLE kenn ich halt ziemlich gut, aber aktuell mach ich auch ein Projekt mit FB/IB, von daher ist das ganze schon nützlich. :)

marabu 10. Nov 2005 13:41

Re: Firebird gen_id()
 
Hallo CoLT,

weine nicht...

Die meisten arbeiten so, wie wir alle es zusammen hier erarbeitet haben. Dass das INSERT den Generator erhöht ist richtig, kannst du aber beim Zugriff "danach" leicht korrigieren.

@Lemmy: ich vergesse oft auf vermeintliche Banalitäten hinzuweisen, aber das müsst ihr mir alle verzeihen - wegen meines biblischen Alters...

marabu

Lemmy 10. Nov 2005 13:45

Re: Firebird gen_id()
 
Zitat:

Zitat von marabu
@Lemmy: ich vergesse oft auf vermeintliche Banalitäten hinzuweisen, aber das müsst ihr mir alle verzeihen - wegen meines biblischen Alters...

Ausreden zählen nicht ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:59 Uhr.

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