PDA

View Full Version : Embedded SQL Kommando



haertl
02-07-04, 13:59
Hallo,
Ich führe in einem PGM ein Embedded SQL Statement aus,
das mir leider kein Ergebnis zurückliefert. Gebe ich das
Statement im interaktiven SQL ein und ersetze die Host
Variablen so funktioniert es. Die Host Variablen werden
im Programm mit korrekten Werten gefüllt. Gibt es
Einschränkungen was die Länge des Kommandos betrifft ?
Das Feld SQLCMD ist 512 Byte groß und Alpha


Programm:
441 /EXEC SQL
442 + EXECUTE IMMEDIATE :SQLCMD
443 /END-EXEC

Debugger:
SQLCMD =
....5...10...15...20...25...30...35...40...45...50 ...55...60
1 'SELECT SUM(VB) INTO :H#SUM FROM LOHKOSP WHERE VABHI = 4 AND '
61 'VWERK = :##WRK AND VABJJ = :##JR AND VABMM BETWEEN 01 AND :#'
121 '#MM AND VEURO = 1 AND VBKST IN ( 145210, 145221, 145224, 145'
181 '222, 145223) AND VKONT IN ( 60100, 60110, 60150, 60180, 6100'
241 '0) '
301 ' '
361 ' '
421 '

Fuerchau
02-07-04, 14:16
Select geht nicht mit Immediate !

Codiere den Select direkt ohne Execute !

haertl
02-07-04, 14:42
Wie kann ich einen per Programm erstellten SQL-Command-String
aufrufen, so das er mir eine Hostvariable mit dem Ergebnis füllt?

Danke für alle Antworten

Rincewind
02-07-04, 15:11
Mit

C/Exec SQL
c+ select a from datei into :b
C/end-exec

Wobei a der Feldname ist und B ein entsprechend grosses Feld im Programm.

Du kannst mehrere Werte durch , Trennen

Select a, a2 from datei into :b, :b2

Ansonsten findest du bestimmt viele Hinweise hier im Forum (Suchfunktion gibts ja ) *g*

Schönes WE
Rince

Fuerchau
04-07-04, 11:55
Um dynamische SQL's mit Ergebniswerten zu erhalten musst du mit SQLDA's arbeiten.
Hostvariablen nützen da überhaupt nichts, da das nur für "embedded SQL" also zur Compile-Zeit bekannten SQL's ist.
Die Verwendung von SQLDA's sprengt allerdings diesen Rahmen hier.

Stichworte hier sind "execute xxx using :mysqlda", "fetch mycursor using :mysqlda".
Hostvariablen sind da leider nicht möglich.

BenderD
04-07-04, 12:42
Hallo,

gilt natürlich alles für embedded SQL in RPG, das ist nämlich ein Problem des lausigen Pre-Compilers. In Java wäre das z.B. eine der leichtesten Übungen.

mfg

Dieter Bender


Um dynamische SQL's mit Ergebniswerten zu erhalten musst du mit SQLDA's arbeiten.
Hostvariablen nützen da überhaupt nichts, da das nur für "embedded SQL" also zur Compile-Zeit bekannten SQL's ist.
Die Verwendung von SQLDA's sprengt allerdings diesen Rahmen hier.

Stichworte hier sind "execute xxx using :mysqlda", "fetch mycursor using :mysqlda".
Hostvariablen sind da leider nicht möglich.

B.Hauser
04-07-04, 14:42
@ Fuerchau
Solange immer die gleiche Anzahl Felder, in der gleichen Reihenfolge mit dem gleichen Format ausgegeben werden müssen, ist auch beim dynamischen SQL keine SQLDA erforderlich.

@haertl
Soweit ich das aus dem obigen Beispiel ersehen kann, möchtest Du einen einzigen Wert zurück erhalten.
In diesem Fall würde ich auch kein dynamisches sondern ein statisches SQL verwenden.
Eine Möglichkeit hierzu hat Kollege Rincewind bereits angegeben.
Die zweite Möglichkeit wäre ein Set-Befehl:


