INSERT mit Firebird Datenbank
INSERT mit Firebird Datenbank
Hallo,
ich habe ein Problem mit dem Einfügen eines Datensatzes in eine Firebird Datenbank. Ich vermute den Fehler irgendwo im SQL Teil oder beim Zusammenspiel der SQLdb Komponenten mit SQL. Ein Auszug aus dem Quelltext:
SQLQuery1.InsertSQL.Clear;
SQLQuery1.InsertSQL.Text:= 'insert into TAB04 (KONTO_NR, ... ) values (:KONTO_NR, ... )'; {es befinden sich noch weitere Felder in dem INSERT Kommando}
SQLQuery1.Params.ParamByName('KONTO_NR').AsString := Edit1.Text;
Wenn der Datensatz eingefügt werden soll erscheint ein EDataBaseError, daß der Parameter KONTO_NR unbekannt sei. Mit einer SELECT Abfrage funktioniert die Konstruktion, so daß es nicht an der Programmlogik liegen sollte. Ich habe schon alle mir sinnvoll erscheinenden Veränderungen vorgenommen, jedoch ohne Erfolg. Kann jemand einen Fehler erkennen bzw. was könnte man noch unternehmen, um den Fehler zu finden?
knight
ich habe ein Problem mit dem Einfügen eines Datensatzes in eine Firebird Datenbank. Ich vermute den Fehler irgendwo im SQL Teil oder beim Zusammenspiel der SQLdb Komponenten mit SQL. Ein Auszug aus dem Quelltext:
SQLQuery1.InsertSQL.Clear;
SQLQuery1.InsertSQL.Text:= 'insert into TAB04 (KONTO_NR, ... ) values (:KONTO_NR, ... )'; {es befinden sich noch weitere Felder in dem INSERT Kommando}
SQLQuery1.Params.ParamByName('KONTO_NR').AsString := Edit1.Text;
Wenn der Datensatz eingefügt werden soll erscheint ein EDataBaseError, daß der Parameter KONTO_NR unbekannt sei. Mit einer SELECT Abfrage funktioniert die Konstruktion, so daß es nicht an der Programmlogik liegen sollte. Ich habe schon alle mir sinnvoll erscheinenden Veränderungen vorgenommen, jedoch ohne Erfolg. Kann jemand einen Fehler erkennen bzw. was könnte man noch unternehmen, um den Fehler zu finden?
knight
- af0815
- Lazarusforum e. V.
- Beiträge: 6877
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Das einzige was mir dazu momentan einfällt ist, der SQL text muß ja zwischenzeitlich geparst (TQuery.ParseSQL) werden um die Parameter zu erstellen. Kann das sein, das das nicht passiert ist, bzw. abgeschalten ist ?knight hat geschrieben: Kann jemand einen Fehler erkennen bzw. was könnte man noch unternehmen, um den Fehler zu finden?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: INSERT mit Firebird Datenbank
Ich habe jetzt ParseSQL auf true gestellt. Am Ergebnis hat es nichts geändert. Wenn ich ein SELECT (auf die selbe Tabelle) mit Parametern loslasse, dann funktioniert es ja. Der Vollständigkeit halber die komplette Fehlermeldung:
Project raised exception class 'EDatabaseError' with message: SQLQuery1: Parameter "KONTO_NR" not found
Ich habe es auch schon mit verschiedenen Lazarus- und Firebird-Versionen probiert. Das Ergebnis war immer das selbe. Ist es möglich, daß ein Trennzeichen falsch ist oder gar fehlt?
knight
Project raised exception class 'EDatabaseError' with message: SQLQuery1: Parameter "KONTO_NR" not found
Ich habe es auch schon mit verschiedenen Lazarus- und Firebird-Versionen probiert. Das Ergebnis war immer das selbe. Ist es möglich, daß ein Trennzeichen falsch ist oder gar fehlt?
knight
- af0815
- Lazarusforum e. V.
- Beiträge: 6877
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Du kannst natürlich auch die Parameterliste 'zu Fuß' erstellen und den Parser Parser sein lassen. Ich bevorzuge diese Methode, da das Ergebnis in meinen Händen liegt und nicht von einer Automatik abhängt.knight hat geschrieben:Ich habe jetzt ParseSQL auf true gestellt. Am Ergebnis hat es nichts geändert. Wenn ich ein SELECT (auf die selbe Tabelle) mit Parametern loslasse, dann funktioniert es ja.
Wenn man in die SQLDB so um die Zeile 1030 (TCustomSQLQuery.SQLParser...) hineinsieht, so kann der Parser nur mit select umgehen und dieses zerlegen. Da habe ich keien Hinweis gefunden das das mit insert auch geht.
Somit heisst das, alles was nicht auf select basiert, muß du selbst behandeln (und bei select auch die komplexeren abfragen).
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 155
- Registriert: Mi 22. Aug 2007, 14:52
- OS, Lazarus, FPC: Mandriva Linux 2008 (L 0.9.28 FPC 2.2.4)
- CPU-Target: 32Bit
- Wohnort: 65719 Hofheim am Taunus
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Ich habe auch mit den Parametern seltsame Ergebnisse erhalten, mal scheint es zu funktionieren, mal nicht (habe aber noch keine Systematik erkannt).
Deshalb lasse ich die Finger von den Parametern und stelle den SQL-String (übrigens IMMER in der Eigenschaft SQL, NIEMALS in der InsertSQL - noch so `ne Merkwürdigkeit...) komplett zusammen, z.B.
Das erscheint einigen Leuten zwar soooo umständlich und unelegant, ¡ aber funktioniert ! Habe das mit MySQL (Lazarus-DB TMySQL50Connection und auch Zeos 6.5), MS-Access (Lazarus-DB, TODBCConnection) und sogar für AS/400-DB/400 (Lazarus, TODBConnection) gemacht und funktioniert unter WinXP und Linux.
Deshalb lasse ich die Finger von den Parametern und stelle den SQL-String (übrigens IMMER in der Eigenschaft SQL, NIEMALS in der InsertSQL - noch so `ne Merkwürdigkeit...) komplett zusammen, z.B.
Code: Alles auswählen
SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Add ('INSERT INTO meinetabelle VALUES (''' + sStringWert + ''', ' + IntToStr (nZahlenWert) + ')');
SQLQuery1.ExecSQL;
- af0815
- Lazarusforum e. V.
- Beiträge: 6877
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Parameter selbst erzeugen ist ja soooo umständlichKOBOLD Messring GmbH hat geschrieben:Das erscheint einigen Leuten zwar soooo umständlich und unelegant,...

Der Vorteil von Parametern ist der, das das Statement selbst auf den Server vorbereitet werden kann ('prepare') und bei wiederholten abfragen nicht immer alles neu kompiliert werden muß, sondern nur der Parameter geändert wird. Ist bei 'kleinen' Projekten und Desktopdatenbanken meist unerheblich. Kann aber zur Performancesteigerung auf Servern beitragen, vor allen durch den Entfall der Kompilierung. Das Kompilat bleibt im Server-Cache gespeichert und ist somit wesentlich schneller und performanter.
Es hängt aber auch davon ab wie die Query intern arbeitet. Ich habe es bei Lazarus selbst nicht im Detail untersucht. Auf anderen Plattformen war es deutlich Nachweisbar.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: INSERT mit Firebird Datenbank
Hast du TSQLQuery.Prepare aufgerufen vor dem Ansprechen der Parameter? Alternativ kannst du die notwendigen Parameter auch selbst erstellen, entweder im code oder im objectinspector, falls Lazarus diese Möglichkeit bietet.knight hat geschrieben:Ich vermute den Fehler irgendwo im SQL Teil oder beim Zusammenspiel der SQLdb Komponenten mit SQL.
- af0815
- Lazarusforum e. V.
- Beiträge: 6877
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Wird nichts bringen, ich habe mir den Parser selbst herausgesucht, der kann derzeit nur mit dem SELECT wirklich umgehen.mse hat geschrieben:[Hast du TSQLQuery.Prepare aufgerufen vor dem Ansprechen der Parameter?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: INSERT mit Firebird Datenbank
IsertSQL, UpdateSQL und DeleteSQL werden von TSQLQuery.ApplyUpdates aufgerufen. Vermutlich würde es sich lohnen, die Funktionsweise von SQLDB etwas genauer anzuschauen.KOBOLD Messring GmbH hat geschrieben: Deshalb lasse ich die Finger von den Parametern und stelle den SQL-String (übrigens IMMER in der Eigenschaft SQL, NIEMALS in der InsertSQL - noch so `ne Merkwürdigkeit...)

Edit: Einige Stichworte sind hier:
http://www.lazarusforum.de/viewtopic.php?p=27855#p27855
Zuletzt geändert von mse am Di 17. Feb 2009, 09:53, insgesamt 1-mal geändert.
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: INSERT mit Firebird Datenbank
Bei mir funktioniert die Parameter-Extrahierung, (MSEgui) mit Lazarus sollte es ebenfalls funktionieren.af0815 hat geschrieben: Wird nichts bringen, ich habe mir den Parser selbst herausgesucht, der kann derzeit nur mit dem SELECT wirklich umgehen.
-
- Beiträge: 489
- Registriert: Sa 5. Apr 2008, 09:37
- OS, Lazarus, FPC: Win Vista,Win 7 (L 0.9.29 FPC 2.4.1)
- CPU-Target: 32Bit /64 Bit
- Wohnort: Nähe Freiburg i.Br.
Re: INSERT mit Firebird Datenbank
folgendes Konstruct funktioniert mit ZEOS und firebird einwandfrei:
FQuery1.SQL.add('select ');
FQuery1.SQL.add('*');
FQuery1.SQL.add('from artikel where ');
FQuery1.SQL.add('ARTIKEL_ID = :ARTIKEL_ID');
FQuery1.ParamByName('ARTIKEL_ID').AsInteger := FARTIKEL_ID;
FQuery1.open; // liefert eine leere datenmenge
FQuery1.append; // neuen Datensatz anhängen
{wird vom DB-Trigger erledigt }
// FQuery1['ARTIKEL_ID']:= FARTIKEL_ID;
FQuery1['ARTIKELNUMMER']:= FARTIKELNUMMER;
FQuery1['BEZEICHNUNG1']:= FBEZEICHNUNG1;
FQuery1['BEZEICHNUNG2']:= FBEZEICHNUNG2;
// weitere felder
FQuery1.post;
damit wird quasi ein insert ausgeführt.
Gruss KH
FQuery1.SQL.add('select ');
FQuery1.SQL.add('*');
FQuery1.SQL.add('from artikel where ');
FQuery1.SQL.add('ARTIKEL_ID = :ARTIKEL_ID');
FQuery1.ParamByName('ARTIKEL_ID').AsInteger := FARTIKEL_ID;
FQuery1.open; // liefert eine leere datenmenge
FQuery1.append; // neuen Datensatz anhängen
{wird vom DB-Trigger erledigt }
// FQuery1['ARTIKEL_ID']:= FARTIKEL_ID;
FQuery1['ARTIKELNUMMER']:= FARTIKELNUMMER;
FQuery1['BEZEICHNUNG1']:= FBEZEICHNUNG1;
FQuery1['BEZEICHNUNG2']:= FBEZEICHNUNG2;
// weitere felder
FQuery1.post;
damit wird quasi ein insert ausgeführt.
Gruss KH
Re: INSERT mit Firebird Datenbank
Das Prepare hat den Durchbruch gebracht. Allerdings konnte ich den Vorgang nicht mit ApplyUpdates abschließen sondern mit ExecSQL. Vielen Dank an alle.mse hat geschrieben: Hast du TSQLQuery.Prepare aufgerufen vor dem Ansprechen der Parameter? Alternativ kannst du die notwendigen Parameter auch selbst erstellen, entweder im code oder im objectinspector, falls Lazarus diese Möglichkeit bietet.
knight
- af0815
- Lazarusforum e. V.
- Beiträge: 6877
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: INSERT mit Firebird Datenbank
Welche Laz/FPC Version ? Vielleicht sollte ich mal updatenknight hat geschrieben:Das Prepare hat den Durchbruch gebracht.

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: INSERT mit Firebird Datenbank
Lazarus 0.9.26 mit FPC 2.2.2af0815 hat geschrieben:Welche Laz/FPC Version ? Vielleicht sollte ich mal updaten
knight
-
- Beiträge: 2013
- Registriert: Do 16. Okt 2008, 10:22
- OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
- CPU-Target: x86,x64,ARM
Re: INSERT mit Firebird Datenbank
Korrekt, ApplyUpdates uberträgt mittells Post und Delete vorgenommene Änderungen an die Datenbank, ExecSQL führt das TSQLQuery.SQL statement aus. Ein leichter Missbrauch der TSQLQuery Komponente IMHO, darum gibts tsqlstatement und tsqlscript für SQL Befehle, welche keine Datenmenge zurückgeben.knight hat geschrieben:Allerdings konnte ich den Vorgang nicht mit ApplyUpdates abschließen sondern mit ExecSQL.