PDA

View Full Version : Java aufruf von RPGLE via SQL-Procedure



Azaron
19-05-08, 16:05
Hallo Leute,

ich bräuchte mal wieder eure Hilfe.

Diesmal versuch ich mit einem Java-Programm via SQL-Procedure von einem RPG-Programm einen Resultset zurück zu kriegen.

Hier die Code-Snipets:

Java:
Connection cn = instance.getConnection();
if(cn!=null) {
CallableStatement stmt1 = null;
ResultSet rs1 = null;
String sql1 = "";
try {

sql1 = "CALL MACXT.GETGRUNDWARE(?,?,?,?,?,?,?)";

stmt1 = cn.prepareCall(sql1);
stmt1.setString(1, strCompany);
stmt1.setString(2, strSeason);
stmt1.setString(3, strCollection);
stmt1.setString(4, strCut);
stmt1.setString(5, strVariation);
stmt1.setString(6, strArticle);
stmt1.setString(7, strColor);
stmt1.setFetchSize(50);
rs1 = stmt1.executeQuery();

...

SQL:
CREATE PROCEDURE MACXT/GETGRUNDWARE(
IN FINR CHAR ( 3),
IN SAIS CHAR( 2),
IN KOLL CHAR ( 2),
IN FORM CHAR ( 4),
IN VACP CHAR ( 2),
IN ARNR CHAR ( 6),
IN FBNR CHAR ( 4))
RESULT SETS 1 LANGUAGE CL NOT
DETERMINISTIC CONTAINS SQL EXTERNAL NAME MACPGM/JSQL01C PARAMETER
STYLE GENERAL

CLLE:
PGM PARM(&FINR &SAIS &KOLL &FORM &VACP &ARNR &FBNR)

DCL VAR(&FINR) TYPE(*CHAR) LEN(3)
DCL VAR(&SAIS) TYPE(*CHAR) LEN(2)
DCL VAR(&KOLL) TYPE(*CHAR) LEN(2)
DCL VAR(&FORM) TYPE(*CHAR) LEN(4)
DCL VAR(&VACP) TYPE(*CHAR) LEN(2)
DCL VAR(&ARNR) TYPE(*CHAR) LEN(6)
DCL VAR(&FBNR) TYPE(*CHAR) LEN(4)

CHKOBJ OBJ(QTEMP/JSQL01PF) OBJTYPE(*FILE)
MONMSG MSGID(CPF0000) EXEC(DO)
CRTDUPOBJ OBJ(JSQL01PF) FROMLIB(MACDTA) OBJTYPE(*FILE) +
TOLIB(QTEMP) DATA(*NO)
MONMSG MSGID(CPF0000)
ENDDO

CLRPFM FILE(QTEMP/JSQL01PF)
MONMSG MSGID(CPF0000)
OVRDBF FILE(JSQL01PF) TOFILE(QTEMP/JSQL01PF)
MONMSG MSGID(CPF0000)

CALL PGM(JSQL01R) PARM(&FINR &SAIS &KOLL &FORM +
&VACP &ARNR &FBNR)
MONMSG MSGID(CPF0000)

ENDPGM


RPGLE:
....
C/EXEC SQL
C+ DECLARE CUR1 SCROLL CURSOR WITH RETURN TO CLIENT FOR
C+ SELECT * FROM QTEMP/JSQL01PF
C+ FOR FETCH ONLY
C/END-EXEC
C/EXEC SQL
C+ OPEN CUR1
C/END-EXEC
C/EXEC SQL
C+ SET RESULT SETS FOR RETURN TO CLIENT
C+ CURSOR CUR1
C/END-EXEC

Hinweis:
Ich fülle in dem RPGLE die QTEMP/JSQL01PF mit Daten aus ein paar Dateien.

Wenn ich das jetzt ausführe krieg ich folgende Fehler:
java.sql.SQLException: Cursor state not valid.
Im Joblog des Jobs sagt er mir dazu das:
Nachrichten-ID . . . . : SQL0579
Lesen von SQL-Daten nicht zulässig.
Nachrichten-ID . . . . : SQL0501
Cursor CUR1 nicht geöffnet.



Ich such da jetzt schon seit Stunden nach der Ursache... :(

Wäre echt nett wenn ihr einen Hinweis für mich hättet.

Danke

pwrdwnsys
20-05-08, 06:09
Nach dem

rs1 = stmt1.executeQuery();

fehlt ein rs1.next();

Nur so wird der Cursor auf die erste Zeile des ResultSets gesetzt. Noch besser:

if (rs1.next()) {
.....
.....

}

Azaron
20-05-08, 07:02
sorry das hab ich vergessen zu posten.

Danach geht es mit


while (rs1.next() ) {
...
}


weiter.


Leider bringt er laut debugger schon beim
executeQuery() den Cursorfehler.


Außerdem ist der Fehler ja scheinbar in meinem RPG.
Zumindest glaub ich das, da die Fehlermeldungen im Joblog doch sehr danach aussehen.

BenderD
20-05-08, 07:37
warum werden da auch vier Programmiersprachen (CL, RPG, SQL und Java verwendet), das machen doch nur Leute, die gerne Fehler suchen...

D*B


sorry das hab ich vergessen zu posten.

Danach geht es mit


while (rs1.next() ) {
...
}


weiter.


Leider bringt er laut debugger schon beim
executeQuery() den Cursorfehler.


Außerdem ist der Fehler ja scheinbar in meinem RPG.
Zumindest glaub ich das, da die Fehlermeldungen im Joblog doch sehr danach aussehen.

Azaron
20-05-08, 08:37
warum werden da auch vier Programmiersprachen (CL, RPG, SQL und Java verwendet), das machen doch nur Leute, die gerne Fehler suchen...

D*B

Das mach ich ja auch bloß, weil mir nix besseres Einfallen will.

Problem ist das ich Daten aus 6 Tabellen lesen muss und mehere Sätze zurückbekommen kann.
Mit einem SQL-Statement dauert das viel zu lange (6er Join! :-o)

Deshalb hab ich mir gedacht ich mach ein kleines RPG (das ja auch supi für sich alleine läuft) das eine QTEMP/Datei mit den Ergebnissätzen füllt.
Diese wollte ich dann ans Java zurück geben...

Wegen der QTEMP-Datei das CLLE.

Bin immer für neue Lösungsansätze hierzu offen.

pwrdwnsys
20-05-08, 08:38
sorry das hab ich vergessen zu posten.

Danach geht es mit


while (rs1.next() ) {
...
}


weiter.


Leider bringt er laut debugger schon beim

executeQuery() den Cursorfehler.


Außerdem ist der Fehler ja scheinbar in meinem RPG.
Zumindest glaub ich das, da die Fehlermeldungen im Joblog doch sehr danach aussehen.




Dann prüf doch mal, ob das ResultSet =null ist. dann würde der Aufruf nicht funktionieren und der Fehler tatsächlich "weiter unten" liegen.
Und ja - die Mischung der vielen Programmiersprachen ist natürlich etwas unglücklich. Vielleicht postest Du mal, was Du eigentlich machen möchtest. Dann kann Dir sicherlich besser geholfen werden.

BenderD
20-05-08, 09:03
warum soll das im SQL langsamer sein als mit dem RPG Umweg?

D*B



Problem ist das ich Daten aus 6 Tabellen lesen muss und mehere Sätze zurückbekommen kann.
Mit einem SQL-Statement dauert das viel zu lange (6er Join! :-o)

Fuerchau
20-05-08, 09:42
Setze ggf. per "exec sql set option ..." die CloseCursor-Eigenschaft, so dass der Cursor nach Prozedurende nicht automatisch geschlossen wird.

Es bietet sich jedoch an, nach dem synchronen Aufruf der RPG-Prozedur den "select * from qtemp.mytbl" selber auszuführen.
Die Prozedur könnte ja als Ergebnis die Anzahl Sätze liefern, so dass das Java-PGM dann entscheiden kann, ob der Select noch lohnt.

Azaron
20-05-08, 11:08
Hallo,

vielen Dank erstmal für die Tipps.
Ich habe jetzt endlich gefunden woran es lag.
Im CREATE-Procedudre-Statement hab ich fälschlicherweise zuerst CONTAINS SQL statt READS SQL DATA angegeben gehabt.

CREATE PROCEDURE MACXT/GETGRUNDWARE(
IN FINR CHAR ( 3),
IN SAIS CHAR( 2),
IN KOLL CHAR ( 2),
IN FORM CHAR ( 4),
IN VACP CHAR ( 2),
IN ARNR CHAR ( 6),
IN FBNR CHAR ( 4))
RESULT SETS 1 LANGUAGE CL NOT
DETERMINISTIC READS SQL DATA EXTERNAL NAME MACPGM/JSQL01C PARAMETER
STYLE GENERAL


Das hab ich zwar als erstes schon korrigiert gehabt... leider war ich zu dumm den QZDASOINIT-JOB zu killen :-/
Somit hat er immer (egal was ich danach gemacht habe) noch auf die alte Definition zugegriffen gehabt.

Naja, nächstes mal bin ich klüger.

Danke nochmal für all die nett gemeinten Ratschläge.