C/EXEC SQL
C+ Set :HSUM = Select Sum(VB)
C+ from LOHKOSP
C+ where VABHI = 4 AND VWERK = :##WRK
C+ AND VABJJ = :##JR
C+ AND VABMM BETWEEN 01 AND :##MM C+ AND VEURO = 1
C+ AND VBKST IN ( 145210, 145221, 145224, 145181 '222, 145223)
C+ AND VKONT IN ( 60100, 60110, 60150, 60180, 61000)'
C/End-Exec


Ist wirklich ein dynamisches SQL erforderlich, müssen die Host-Variablen entweder im String aufgelöst werden ( + MyVar), oder mit Platzhaltern (?) und Using gearbeitet werden.
Der Unterschied zwischen beiden Methoden liegt darin, dass im ersten Fall der Command bei jedem Aufruf neu konvertiert werden muss (was bei EXECUTE IMMEDIATE sowieso der Fall ist), während bei der zweiten Methode der Sting nur einmal konvertiert wird und nur die Werte der Host-Variablen ausgetauscht werden.

Um einen Select-Befehl im dynamischen SQL verarbeiten zu können, muss zunächst der Command durch eine PREPARE-Anweisung in einen SQL-String konvertiert werden. Dann muss ein Cursor für diesen SQL-String deklariert werden. Anschliessend kann der Cursor geöffnet werden (OPEN), der Satz eingelesen (FETCH) und der Cursor wieder geschlossen werden (CLOSE).

Bisher habe ich schon jede Menge SQLRPG-Programme geschrieben, dynamisches SQL musste ich jedoch nur in einigen ganz wenigen Fällen verwenden, da selbst unterschiedliche Sortierungen im statischen SQL gehandelt werden können.

@Dieter
Ich fand das SQL-Handling in JAVA, bzw. das was ich bisher davon gesehen habe, auch nicht unbedingt einfacher!

Birgitta

BenderD
04-07-04, 17:50
Hallo Birgitta,



@Dieter
Ich fand das SQL-Handling in JAVA, bzw. das was ich bisher davon gesehen habe, auch nicht unbedingt einfacher!

Birgitta

das muss and dem liegen, was Du bisher gesehen hast. Da gibt es die volle Palette, was immer Du willst:
- pure JDBC alles dynamisch mit allen Freiheitsgraden, ohne Netz und doppelten Boden
- SQLJ embedded SQL in Java, ähnlich embedded SQL in anderen Sprachen, mit leistungsfähigem PreCompiler (könnte allerdings leider Auslaufmodell sein, wenn man Gerüchten glauben soll).
- JDO Datenbankzugriff ohne SQL
- Mapping Frameworks wie OJB oder Hibernate mit automatischen Datenbankzugriffen nach XML Konfiguration
- EJBs mit container managed persistence
- SQL Tag language in JSTL aus Java Server Pages (hatte ich fast vergessen, was ich auch aus Designgründen empfehle)

mfg

Dieter Bender

Fuerchau
05-07-04, 08:30
@Birgitta

Diese Beispiele haben mit dynamischem SQL wenig zu tun und können natürlich mit statischen SQL's gelöst werden.
Auch wenn ich immer die gleiche Anzahl Ergebnisfelder habe, ist das nocht nicht so richtig dynamisch.
Parametermarker "?" sind ja ganz in Ordnung, aber was ist, wenn ich die Anzahl und Art der möglichen Parameter noch nicht kenne ? Soll ich dann schon mal 250 Parameter definieren und womit fülle ich sie dann ?

Richtiges dynamisches SELECT-SQL (bzw. CALL) funktioniert nur unter Verwendung von SQLDA's, wo ich Anzahl und Ausprägung der Parameter als auch der Ergebnisse über SQLDA's steuere.
Für alle anderen SQL's reicht ggf. der "execute immediate".

Insofern gebe ich Dieter recht, dass andere HLL's bessere Unterstützung von dynamischen SQL's geben. Auf der AS/400 bleibt mir da nur REXX.