Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi IBSQL - INSERT Problem (https://www.delphipraxis.net/16763-ibsql-insert-problem.html)

Quake 23. Feb 2004 09:41


IBSQL - INSERT Problem
 
Hallo,

ich benutze eine IB-Datenbank un habe dort einen Before-Insert-Trigger erstellt, der mir einige Felder berechnet. Füge ich nun einen Datensatz per INSERT ein, wird eine ID im Trigger generiert und die anderen Felder berechnet.
Nun zu meiner Frage. Wie bekomme ich die ID und die berechneten Felder zurück?

Code:
var
  i: integer;
begin
  ibsql1.sql.clear;
  ibsql1.SQL.Add('insert into MyTable (MyIntWert) values (20);');
  ibsql1.ExecQuery;
  ibsql1.sql.clear;
  ibsql1.SQL.add('commit retain;');
  ibsql1.ExecQuery;

  i:=ibsql1.FieldByName('ID').AsInteger;    // Hier bekomme ich immer einen Fehler, daß das Feld nicht existiert
Muss ich hier in diser Procedure was ändern oder muss ich in meinem Trigger irgendwie einen Wert zurückgeben? Wenn Ja, wie? :gruebel:

ciao und schon mal vielen Dank für eure Mühe


PS : Vielleicht sollte ich noch sagen, ich benötige dafür keine Ausgabe auf dem Bildschirm. Ich möchte nur mit den Errechneten Feldern meines Triggers in meinem Delphi-Progi weiter rechnen.

Robert_G 23. Feb 2004 09:47

Re: IBSQL - INSERT Problem
 
Du hast doch garkeine Datenmenge, die ein Feld enthalten könnte!
Dein letztes SQL-Statement war "commit retain" das wird nun wirklich nix zurückliefern...

Quake 23. Feb 2004 10:08

Re: IBSQL - INSERT Problem
 
Auch wenn ich die Reihenfolge ändere funzt das nicht :gruebel:

Code:
var
  i: integer;
begin
  ibsql1.sql.clear;
  ibsql1.SQL.Add('insert into MyTable (MyIntWert) values (20);');
  ibsql1.ExecQuery;

  i:=ibsql1.FieldByName('ID').AsInteger;    // Hier bekomme ich immer einen Fehler, daß das Feld nicht existiert

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

Leuselator 23. Feb 2004 14:02

Re: IBSQL - INSERT Problem
 
Wie Robert_G faka GeorgeWNewbie schon sagte:

Du öffnest keine Datenmenge sondern sendest Nur einen Befehl an die DB. Wenn Du die gerade erzeugte Id haben möchtest müßtest Du noch:
Code:
var
  i: integer;
begin
  ibsql1.sql.clear;
  ibsql1.SQL.Add('insert into MyTable (MyIntWert) values (20);');
  ibsql1.ExecQuery;
  ibsql1.sql.clear;
  ibsql1.SQL.add('commit retain;');
  ibsql1.ExecQuery;

  [color=red]ibsql1.sql.clear;
  ibsql1.SQL.add('select max(ID) from MyTable where MyIntWert=20');
  ibsql.Open;[/color]
  i:=ibsql1.FieldByName('ID').AsInteger;
  ...
Gruß

Quake 23. Feb 2004 14:29

Re: IBSQL - INSERT Problem
 
Danke schon mal, :bounce2:

Eine Frage habe ich dazu aber noch. Währe es denkbar, daß in dem Fall wenn 2 PC gleichzeitig einen Datensatz einfügen, das der eine PC den Falschen Datensatz zurück bekommt?

Wenn ja könnte ich nur eine Stored Procedure schreiben die den Datensatz einfügt, die Berechnungen durchführt und mir diese Werte zurück gibt.

Oder gibt es noch eine Methode, bei der ich die Werte direkt bei dem insert zurück bekomme ohne nachfolgendes select, da der Wert MyIntWert sehr oft vorkommen kann?

ciao :dance: :dance: :dance: :dance: :dance: :dance:

PS: ich hatte nur noch das SELECT abgeänder
Code:
select * from MyTable where ID=(select max(ID) from MyTable)

Robert_G 23. Feb 2004 14:41

Re: IBSQL - INSERT Problem
 
Do könntest die Tabelle sperren oder hoffen, das es wie bei Oracle auch in IB eine RETURNING-Clause gibt:
Delphi-Quellcode:
Var
  NewID :Integer;
Begin
  With Query Do
  Begin
    SQL.Text :=
      'INSERT INTO Tabelle (Feld2) VALUES (:i_Value)' + #10 +
      ' RETURNING ID INTO :o_ID';
    Prepared := True;
    Parameters.ParamByName('i_Value').Value := 'Hallo';
    Parameters.ParamByName('o_ID').Direction := pdOutput;
    ExecSQL;
    NewID := Parameters.ParamByName('o_ID').Value;
  End;
End;

Quake 23. Feb 2004 14:48

Re: IBSQL - INSERT Problem
 
Ja, das ist genau das was ich suche, aber es funktionirt bei IB nicht (soweit ich weis).
Deinen Vorschlag hatte ich hier im Forum auch schon irgendwo gefunden.

Aber trotzdem Danke.

Wenn jemand noch eine Ide hat währe sehr schön.

Lemmy 24. Feb 2004 16:50

Re: IBSQL - INSERT Problem
 
Hi,

die meiner Meinung nach einzig sinnvolle Vorgehensweise in diesem Fall ist die Verwendung einer Stored Procedure die den Insert durchführt und die berechneten Daten zurückgibt.
Ein MAX(ID) wird bei einem Netzwerkbetrieb nicht sicher funktionieren.

Grüße
Lemmy

Marcel Gascoyne 24. Feb 2004 22:10

Re: IBSQL - INSERT Problem
 
Ich würd es auch mit einer Procedure probieren. Dein Programm sollte dann folgendes machen:

Delphi-Quellcode:
var
  i: integer;
begin
  ibsql1.SQL.Text := 'select id from myprocedure(:myintwert)';
  ibsqll.ParamByName('myintwert').AsInteger := 20;
  ibsql1.Open;

  if not ibsqll.Eof then
    i := ibsqll.FieldByName('ID').AsInteger
  else
    i := -1;

  ibsqll.Close;
Und hier die Procedure dazu:

SQL-Code:
create procedure myprocedure (
  myintwert integer
)
returns (
  id integer
)
as
begin
  insert into MyTable (MyIntWert)
  values (:myintwert);

  // hier Deine Berechnungen

  id = gen_id(generator_name,1); // oder wie auch immer du den wert bekommst...
  suspend;
end
Gruß,
Marcel

Quake 26. Feb 2004 06:57

Re: IBSQL - INSERT Problem
 
So in der Art werde ich das mache.

Danke euch allen. :bounce2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04: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-2025 by Thomas Breitkreuz