Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi wie bekomme ich die id des zuletzt geschriebenen Datensatzes (https://www.delphipraxis.net/28161-wie-bekomme-ich-die-id-des-zuletzt-geschriebenen-datensatzes.html)

Grumble 20. Aug 2004 11:28


wie bekomme ich die id des zuletzt geschriebenen Datensatzes
 
hi

ich habe ne IBdatenbank und schreibe nun mit sql strings in eine tabelle, das klappt auch, nun moechte ich gern die zuletzt geschriebene automatisch erzeugt ID herausbekommen, ich hatte mit das in etwa so vorgestellt (zusammengesucht):

Delphi-Quellcode:
       // schreiben der werte
       DBForm.SQLI.sql.clear;
       DBForm.sqli.SQL.Add('insert into IDRECORDS (RECA,RECB,DATNAME,EINSPIELDATUM,EINSPIELER) values ('''+s+''','''+tempstring+''','''+vn+''','''+d+''','''+au+''');');
       DBForm.sqli.ExecQuery;

       DBForm.sqli.sql.clear;
       DBForm.sqli.SQL.add('commit retain;');
       DBForm.sqli.ExecQuery;

       // suchen der ID
       DBForm.sqli.sql.clear;
       DBForm.sqli.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database into :cid;');
       DBForm.sqli.ExecQuery;
beim suchen der id krieg ich ne exception in der steht das into unbekannt ist..

wie kann man sowas machen ?

Gruber_Hans_12345 20. Aug 2004 11:32

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Hi

Delphi-Quellcode:
// suchen der ID
       DBForm.sqli.sql.clear;
       DBForm.sqli.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database;');
       DBForm.sqli.Open;
       
       id := DBForm.sqli.Fields[0].AsInteger;
PS.: Bei der obigen INSERT, üwrde ich trotzdem eher die Variante mit ParamByName bevorzugen, ist einfach viel Übersichtlicher, und nicht so Fehleranfällig (wenn im Text irgendwelche Spezialzeichen vorkommen !!!)

Grumble 20. Aug 2004 11:37

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

PS.: Bei der obigen INSERT, üwrde ich trotzdem eher die Variante mit ParamByName bevorzugen, ist einfach viel Übersichtlicher, und nicht so Fehleranfällig (wenn im Text irgendwelche Spezialzeichen vorkommen !!!)
gut dann werd ich die parambyname variante nehmen...

nun krieg ich beim compilieren in der zeile

Delphi-Quellcode:
DBForm.sqli.Open;
die fehlermeldung:
[Fehler] Anweisung erforderlich, aber Ausdruck vom Typ 'Boolean' gefunden

was fehlt denn da noch??

Gruber_Hans_12345 20. Aug 2004 11:40

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
Delphi-Quellcode:
DBForm.sqli.Open;
die fehlermeldung:
[Fehler] Anweisung erforderlich, aber Ausdruck vom Typ 'Boolean' gefunden

was fehlt denn da noch??

Was ist den sqli für ein Typ ?

Grumble 20. Aug 2004 11:41

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
es ist ein TIBSQL

Gruber_Hans_12345 20. Aug 2004 11:43

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
es ist ein TIBSQL

Probiers mal mit einem TIBQuery. Mit dem sollte beides funktionieren (ExecSQL und Open)

Grumble 20. Aug 2004 11:57

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
ok

nun hab ichs so:
Delphi-Quellcode:
       DBForm.query1.SQL.Clear;
       DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database');
       DBForm.query1.open;
       cid:=DBForm.query1.FieldByName('IDR').AsInteger;
nun krieg ich die fehlermeldung, dass er mein feld IDR nicht findet

Gruber_Hans_12345 20. Aug 2004 12:14

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
ok

nun hab ichs so:
Delphi-Quellcode:
       DBForm.query1.SQL.Clear;
       DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database');
       DBForm.query1.open;
       cid:=DBForm.query1.FieldByName('IDR').AsInteger;
nun krieg ich die fehlermeldung, dass er mein feld IDR nicht findet

entweder mit
Delphi-Quellcode:
       cid:=DBForm.query1.Fields[0].AsInteger;
oder mit

Delphi-Quellcode:
       DBForm.query1.SQL.Clear;
       DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) AS IDR From RDB$Database');
       DBForm.query1.open;
       cid:=DBForm.query1.FieldByName('IDR').AsInteger;

Grumble 20. Aug 2004 12:23

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
danke nun klappt es :-D

allerdings addierte
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database');
immer noch ne id dazu...

deshalb hab ichs in
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,0) From RDB$Database');
geaendert... nun krieg ich wirklich die zuletzt geschriebene id raus

:o

Gruber_Hans_12345 20. Aug 2004 12:28

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
danke nun klappt es :-D

allerdings addierte
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database');
immer noch ne id dazu...

deshalb hab ichs in
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,0) From RDB$Database');
geaendert... nun krieg ich wirklich die zuletzt geschriebene id raus

:o

wo wird den die ID verwendet und in die Tabelle geschrieben ?
Wenn du es so machst wie oben, kann es dir passieren, wenn zwei gleichzeitig (von verschiedenen Computern) aus einen Eintrag erzeugen, das dann die ID's falsch sind, die die bekommst (mit GEN_ID(GEN_IDRECORDS_ID,0))

daher vielleicht eher so :
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,1) From RDB$Database');
DBForm.query1.Open;
id := DBForm.query1.Fields[0].AsInteger;

DBForm.query1.SQL.Add('insert into IDRECORDS (ID, s, ...) values (:ID, :s);');
DBForm.query1.ParamByName('ID').AsInteger := id;
DBForm.query1.ParamByName('s').AsString := s;
DBForm.query1.ExecQuery;
damit hast du 100% die richtige ID ...

nur als Vorschlag

Gruss
Hans

Grumble 20. Aug 2004 12:32

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
danke fuer die vielen tipps :)

ich dachte aber das beim insert wieder der generator anspringt und ne neue id erzeugt und ich somit nicht die richtige erhalte...

es ist eigentlich nie der fall dass 2 gelichzeitig zugreifen... es geht erstmal nur um das fuellen der datenbank, es wird textdatei eingelesen und das in datenbank geschrieben...

Robert_G 20. Aug 2004 12:35

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
Delphi-Quellcode:
DBForm.query1.SQL.add('Select GEN_ID(GEN_IDRECORDS_ID,0) From RDB$Database');
geaendert... nun krieg ich wirklich die zuletzt geschriebene id raus

Es ist aber nicht sichergestellt, dass es auch der DS war, den du eingefügt hast. ;)
  • Tabelle:
    • PK -> Prim. Key
    • A
    • B
    • C
  • INSERT:
    SQL-Code:
    INSERT INTO Tabelle
      (A
      ,B
      ,C)
    VALUES
      (:iA
      ,:iB
      ,:iC)
     RETURNING PK
       INTO :oPK

Der Output Parameter (sollte auch als solcher definiert werden ;) ) enthält jetzt den PK des neuen DS.

Nachtrag:
@Gruber_Hans_12345

Dein Vorschlag würde zwar theoretisch funktionieren, vertößt aber IMHO gegen die Grundregel einen PK immer aus einem BEFORE INSERT Trigger zu beziehen. ;)

Gruber_Hans_12345 20. Aug 2004 12:36

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
ich dachte aber das beim insert wieder der generator anspringt und ne neue id erzeugt und ich somit nicht die richtige erhalte...

schon aber es könnte "theoretisch" sein das :

Insert von Computer 1 ... (bekommt ID 12)
Insert von Computer 2 ... (bekommt ID 13)
GEN_ID(..., 0) bekommst ID 13
GEN_ID(..., 0) bekommst ID 13


Die ID's in der Datenbank sind und bleiben eindeutig, nur den ID den du dir danach rausholst könnte sein, das der falsch ist ...
Da auch die Generatoren nicht über Transaktionen laufen !

Aber wennst nur von einem PC aus das ganze machst (und auch keine Threads verwendets) dann sollte es auch kein Problem geben !

Gruss
Hans

Grumble 20. Aug 2004 12:48

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
@Rober_G

ich hab das jetzt so:
Delphi-Quellcode:
DBForm.SQLI.SQL.Add('INSERT INTO IDRECORDS (RECA,RECB,DATNAME,EINSPIELDATUM,EINSPIELER) values (:s, :tempstring,:vn,:d,:au) RETURNING IDR INTO :cid;');
nur krieg ich jetzt die fehlermeldung das er returning nicht kennt...

???

Gruber_Hans_12345 20. Aug 2004 13:16

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Ich glaube, das das nur mit einer Stored PRocedure funktioniert .. aber das müßte Robert_G besser wissen....

@Robert_G
In meinem Projekt find ich die Version mit ID's holen und dann im Insert String einfügen besser (habe mir einfach eine neue IBQuery erzeugt die das Standardmäßig macht)
Generator name = TabellenName + _ID ... daher funktioniert das ganze ganz gut.

und bei über 300 Tabellen ist es mir zu viel aufwand / Wartung ... jedesmal eine Stored Procedure zu verwenden ... ausser ich habe etwas übersehen, wie es besser funktioniert ...
Dann würde ich mich freuen, wenn du eine Lösung dafür hast.

Gruss
Hans

Hansa 20. Aug 2004 13:50

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Ich kriege etwas Bauchschmerzen, wenn ich so was sehe :

Delphi-Quellcode:
DBForm.SQLI.SQL.Add('INSERT INTO IDRECORDS (RECA,RECB,DATNAME,EINSPIELDATUM,EINSPIELER) values (:s, :tempstring,:vn,:d,:au) RETURNING IDR INTO :cid;');
wieso verwendest du dafür keine STored Procedure und übergibst die Parameter in deinem Delphi-Programm ?

Noch schlimmer ist das hier :

Delphi-Quellcode:
 DBForm.sqli.sql.clear;
       DBForm.sqli.SQL.add('commit retain;');
       DBForm.sqli.ExecQuery;
Wieso nicht :

Delphi-Quellcode:
TransAction.CommitRetaining;
:gruebel:

Robert_G 20. Aug 2004 14:03

Re: wie bekomme ich die id des zuletzt geschriebenen Datensa
 
Zitat:

Zitat von Grumble
nur krieg ich jetzt die fehlermeldung das er returning nicht kennt...

Sorry, ich erinnere mich gerade an einen ähnlichen Thread. Es gibt in Interbase oder Firebird keine hübsche und konsistente Lösung dafür.

Zitat:

...und bei über 300 Tabellen ist es mir zu viel aufwand / Wartung ... jedesmal eine Stored Procedure zu verwenden ... ausser ich habe etwas übersehen, wie es besser funktioniert ...
Dann würde ich mich freuen, wenn du eine Lösung dafür hast.
Warum unbedingt eine SP? (Obwohl die SP geändert werden kann ohne den Client neu zu kompostieren. )
Niemand legt heute noch Trigger für einen PK per Hand an. Dafür gibt es dynamisches SQL. ;)
Wenn du per Trigger die PK festlegst, ist es vollkomen egal wie auf die Daten zugegriffen wird -> Du bekommst immer einen konsistenten PK.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:10 Uhr.

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