![]() |
Datenbank: Firebird • Version: 2.1 • Zugriff über: IBDAC neueste Version
Bekomme kein INSERT mit FB und IBDAC hin!?!
Hallo,
ich werd' noch verrückt. Folgende Anweisung wird mit einem Fehler abgewiesen (Token unknown). Hab auch schon TIBCSQL durch TIBCQuery ersetzt, gleiches Problem... Exakt die gleiche Abfrage funktioniert unter einer Firebird-GUI einwandfrei. Die Schleife (to 31) sowie das entsprechende Datum habe ich zu Demonstrationszwecken in einen festen Wert geändert.
Delphi-Quellcode:
Meine Tabelle sieht so aus:
procedure TPlanner.PCreateMonthInDB(Month: Byte; Year: Integer);
VAR TMPSQL : TIBCSQL; i : Integer; begin (* Kalender in Datenbank erstellen *) TMPSQL := TIBCSQL.Create(nil); for I := 1 to 31 do begin TMPSQL.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(0,''13.07.2010'');'); end; TMPSQL.AutoCommit := True; TMPSQL.Execute; (* Abfrage freigeben *) TMPSQL.Free; end;
SQL-Code:
Ich greife über Firebird embedded darauf zu, Verbindung und auch Abfragen funktionieren tadellos :(
CREATE TABLE TBLCALENDAR (
ID INTEGER NOT NULL, DATUM DATE NOT NULL, ANWESEND SMALLINT, BEREITSCHAFT SMALLINT, NOTARZT SMALLINT, ISHOLIDAY SMALLINT DEFAULT 0 NOT NULL); ALTER TABLE TBLCALENDAR ADD PRIMARY KEY (ID); SET TERM ^ ; CREATE TRIGGER BI_TBLCALENDAR_ID FOR TBLCALENDAR ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(TBLCALENDAR_ID_GEN, 1); END^ SET TERM ; ^ Danke für Eure Hilfe! SCRaT |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Ich würde es mit einer parametrisierten Abfrage veruchen.
|
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Probiere es mal so :
Delphi-Quellcode:
procedure TPlanner.PCreateMonthInDB(Month: Byte; Year: Integer);
VAR TMPSQL : TIBCSQL; i : Integer; begin (* Kalender in Datenbank erstellen *) TMPSQL := TIBCSQL.Create(nil); for I := 1 to 31 do begin TMPSQL.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(:Holiday, :Holidaydatum);'); TMPSQL.ParamByName('Holiday').AsInteger := 0; TMPSQL.ParamByName('Holidaydatum').AsDateTime := StrToDateTime('13.07.2010'); end; TMPSQL.AutoCommit := True; TMPSQL.Execute; (* Abfrage freigeben *) TMPSQL.Free; end; |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Delphi-Quellcode:
Leider dasselbe Problem...
[...]
for I := 1 to 31 do begin TMPSQL.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(:Test1,:Test2);'); end; TMPSQL.ParamByName('Test1').AsInteger := 0; TMPSQL.ParamByName('Test2').AsDate := Now; [...] |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Noch besser:
Delphi-Quellcode:
TMPSQL.SQL.Text := 'INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(:Holiday, :Holidaydatum);';
TMPSQL.AutoCommit := True; for I := 1 to 31 do begin TMPSQL.ParamByName('Holiday').AsInteger := 0; TMPSQL.ParamByName('Holidaydatum').AsDateTime := StrToDateTime('13.07.2010'); TMPSQL.Execute; end; |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Vielen Dank für Eure Hilfe, es hat geklappt!! :cheers:
Aber warum MUSS(?) man parametisierte Abfragen benutzen? WARUM funktioniert mein 1. Vorschlag nicht, rein formal ist er doch ok, oder? |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Um ein Skript auszuführen musst du temporär das Termsymbol (SET TERM) ändern, so dass das Ende eines Befehls und das Ende des Skriptes unterschieden werden kann
|
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Werd ich mir mal anschauen...
Gab noch eine kurze Schrecksekunde, die Tabelle war trotz erfolgrechem Insert leer, ein XXXConnection.Commit; hat aber geholfen. Warum muss ich denn das nochmals committen, wenn ich AutoCommit auf True stehen habe? (Ja, bei der Connection steht es auf False...) |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zu deiner Tabellenstruktur:
Du solltest das Feld ID ganz weglassen und stattdessen das Feld DATUM zum Primärschlüssel machen. Dann sparst du dir den Trigger, gewinnst mehr Leistung und ausserdem darf es ja pro Datum nur einen Datensatz geben. |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zitat:
|
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zitat:
|
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Hallo,
zu deiner Ausgangsfrage, warum es nicht klappt.
Delphi-Quellcode:
31 mal wird insert into als Befehl eingetragen
TMPSQL := TIBCSQL.Create(nil);
for I := 1 to 31 do begin TMPSQL.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(0,''13.07.2010'');'); end;
Delphi-Quellcode:
Jetzt wird der Code einmal zum Server geschickt.TMPSQL.AutoCommit := True; TMPSQL.Execute; Der sieht jetzt also folgendes INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(0,''13.07.2010'');INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(0,''13.07.2010''); INSERT INTO TBLCALENDAR(ISHOLIDAY,DATUM) VALUES(0,''13.07.2010'') Und das waren nur 3 der 31. Firebird kann im Untershcied zu MS-SQL immer nur einen Befehl ausführen (es sei denn, man benutzt irgendeine Script-Komponente). Durch das Umbauen auf die Parameter ist das TMPSQL.Execute; mit in die For-Schleife gerutscht. Somit wird der Befehl auch korrekt 31 mal ausgeführt. Das war ja auch der ursprüngliche Plan ... ;) Zum Ändern der Tabellen-Struktur: Warum soll das bei Firebird mehr Leistung bringen, vom Trigger abgesehen ? Index ist Index (bei Firebird zumindestens) Ich würde das so lassen, falls später mal Replikation ein Thema ist, ist der künstliche Schlüsel ID ideal. Heiko |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zitat:
Ein Beispiel :
Delphi-Quellcode:
Wenn Du jetzt noch mehrere solcher Felder hast, tust Du Dich schwer den kompletten SQL richtig vernüpftig zu lesen. Jetzt gibt es zwei Varianten, wie man das ganze etwas überischtlicher gestalten kann.
Query.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY, Reiseziel, Startflughafen) VALUES(0,''''Hawaii'''', ''''Frankfurt'''');');
1. Möglichkeit: Hier muss ich aber wieder auf die Formatierung in der SQL-Anweisung achten. Ich ersetze die vier Hochkommas durch QuotedStr. Das ganze sieht dann so aus :
Delphi-Quellcode:
Das ganze ist zwar schon besser zu lesen und übersichtlicher, aber den kompletten Insert-Befehl kann ich nicht erkennen.
Query.SQL.Add('INSERT INTO TBLCALENDAR(ISHOLIDAY, Reiseziel, Startflughafen) VALUES(0,' + QuotedStr('Hawaii') + ', ' + QuotedStr('Frankfurt') + ');');
2. Möglichkeit: Die Werte, die ich über Variablen oder Fest in den SQL-Befehl einfügen will, übergebe ich mit Parametern. Das ganze sieht dann so aus :
Delphi-Quellcode:
Hier sehe ich einwandfrei den SQL-Befehl und weiss was er macht. In den Zeilen darunter sehe ich dann die übergebenen Parameter. Was auch der Übersichtlichkeit dient. Ein weiterer Vorteil ist, dass ich jetzt die Query nehmen kann und hier immer nur noch die Parameter übergebe und dann den SQL-Befehl ausführen kann ohne jedes mal überlegen zu müssen, was muss ich wohin schreiben.
Query.SQL.Add('INSERT INTO TBLCALENDAR(IsHoliday, Reiseziel, Startflughafen) VALUES (:IsHoliday, :Reiseziel, :StartFlughafen);');
Query.SQL.ParamByName('IsHoliday').AsInteger := 0; Query.SQL.ParamByName('Reiseziel').AsString := 'Hawaii'; Query.SQL.ParamByName('StartFlughafen').AsString := 'Frankfurt'; |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zitat:
Und Probleme mit SQL-Injection bekommst du auch keine. |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Zitat:
Ohne das Feld ID spart man sich einen weiteren Index (und den Trigger). Die Tabelle ist kleiner und benötigt so weniger Resourcen. Wie mkinzler gesagt hat ist das natürlich auch eine Frage der Philosopie. Wenn man aber einen eindeutigen natürlichen Primärschlüsselkandidaten findet (hier das DATUM), dann sollte man ihn auch benützen. Also mein Verständnis von Primärschlüsseln ist so: Gibt es einen natürlichen Primärschlüsselkandidaten bestehend aus nur einem Feld? Falls ja dann benützen. Wenn zwei oder mehr Felder benötigt werden um einen Primärschlüssel zu bilden, dann sollte man einen künstlichen Schlüssel einführen. Das gilt auch, wenn das potentielle Primärschlüsselfeld sehr lang ist. Wenn die Möglichkeit besteht, dass der Inhalt des Primärschlüsselfelds später geändert wird, dann sollte man auch einen künstlichen Schlüssel bevorzugen. ( ![]() |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Hallo,
Zitat:
Bsp. Kundennummer Kunde sagte, die sind immer eindeutig -> Prim Key 2 Jahre später will er, dass das erweitert wirrd um ein neues 2. Feld (z.B. Kunden-Nr. / Niederlassung). Man kann so viel vordenken, wie mn will, es kommt immer anders ;) Ausserdem werden Prim.-Keys oft auch als ForeignKeys verwendet, im Fall des Kunden müßte man jetzt an der ganzen DB rumschrauben. Sch... of die paar Bytes des Integer ;) Heiko |
Re: Bekomme kein INSERT mit FB und IBDAC hin!?!
Ich danke Euch für Eure ausführlichen Erläuterungen!! Vorerst bleibe ich mal bei meinem "künstlichen" Schlüssel. Ein neuer Plan (=Aufrufen des Triggers) wird nur 1x im Monat erstellt, ich denke, damit kann man gut leben :)
SCRAT |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 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