Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   create.execsql error -104 Token unknown (https://www.delphipraxis.net/192137-create-execsql-error-104-token-unknown.html)

Manollo 22. Mär 2017 11:57

Datenbank: firebird • Version: 5.2.4 • Zugriff über: delphi

create.execsql error -104 Token unknown
 
Hallo,

ihr habt sehr interessante Themen hier im Forum und ich hoffe ihr könnt mir bei meinem kleinen Problem behilflich sein (sufu hat nichts ergeben).

Ich möchte über delphi(7) für eine interbase (firebird) DB eine Prozedur erzeugen. Den den SQL Code habe ich zuvor direkt über den SQL Editor im SQL Manager auf die DB ausgeführt und er funktioniert.

Wenn ich über die delphi die TIBQuery aufrufe bekomme ich allerdings einen -104 Error, er stört sich an den ":" bei :MNR z.B. kann man die in delphi irgendwie escapen? Wenn ich die ":" weglasse bekomme ich einen error -206 MNR unknown. Wie gesagt im SQL Manager kann ich eine neue Prozedur mit diesem Code erzeugen.

Hier mein SQL-Code:

Code:
CREATE PROCEDURE XYprod(
    DID INTEGER,
    JID INTEGER,
    MNR VARCHAR(20))
AS
begin
  For select trim(Journal.XY), journal.jid from journal where DID is null and journal.XY <>'' INTO :MNR, :JID do
  begin
     SELECT first 1 DID from Daten where TRIM(Daten.XY) = :MNR into :DID;
     if (:did > 1) then
         UPDATE Journal SET DID = :DID where journal.XY = :mnr;
  end
  suspend;
end
Vielen Dank im voraus für eure Hilfe.

Viele Grüße

Manollo

mkinzler 22. Mär 2017 12:17

AW: create.execsql error -104 Token unknown
 
Wie sieht der Aufruf der Prozedur aus? Die Prozedur kann so nicht direkt ausgeführt werden. Wäre nur bei Ausführung als Codeblock möglich. (
SQL-Code:
execute block
)

nahpets 22. Mär 2017 12:21

AW: create.execsql error -104 Token unknown
 
Wenn man aus dem Delphi-Quelltext heraus eine SQL-Abfrage macht, so beginnen Parameter mit :

Diese müssen vor dem Ausführen des SQL gefüllt werden.

Beispiel:
Delphi-Quellcode:
  Query.SQL.Text := 'select * from tabelle where spalte = :wert';
  Query.Params[0].AsString := 'zu suchender Inhalt';
  // oder
  Query.ParamByName('wert').AsString := 'zu suchender Inhalt';
  Query.Open;
Das Problem hier ist nun, dass Dein SQL den : enthält, dieser hier aber nicht als Beginn eines Parameters dienen soll.

Wenn ich mit FireBird arbeite, nutze ich die Zeos-Komponenten.

Die TZQuery hat u. a. die Eigenschaften ParamChar und ParamCheck.

Schau bitte mal, ob es etwas derartiges auch bei Deinen Komponenten gibt.

Am Sinnvollsten wäre es dann, ParamCheck auf False zu setzen. In dem Fall dürfte keine Prüfung auf das Vorhandensein von Parametern stattfinden und das SQL sollte sich ausführen lassen.

Andernfalls bei ParamChar ein anderes Zeichen eingeben, welches im SQL nicht vorkommt und dieses dann für die Kennzeichnung von Parametern nutzen.

Methode unelegant, aber eventuell ein "Notnagel":

SQL wie oben und dann:
Delphi-Quellcode:
  Query.ParamByName('MNR').AsString := ':MNR';
  Query.ParamByName('JID').AsString := ':JID';
  Query.ParamByName('DID').AsString := ':DID';
Das aber bitte nur dann probieren, wenn's anders überhauptnicht geht. Es muss nicht unbedingt funktionieren, könnte aber mit ein bisserl Glück.

Mit den Zeos-Komponenten lässt sich eine CREATE PROCEDURE in Query.SQL.Text mit Query.ExecSQL problemlos ausführen.
Ein execute block ist dort nicht erforderlich.

Manollo 24. Mär 2017 07:54

AW: create.execsql error -104 Token unknown
 
Hallo,

vielen Dank für eure Antworten. Leider hat es noch nicht geklappt

1. ParamCheck auf False gesetzt, leider bekomme ich hier die MEldung XSQLDA-Index außerhalb des gültigen Bereichs.
2. Sobald ich die Querys, so wie beschreiben, erzeuge und ParamCheck wieder auf true setze, bekomme ich wieder den alten Fehler (-104 Error).

So habe ich es erstellt.

Code:
procedure TfrmMain.IBDatabaseMKPAfterConnect(Sender: TObject);
begin
  procedure_create.ParamByName('MNR').AsString := ':MNR';
  procedure_create.ParamByName('JID').AsString := ':JID';
  procedure_create.ParamByName('DID').AsString := ':DID';
  procedure_create.ExecSQL;
end;
Für weitere Ansätze wäre ich dankbar.

Viele Grüße

Manollo

mkinzler 24. Mär 2017 08:34

AW: create.execsql error -104 Token unknown
 
ParamCheck muss True sein, dass die Parameterobjekte automatisch erzeugt werden. Sonst müsstest Du das manuell erledigen.

nahpets 24. Mär 2017 09:45

AW: create.execsql error -104 Token unknown
 
Was steht denn hier konkret vor dem Befüllen der Parameter in procedure_create.SQL.Text?

SQL-Code:
procedure TfrmMain.IBDatabaseMKPAfterConnect(Sender: TObject);
begin
  procedure_create.ParamByName('MNR').AsString := ':MNR';
  procedure_create.ParamByName('JID').AsString := ':JID';
  procedure_create.ParamByName('DID').AsString := ':DID';
  procedure_create.ExecSQL;
end;
So ist das nur ein wages Rumraten und Stochern mit Hilfe der :glaskugel:

Du hattest oben doch ein SQL, das Doppelpunkte enthält, bei denen es sich nicht um Parameter handelt.

Wenn Parameter nicht ausgewertet werden sollen, muss ParamCheck auf False stehen. Es dürfen dann auch keine Parameter befüllt werden.

ParamCheck = false und ParamByName('ParameterName').AsString := 'Wert' schließen sich gegenseitig aus.

Ob der auftretende Fehler ursächlich mit den Parametern zusammenhängt, erscheint mir momentan nicht zwingend gegeben.

https://www.benefind.de/web.php?org=...erbase++xsqlda

Der Fehler kann wohl auch auftreten, wenn ein SQL ungültige Zeichen enthält.

Lässt sich die Prozedur mit reinen Datenbankmitteln problemlos erstellen? Wenn nein, bitte erst dort die Fehler beheben und dann via Delphi erneut probieren.

Manollo 24. Mär 2017 09:52

AW: create.execsql error -104 Token unknown
 
Zitat:

Zitat von nahpets (Beitrag 1365459)
Was steht denn hier konkret vor dem Befüllen der Parameter in procedure_create.SQL.Text?

....
Der Fehler kann wohl auch auftreten, wenn ein SQL ungültige Zeichen enthält.

Lässt sich die Prozedur mit reinen Datenbankmitteln problemlos erstellen? Wenn nein, bitte erst dort die Fehler beheben und dann via Delphi erneut probieren.

Hallo,

ja, wie oben beschrieben kann ich das Erzeugen der Prozedur im SQL Manager ohne Probleme ausführen. Sobald ich aber in Delphi die TIBQuery erzeuge und mit dem SQL befülle bekomme ich die besagte Fehlermeldung.

nahpets 24. Mär 2017 09:55

AW: create.execsql error -104 Token unknown
 
Bitte Quelltext dazu:
Zitat:

Zitat von nahpets
Was steht denn hier konkret vor dem Befüllen der Parameter in procedure_create.SQL.Text?

Nicht nur den der Prozedur, sondern den, an der SQL.Text in Delphi befüllt wird.

hoika 24. Mär 2017 13:24

AW: create.execsql error -104 Token unknown
 
Hallo,
von welcher DB-Komponentensammlung reden wir hier eigentlich?
IBDAC hat dafür z.B. TIBCScript.

TIBQuery -> TIBScript ?



Zeig doch noch mal den ganzen Code.
Laut dem hier
http://stackoverflow.com/questions/3...om-delphi-code
müsste ParamCheck:=False vollkommen ausreichen.

Das hier ist falsch, es geht hier nicht um parametrisierte Queries.
Delphi-Quellcode:
procedure TfrmMain.IBDatabaseMKPAfterConnect(Sender: TObject);
begin
  procedure_create.ParamByName('MNR').AsString := ':MNR';
  procedure_create.ParamByName('JID').AsString := ':JID';
  procedure_create.ParamByName('DID').AsString := ':DID';
  procedure_create.ExecSQL;
end;
In meinem Link weiter oben steht noch was zu Set Term .
Les dir das noch mal durch, vielleicht ist das Semikolon ja das Problem.

ibp 24. Mär 2017 15:18

AW: create.execsql error -104 Token unknown
 
das Problem sind die ''

Wenn du eine SP erzeugen willst, dann pramcheck=false und für alle '' am besten mit QuotedStr arbeiten...

Delphi-Quellcode:
  query.sql.add('CREATE PROCEDURE XYprod(');
  query.sql.add('   DID INTEGER,');
  query.sql.add('   JID INTEGER,');
  query.sql.add('   MNR VARCHAR(20))');
  query.sql.add('AS');
  query.sql.add('begin');
  query.sql.add(' For select trim(Journal.XY), journal.jid from journal where DID is null and journal.XY <>'+quotedstr('')+' INTO :MNR, :JID do');
  query.sql.add(' begin');
  query.sql.add('    SELECT first 1 DID from Daten where TRIM(Daten.XY) = :MNR into :DID;');
  query.sql.add('    if (:did > 1) then');
  query.sql.add('        UPDATE Journal SET DID = :DID where journal.XY = :mnr;');
  query.sql.add(' end');
  query.sql.add(' suspend;');
  query.sql.add('end');
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz