INSERT mit Firebird Datenbank

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

INSERT mit Firebird Datenbank

Beitrag von knight »

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

Benutzeravatar
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

Beitrag von af0815 »

knight hat geschrieben: Kann jemand einen Fehler erkennen bzw. was könnte man noch unternehmen, um den Fehler zu finden?
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 ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

Re: INSERT mit Firebird Datenbank

Beitrag von knight »

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

Benutzeravatar
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

Beitrag von af0815 »

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.
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.

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).

KOBOLD Messring GmbH
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

Beitrag von KOBOLD Messring GmbH »

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.

Code: Alles auswählen

SQLQuery1.SQL.Clear;
SQLQuery1.SQL.Add ('INSERT INTO meinetabelle VALUES (''' + sStringWert + ''', ' + IntToStr (nZahlenWert) + ')');
SQLQuery1.ExecSQL;
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.

Benutzeravatar
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

Beitrag von af0815 »

KOBOLD Messring GmbH hat geschrieben:Das erscheint einigen Leuten zwar soooo umständlich und unelegant,...
Parameter selbst erzeugen ist ja soooo umständlich :-)

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).

mse
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

Beitrag von mse »

knight hat geschrieben:Ich vermute den Fehler irgendwo im SQL Teil oder beim Zusammenspiel der SQLdb Komponenten mit SQL.
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.

Benutzeravatar
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

Beitrag von af0815 »

mse hat geschrieben:[Hast du TSQLQuery.Prepare aufgerufen vor dem Ansprechen der Parameter?
Wird nichts bringen, ich habe mir den Parser selbst herausgesucht, der kann derzeit nur mit dem SELECT wirklich umgehen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mse
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

Beitrag von mse »

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...)
IsertSQL, UpdateSQL und DeleteSQL werden von TSQLQuery.ApplyUpdates aufgerufen. Vermutlich würde es sich lohnen, die Funktionsweise von SQLDB etwas genauer anzuschauen. :-)
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.

mse
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

Beitrag von mse »

af0815 hat geschrieben: Wird nichts bringen, ich habe mir den Parser selbst herausgesucht, der kann derzeit nur mit dem SELECT wirklich umgehen.
Bei mir funktioniert die Parameter-Extrahierung, (MSEgui) mit Lazarus sollte es ebenfalls funktionieren.

khh
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

Beitrag von khh »

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

knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

Re: INSERT mit Firebird Datenbank

Beitrag von knight »

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.
Das Prepare hat den Durchbruch gebracht. Allerdings konnte ich den Vorgang nicht mit ApplyUpdates abschließen sondern mit ExecSQL. Vielen Dank an alle.

knight

Benutzeravatar
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

Beitrag von af0815 »

knight hat geschrieben:Das Prepare hat den Durchbruch gebracht.
Welche Laz/FPC Version ? Vielleicht sollte ich mal updaten :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

Re: INSERT mit Firebird Datenbank

Beitrag von knight »

af0815 hat geschrieben:Welche Laz/FPC Version ? Vielleicht sollte ich mal updaten :-)
Lazarus 0.9.26 mit FPC 2.2.2

knight

mse
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

Beitrag von mse »

knight hat geschrieben:Allerdings konnte ich den Vorgang nicht mit ApplyUpdates abschließen sondern mit ExecSQL.
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.

Antworten