Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Rückgabeparameter bei FireBird (https://www.delphipraxis.net/151685-rueckgabeparameter-bei-firebird.html)

idefix2 27. Mai 2010 18:48


Rückgabeparameter bei FireBird
 
Zitat:

INSERT INTO TEST(BEZ) VALUES (:BEZ) returning ID;
Dazu habe ich eine Frage: Wo bekomme ich in meinem Delphi Programm diesen Ergebniswert ID zurück?

[edit=mkinzler] Dieser Beitrag wurde von http://www.delphipraxis.net/internal...t.php?t=120227 angespalten Mfg, mkinzler[/edit]

DeddyH 27. Mai 2010 18:56

Re: Performance: Interbase vs. Firebird
 
Indem Du statt ExecSQL Open benutzt.

mkinzler 27. Mai 2010 19:02

Re: Performance: Interbase vs. Firebird
 
Und dann im 2. Parameter ( Index 1)

idefix2 27. Mai 2010 19:44

Re: Performance: Interbase vs. Firebird
 
Nachdem ich mit der SQL Programmierung eben erst anfange, kann ich mit diesen Antworten nicht viel anfangen.
Mir ist nicht klar, was ich brauche, um einen einzelnen Wert als Query-Ergebnis zu übernehmen. Wenn im Hintergrund eine Tabelle liegt, liefert mir eine Query die entsprechenden Spalten, die dann z.B. in einem dbGrid landen. Aber in dem Fall habe ich ja keine Datenbanktabelle im Hintergrund und damit keine entsprechende Komponente.

mkinzler 27. Mai 2010 19:52

Re: Performance: Interbase vs. Firebird
 
So würde es mit IBDAC gehen
Delphi-Quellcode:
IBCQuery.SQL.Text := 'INSERT INTO TEST(BEZ) VALUES (:BEZ) returning ID;';
...
IBCQuery.ParamByName('bez').Value := 'Test';
IBCQuery.Open;
ID := IBCQuery.Params[1];

idefix2 27. Mai 2010 20:31

Re: Performance: Interbase vs. Firebird
 
Ah, danke.
Ich hoffe, es geht mit DBX genauso.

Landen eigentlich alle Ergebnis-Einzelwerte von Querys in Params, (z.B. select count(*) from x) oder gilt das nur für Werte, die mit returns zurückgegeben werden?
Und nur aus Neugierde: Was wird in Params[0] zurückgeliefert?

Und letzte Frage: Gibt es irgendwo eine Schnittstellendokumentation, in der man derartige Informationen halbwegs kompakt nachlesen kann - das ist ja nicht die einzige Frage, die sich einem SQL-Einsteiger in den Weg stellt, das meiste lässt sich mit recht mühsamen Herumsuchen irgendwo herausfinden, manches anscheinend nicht (zum Glück gibt es dann dieses Forum, aber lieber würde ich die Sachen irgendwo nachlesen, als euch hier wiederholt mit Trivialitäten zu quälen). Ich habe jetzt noch einmal nachgeschaut, in der Delphi Dokumentation von Tquery steht dazu nichts, und wenn doch, dann so gut versteckt, dass ich es jedenfalls nicht finde.

mkinzler 27. Mai 2010 20:40

Re: Performance: Interbase vs. Firebird
 
Zitat:

Landen eigentlich alle Ergebnis-Einzelwerte von Querys in Params, (z.B. select count(*) from x) oder gilt das nur für Werte, die mit returns zurückgegeben werden?
Nein, diese Werte sind ja Spalten in der Ergebnismenge.
Zitat:

Was wird in Params[0] zurückgeliefert?
Der Rückgabeparameter wird an die Inputparameter angehängt, Params[0] ist also der Paramter Bez

idefix2 28. Mai 2010 21:19

Re: Rückgabeparameter bei FireBird
 
Delphi-Quellcode:
       s:='insert into Interpret values (''0'',''Wert1'') returning id;';
       SQLQ := TSQLQuery.Create(SDIAppForm);
       SQLQ.SQLConnection := SQLC;
       SQLQ.Params.Clear;
//       SQLQ.Params.Add;
       SQLQ.SQL.Clear;
       SQLQ.SQL.add(s);
       SQLQ.open;
       messagedlg ('id: '+SQLQ.Params[0].asstring,mtInformation,[mbok],0);
Irgendwie funktioniert das nicht - Ich bekomme beim letzten Befehl eine Exception, weil SQLQ.Params leer ist. Auch der Versuch, vor dem Open des SQL Statement einen leeren Params[0] zu erzeugen (auskommentierte Zeile) hat an der Exception nichts geändert.

In ISQL wird bei der Eingabe dieses Befehls über den gespeicherten Trigger der Wert id='0' durch einen neuen eindeutigen Wert ersetzt.

Ja, und in der Datenbank ist nach der Ausführung dieses Codes in der Tabelle Interpret auch noch keine neue Zeile angekommen, obwohl bei der Ausführung des Open Befehls keine Fehler gemeldet wurde.

mkinzler 28. Mai 2010 21:21

Re: Rückgabeparameter bei FireBird
 
Vielleicht hilft dir dieser Beitrag:
http://www.andreanolanusse.com/bloge...dbx-framework/

idefix2 28. Mai 2010 22:21

Re: Rückgabeparameter bei FireBird
 
Leider nein, hat mit meinem Problem nichts zu tun.

Ich bekomme einfach das Ergebnis des SQL Statements, das mit der returning Klausel an das Programm zurückgegeben werden sollte, nicht zu fassen. Bei der Rückkehr von der Query ist Query.params ganz leer.

Aber es muss irgend etwas grundlegend falsch sein, weil in der Tabelle auch kein Datensatz abgelegt wird. Die Übergabe des Befehlsstrings an SQL funktioniert aber offenbar, weil wenn ich den String irgendwie auf ein ungültiges SQL-Statement ändere (ungültiger Tabellenname oder fehlender Strichpunkt am Ende), löst der Aufruf von Open eine Exception aus. Nur wenn S einen syntaktisch richtigen SQL Befehl enthält, kehrt OPEN ohne Fehlermeldung zurück, ausgeführt wird das Insert aber trotzdem nicht - nicht einmal, wenn ich die returning Klausel weglasse.

Edit: Dass keine Daten in der Tabelle ankommen, stimmt nicht. Es scheint nötig zu sein, im ISQL nach einem Select ein commit einzugeben, bevor man mit einem neuerlichen Select die neuen Daten zu Gesicht bekommt. Offenbar wird mit einem select implizit eine Transaktion gestartet, die dann die Sicht auf die Daten konsistent hält. Fazit: Das Insert wird ausgeführt, aber ich komme einfach nicht zum Rückgabewert.

DeddyH 29. Mai 2010 09:03

Re: Rückgabeparameter bei FireBird
 
Ich habe gerade unter Linux mit Lazarus folgendes ausprobiert:
SQL-Code:
INSERT INTO Person(Name,Vorname) VALUES(:name,:vorname) RETURNING ID
Delphi-Quellcode:
  SQLQuery.Params.ParamByName('Name').Value := 'Mustermann';
  SQLQuery.Params.ParamByName('Vorname').Value := 'Max';
  SQLQuery.Open;
  ShowMessage(SQLQuery.FieldByName('ID').AsString);
Siehe da, mir wurde die ID ausgegeben. Unter Delphi dürfte das (je nach Zugriffskomponenten) ähnlich aussehen.

mkinzler 29. Mai 2010 09:09

Re: Rückgabeparameter bei FireBird
 
Die Rückgabe scheint sehr von den verwendeten Komponenten abzuhängen

DeddyH 29. Mai 2010 09:13

Re: Rückgabeparameter bei FireBird
 
Trotzdem würde ich es einmal mit Fields statt Params versuchen, wenn Letzteres nicht funktioniert.

idefix2 30. Mai 2010 12:37

Re: Rückgabeparameter bei FireBird
 
Delphi-Quellcode:
SQLQ := TSQLQuery.Create(SDIAppForm);
SQLQ.SQLConnection := SQLC;
SQLQ.SQL.Clear;
SQLQ.SQL.add('insert into Interpret (id,name) values (:id,:name);'); // returning id;');
SQLQ.PrepareStatement;
SQLQ.Params.Parambyname('id').value := 0;
SQLQ.Params.Parambyname('name').value := 'Testwert';
SQLQ.ExecSQL;
Ich habe jetzt versucht, die Werte als Parameter zu übergeben (in der Hoffnung, dann vielleicht in id eine Antwort zurückzubekommen - obwohl auch das unbefriedigend wäre, weil der mit returning zurückgegebene Wert eines SQL Statements muss ja nicht in allen Fällen einem übergebenem Feldelement entsprechen, sondern kann ja irgend ein errechneter Wert sein). Jetzt erzeugt schon der SQL Aufruf eine Exception, mit der für mich unverständlichen Fehlermeldung: "Die Feldnamen für %s konnten nicht erkannt werden".

omata 30. Mai 2010 15:20

Re: Rückgabeparameter bei FireBird
 
Hast Du auch mal das aus #11 probiert?

idefix2 30. Mai 2010 16:43

Re: Rückgabeparameter bei FireBird
 
Ich komme ja jetzt nicht einmal mehr dazu, das returning irgendwie auszuprobieren, weil das ExecSQL - mit und ohne returning - eine Exception auslöst, sobald ich Parameter verwende.
Wenn ich im SQL Statement keine Parameter verwende, sondern direkt die Werte angegebe, kennt er ein FieldByName ('id') nicht.

haentschman 30. Mai 2010 16:48

Re: Rückgabeparameter bei FireBird
 
Hallo...
Zitat:

Hast Du auch mal das aus #11 probiert?
...ich wiederhole das mal.

Denn anscheinend nicht. Es wurde schon mehrfach gesgt, daß du wenn du einen Rückgabewert erwartest OPEN statt EXECSQL benutzen mußt.

:hi:

idefix2 30. Mai 2010 22:20

Re: Rückgabeparameter bei FireBird
 
Ich habe sowohl open als auch execsql probiert. Das Verhalten ist in beiden Fällen exakt gleich:

SQL-Code:
SQLQ.SQL.add('insert into Interpret (id,name) values (''0'',''Testwert'') returning id;');
liefert beim Aufruf von Open oder ExecSQL keine Fehlermeldung, aber es gibt keinen Parameter id, dh der Zugriff auf SQLQ.Params.Parambyname('id') produziert eine Exception (was zu erwarten war, weil den Parameter id gibt es ja wirklich nicht).


SQL-Code:
SQLQ.SQL.add('insert into Interpret (id,name) values (:id,:name) returning id;');
erlaubt mir zwar, die Werte für
SQLQ.Params.Parambyname('id').value := 0;
SQLQ.Params.Parambyname('name').value := 'testwert';
zu setzen, dafür produziert der Aufruf von Open ebenso wie der Aufruf von ExecSQL eine Exception, nämlich
Die Feldnamen für %s konnten nicht erkannt werden
Dabei ist es egal, ob ich versuche, mit der Klausel "returning id" einen Rückgabewert zu bekommen oder ob ich diese Klausel weglasse. In dem Fall komme ich also gar nicht dazu, den Rückgabewert von
SQLQ.Params.Parambyname('id') anzuschauen.

omata 30. Mai 2010 23:23

Re: Rückgabeparameter bei FireBird
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal ein Beispiel, das wunderbar funktioniert.

Ist dir klar, was du alles in der Datenbank anlegen must, damit das überhaupt funktioniert? Das hat nämlich nichts mit Delphi zu tun. Falls nicht, siehe hier.

idefix2 31. Mai 2010 12:34

Re: Rückgabeparameter bei FireBird
 
Hallo omata,

Du verwendest in diesem Beispiel die Interbase DBX Komponenten. Das hatte ich als erstes versucht, leider absolut erfolglos.

In diesem Link ist beschrieben, dass mir mit den Komponenten nicht einmal ein Connect zur Firebird Datenbank gelungen ist. Das gleiche passiert mir bei Deinem Beispiel. Nach der Anpassung von Benutzername, Password und Datenbankpfad kommt auch hier die Fehlermeldung: connection rejected by remote interface, als wäre Benutzername oder Password falsch. Mit Isql und mit dbworkbench funktioniert der Zugriff. Ich verwende Delphi 2009 und Firebird 2.1. Im oben angeführten Thread haben verschiedene Poster gemeint, es liege daran, dass man mit den DBX Interbase Komponenten prinzipiell nicht auf Firebird zugreifen könne. Anscheinend geht es bei Dir doch, und es würde mich interessieren, in welcher Konstellation das geht.

Zitat:

Ist dir klar, was du alles in der Datenbank anlegen must, damit das überhaupt funktioniert
Im Posting #10 habe ich geschrieben: Das Insert wird ausgeführt, aber ich komme einfach nicht zum Rückgabewert.
Natürlich habe ich auch überprüft, ob in der Spalte id die richtigen trigger-generierten Werte ankommen, das ist alles in Ordnung. Nur der Rückgabewert in delphi ist das Problem.

Ich werde jetzt noch versuchen, Dein Beispiel mit möglichst wenig Änderungen auf die Firebird - DBX-Komponenten umzustellen - mit etwas Glück könnte es genügen, nur die Properties von SQLConnection geeignet anzupassen.

DeddyH 31. Mai 2010 12:37

Re: Rückgabeparameter bei FireBird
 
Was ist eigentlich mit meinem Beispiel aus #11? Hast Du denn einmal versucht, das Statement mittels Open auszuführen und Dir den Wert mit FieldByName (nicht ParamByName) zu holen?

idefix2 31. Mai 2010 13:16

Re: Rückgabeparameter bei FireBird
 
Ich habe das auch schon versucht, irgend etwas hat dabei aber auch nicht geklappt. Ich wollte es gerade noch einmal versuchen, aber jetzt funktioniert gar kein SQL Statement mehr, weder mit noch ohne Parameter, weder mit noch ohne RETURNING: Ich bekomme jetzt immer die Exception:
Die Feldnamen für %s konnten nicht erkannt werden
Mir ist aber nicht klar, was an meinem Code gegenüber vorher grundlegend verändert ist, vorher hat der Open Aufruf zumindest dann noch geklappt, wenn ich keine Parameter übergeben habe. Der aktuelle Code lautet, auf das einfachste heruntergebrochen:

Delphi-Quellcode:
SQLQ.SQLConnection := SQLC;
SQLQ.SQL.Clear;
SQLQ.Params.Clear;
SQLQ.SQL.add('INSERT into Interpret (NAME) values (''Testwert'') ;');// returning id;');
SQLQ.Open;
und an dieser Stelle bekomme ich, egal ob mit oder ohne die Klausel "returning id", die oben angeführte Exception, d.h. ich kann jetzt überhaupt kein SQL Statement mehr erfolgreich absetzen. Wenn ich über ISQL genau das gleiche Statement (mit cut and paste hinüber kopiert, verdoppelte Hochkomma weggelöscht) eingebe, wird ganz normal eine neue Tabellenzeile angelegt.

DeddyH 31. Mai 2010 13:55

Re: Rückgabeparameter bei FireBird
 
Das könnte aber an DBExpress liegen. Ich hatte den Treiber auch schon einmal ausprobiert und bin dann für mich zu der Erkenntnis gekommen, dass ich lieber noch ein paar Versionen abwarte :mrgreen:. Ein paar Alternativen zum Zugriff (sowohl kostenlose als auch kostenpflichtige) bekommst Du z.B. hier gelistet: http://www.firebirdfaq.org/faq8/

idefix2 31. Mai 2010 15:30

Re: Rückgabeparameter bei FireBird
 
Ja, danke, leider kenne ich die Seite schon, und es ist nicht sehr aufbauend. Was ich suche, ist eine sehr schlanke Schnittstelle, weil ich mir darum herum meine eigene Zwischenschicht programmieren will. Und dafür möchte ich jetzt auch noch kein Geld ausgeben, d.h. ich suche nach irgend einer freeware Variante. Was es da gibt, ist aber grösstenteils überhaupt nicht mit Delphi 2009 kompatibel, teilweise sind die Links auch tot. Das einzige, was ich gefunden habe, was im Prinzip gepasst hätte, und mir auch absolut ausreichen würden, sind eben diese Firebird DBX Komponenten, und die funktionieren offenbar auch nicht richtig.

mkinzler 31. Mai 2010 15:57

Re: Rückgabeparameter bei FireBird
 
Welchen DBX-Treiber verwendest du den? ( nicht den von D2010?)

idefix2 31. Mai 2010 16:14

Re: Rückgabeparameter bei FireBird
 
Ich habe im Internet auf einen Tip von Lemmy in einem anderen Thread hin die DLL dbxfb4d12.dll heruntergeladen.

http://sites.google.com/site/dbxfirebird/download

D12 entspricht glaube ich dem Delphi 2009.

mkinzler 31. Mai 2010 16:17

Re: Rückgabeparameter bei FireBird
 
Ab D2010 unterstützt DBX FireBird nativ, wobei dieser Treiber bei der Pro ( wie alle Treiber) gewisse Beschränkungen ( Z.B. nur lokal, 5 Benutzer) unterliegt.

DeddyH 31. Mai 2010 16:29

Re: Rückgabeparameter bei FireBird
 
Soll er dafür jetzt das Update kaufen? Da kämen Fremdkomponenten aber meist billiger und wären zielführender.

idefix2 31. Mai 2010 16:58

Re: Rückgabeparameter bei FireBird
 
@ Omata (Thread 19)
Habe Dein Demoprogramm jetzt mit den Firebird DBX Komponenten statt Interbase ausprobiert. Irgendwo ganz tief drinnen lösen die DBX Komponenten schon beim ClientDataSet.Open eine exception aus, weitergeben wird nur lakonisch: Schwerwiegender Fehler.

haentschman 31. Mai 2010 18:40

Re: Rückgabeparameter bei FireBird
 
Hallo...

weil wir jetzt schon mit Komponenten um uns werfen, schmeiß ich mal Zeos(Version 7 Alpha) und UIB in den Raum. Damit sollte das returning definitiv funktionieren.

:hi:

DeddyH 31. Mai 2010 18:42

Re: Rückgabeparameter bei FireBird
 
Die beiden wurden im anderen Thread auch schon genannt.

idefix2 31. Mai 2010 19:55

Re: Rückgabeparameter bei FireBird
 
Bei den Schwierigkeiten, die ganz normale Produktionsversionen von manchen Komponenten machen, bin ich sehr skeptisch, ob ich mich wirklich auf eine "alpha"-Version von irgendwas einlassen soll. Hat irgendwer mit ZEOS 7 schon knkrete Erfahrungen gesammelt?

UIB werde ich jedenfalls als nächstes ausprobieren, auf zwei Seiten, auf denen Schnittstellenkomponenten gelistet waren, war der Link zu UIB tot, aber über Google kommt man zu einer Seite, wo es die Komponenten wirklich gibt.

omata 1. Jun 2010 23:59

Re: Rückgabeparameter bei FireBird
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier nochmal ein neuer Versuch...

idefix2 2. Jun 2010 10:20

Re: Rückgabeparameter bei FireBird
 
Hallo, Omata, danke! mit dieser DLL funktioniert es! Ich kann mich mit der Datenbank verbinden und bekomme in id den Trigger-Wert zurück.

Noch eine Frage: Was ist das für eine DLL?


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:14 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