Anmelden

View Full Version : Execute Immediate Problem



haertl
12-07-04, 08:37
Hallo, ich habe ein SQL-Programm geschrieben, welches
viele Embedded SQL Statements enthält. Z.B. so eins

C/EXEC SQL
C+ SELECT SUM(VB) INTO :H#SUM FROM LOHKOSP WHERE
C+ VABHI = 4 AND VWERK = :##WRK AND VABJJ = :##JR AND
C+ VABMM BETWEEN 01 AND :##MM AND
C+ (VBKST = 145210 OR VBKST = 145221 OR
C+ VBKST = 145224 OR
C+ VBKST = 145222 OR VBKST = 145223) AND
C+ (VKONT = 60100 OR VKONT = 60110 OR VKONT = 60150 OR
C+ VKONT = 60180 OR VKONT = 61000)
C+ AND VEURO = 1
C/END-EXEC
C*

Problem:
Bei Programmänderungen müssen alle Statements manuell im Source abgeändert werden.
Um dies zu vermeiden, habe ich ein Verwaltungsprogramm geschrieben, welches die
Parameter in eine Datei schreibt.
Diese Parameter werden in einem weiteren Programm gelesen und in einer Variable zu einem SQL
Kommando zusammengebaut. Z.B. so

Der Inhalt der Variable SQLCMD ist:
SELECT SUM(VB) INTO :H#SUM FROM LOHKOSP WHERE VABHI = 4 AND
VWERK = :##WRK AND VABJJ = :##JR AND VABMM BETWEEN 01 AND :##MM AND
VEURO = 1 AND VBKST IN ( 145210, 145221, 145224, 145222, 145223)
AND VKONT IN ( 60100, 60110, 60150, 60180, 61000)


Ich hatte vor das Kommando mit EXECUTE IMMEDIATE auszuführen:

C/EXEC SQL
C+ EXECUTE IMMEDIATE :SQLCMD
C/END-EXEC


Was aber laut Handbuch und Nachfrage in diesem Forum nicht geht.

Wie kann ich diesem Problem lösen ??

Danke für alle Antworten.

BenderD
12-07-04, 09:15
Hallo,

das Problem ist ncoh nicht klar formuliert: welche Parameter stehen denn in dieser Datei? Je nachdaem was da variabel sein soll geht das mit relativ einfachen prepared Statements.

mfg

Dieter Bender


Hallo, ich habe ein SQL-Programm geschrieben, welches
viele Embedded SQL Statements enthält. Z.B. so eins

C/EXEC SQL
C+ SELECT SUM(VB) INTO :H#SUM FROM LOHKOSP WHERE
C+ VABHI = 4 AND VWERK = :##WRK AND VABJJ = :##JR AND
C+ VABMM BETWEEN 01 AND :##MM AND
C+ (VBKST = 145210 OR VBKST = 145221 OR
C+ VBKST = 145224 OR
C+ VBKST = 145222 OR VBKST = 145223) AND
C+ (VKONT = 60100 OR VKONT = 60110 OR VKONT = 60150 OR
C+ VKONT = 60180 OR VKONT = 61000)
C+ AND VEURO = 1
C/END-EXEC
C*

Problem:
Bei Programmänderungen müssen alle Statements manuell im Source abgeändert werden.
Um dies zu vermeiden, habe ich ein Verwaltungsprogramm geschrieben, welches die
Parameter in eine Datei schreibt.
Diese Parameter werden in einem weiteren Programm gelesen und in einer Variable zu einem SQL
Kommando zusammengebaut. Z.B. so

Der Inhalt der Variable SQLCMD ist:
SELECT SUM(VB) INTO :H#SUM FROM LOHKOSP WHERE VABHI = 4 AND
VWERK = :##WRK AND VABJJ = :##JR AND VABMM BETWEEN 01 AND :##MM AND
VEURO = 1 AND VBKST IN ( 145210, 145221, 145224, 145222, 145223)
AND VKONT IN ( 60100, 60110, 60150, 60180, 61000)


Ich hatte vor das Kommando mit EXECUTE IMMEDIATE auszuführen:

C/EXEC SQL
C+ EXECUTE IMMEDIATE :SQLCMD
C/END-EXEC


Was aber laut Handbuch und Nachfrage in diesem Forum nicht geht.

Wie kann ich diesem Problem lösen ??

Danke für alle Antworten.

haertl
12-07-04, 09:41
Die Parameter sind in diesem Fall die Werte 145210 sowie 145221, 145224 , 145222, 145223, 60100, 60110, 60150, 60180, 61000. Sie werden durch einen Datensatz
aus einer Datei eingelesen. Jeder Wert steht in einer eigenen Variable. Die Hostvariablen
##WRK, :##JR und :##MM werden durch eine Eingabemaske beim Start des
Programms vom User eingegeben. Danach werden die Informationen in eine
Variable zum SQL-Kommando zusammengebaut.

BenderD
12-07-04, 10:28
Hallo,

SELECT SUM(VB)
INTO :H#SUM
FROM LOHKOSP
WHERE VABHI = 4 AND
VWERK = ? AND
VABJJ = ?
AND VABMM BETWEEN 01 AND ? AND
VEURO = 1 AND ( VBKST = ? OR
VBKST = ? OR
VBKST = ? OR
VBKST = ? OR
VBKST = ?)
AND (VKONT = ? OR
VKONT = ? OR
VKONT = ? OR
VKONT = ? OR
VKONT = ?)
lässt sich im Programm preparen und dann mit Execute using variabel ausführen.
(Tippfehler vorbehalten)

mfg

Dieter Bender



Die Parameter sind in diesem Fall die Werte 145210 sowie 145221, 145224 , 145222, 145223, 60100, 60110, 60150, 60180, 61000. Sie werden durch einen Datensatz
aus einer Datei eingelesen. Jeder Wert steht in einer eigenen Variable. Die Hostvariablen
##WRK, :##JR und :##MM werden durch eine Eingabemaske beim Start des
Programms vom User eingegeben. Danach werden die Informationen in eine
Variable zum SQL-Kommando zusammengebaut.

haertl
12-07-04, 12:26
Hallo Herr Bender,

im Handbuch steht:

Syntax: EXECUTE statementname USING hostvariable

Mit dem Hinweis: The prepared statement cannot be a select statement. ???!!!
Dazu gehört doch auch der select sum.


Außerdem fällt mir ein, daß die Anzahl der Parameter je Aufruf unterschiedlich
sein können. Hier muß ich dann mit SQLDA arbeiten oder ?

Hätten Sie vielleicht ein kleines Beispiel ?
Danke für Ihre Antwort
M.f.G. Härtl

BenderD
12-07-04, 13:11
Hallo nochmal,

statt SELECT geht prepare eines Cursors und dann OPEN using, mit nachfolgendem FETCH. Damit könnte man wohl sogar die ursprüngliche Geschichte heilen.
Das Problem mit der Anzahl der verwendeten Parameter lässt sich auf mehrere Arten heilen, wobei man hier auch aufpassen müsste, wie gut das ausgeführt wird. Der WHERE IN ist ein ausgesprochener Penner. In Ihrem Fall könnte man z.B. WHERE Klauseln blind zufügen (doppeln), beim koppeln mit AND kann man and xyz < Highval oder > loval zufügen.

Beispiel habe ich sicherlich, nur im Moment keine Zeit zum Suchen (deshalb auch Vertipper und die Ungenauigkeit der vorherigen Antwort.)
SQLDA vermeide ich, weil ich das für schlecht lesbar und daher Fehler trächtig bei Änderung halte.

mfg

Dieter Bender


Hallo Herr Bender,

im Handbuch steht:

Syntax: EXECUTE statementname USING hostvariable

Mit dem Hinweis: The prepared statement cannot be a select statement. ???!!!
Dazu gehört doch auch der select sum.


Außerdem fällt mir ein, daß die Anzahl der Parameter je Aufruf unterschiedlich
sein können. Hier muß ich dann mit SQLDA arbeiten oder ?

Hätten Sie vielleicht ein kleines Beispiel ?
Danke für Ihre Antwort
M.f.G. Härtl

B.Hauser
17-07-04, 19:30
Die Parameter sind in diesem Fall die Werte 145210 sowie 145221, 145224 , 145222, 145223, 60100, 60110, 60150, 60180, 61000. Sie werden durch einen Datensatz
aus einer Datei eingelesen. Jeder Wert steht in einer eigenen Variable. Die Hostvariablen
##WRK, :##JR und :##MM werden durch eine Eingabemaske beim Start des
Programms vom User eingegeben. Danach werden die Informationen in eine
Variable zum SQL-Kommando zusammengebaut.

Hallo,

vielleicht habe ich ja Dein Problem nicht verstanden, aber:
Wenn Du die Parameter sowieso schon in einer Datei hast, warum verwendest du nicht bei Deinem IN einen Subselect?

Select .... from .... where ABC in (Select MyFld from MyFile where Key = 'X')

Voraussetzung ist, dass pro Auswahl-Möglichkeit ein Satz in der Datei vorhanden ist.

Wenn der String aufbereitet ist benötigst Du folgende Schritte:
1. Über ein Prepare-Statement wird der String in ein SQL-Statement konvertiert
2. Über ein Declare-Statement wird ein Cursor definiert.
3. Mit Open wird der Cursor geöffnet
4. Mit Fetch wird der erste (in deinem Fall einzige Satz) eingelesen.
5. Mit Close wird der Cursor wieder geschlossen.

Und das klappt sicher! bei einem Select Statement. Select ... into geht natürlich nicht!

Die Descriptor Area (SQLDA) brauchst Du nur, wenn im Select unterschiedliche Felder benötigt werden. Soweit ich das beurteilen kann ist das bei Dir nicht der Fall, da jedes Mal der Maximal-Wert ermittelt werden soll.

Birgitta