PDA

View Full Version : RPG Programm via DB2 SQL Procedure ausführen / JDBC



Curan
18-09-09, 13:22
Hallo!

Ich habe momentan die große Ehre, Schüler an einer tollen Schule zu sein, der eine AS400 zur Verfügung steht. Da ich mich seit einiger Zeit auch mit Java beschäftige, interessiere ich mich natürlich für die Kombination Java/RPG/DB2. Die Verbindung zur AS400 funktioniert recht gut, auch einfache SQL Statements sind kein Problem (jt400.jar)

Nun möchte ich aber gerne ein RPG Programm (welches einen Parameter benötigt) via Java aufrufen & habe gelesen, das es am besten mit stored procedures funktioniert.

Allerdings scheitere ich genau hier, ich versuche eine stored procedure zu erstellen, die 2 Werte übergeben bekommt. Zunächst den Programmnamen und anschließend den Parameterwert fürs Programm, aber wie führe ich nun via SQL Statement ein RPG Programm auf der AS400 aus?

Außerdem würde ich gerne wisse, ist das überhaupt der richtige weg oder geht es anders "sauberer"?


schöne Grüße aus dem regnerischen Wien

Fuerchau
18-09-09, 14:05
Naja, eine Prozedur, die ein externes Programm aufruft, muss auch entsprechend definiert werden.
D.h., beim CREATE PROCEDURE wird der Name des aufzurufenden Programmes sowie Übergabeparameter mitgegeben.

Der Aufruf erfordert dann nur noch den Prozedurnamen und die Parameter.

Das Gleiche gilt auch fur CREATE FUNCTION, nur dass diese einen Returnwert hat.

Beispiel eier CREATE FUNCTION:



CREATE FUNCTION USMOD_16/DATESERIAL
(YEAR INTEGER,
MONTH INTEGER,
DAY INTEGER)
RETURNS DATE
LANGUAGE RPGLE
EXTERNAL NAME 'USMOD_16/DATSER'
DETERMINISTIC
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
PARAMETER STYLE SQL
ALLOW PARALLEL
NOT FENCED


Beispiel des zugehörigen ILERPG's:



hactgrp(*caller) dftactgrp(*no) datfmt(*iso)

d SYear s 10I 0
d SMonth s 10I 0
d SDay s 10I 0

d SQLDate s d
d SYear_Ind s 5I 0
d SMonth_Ind s 5I 0
d SDay_Ind s 5I 0

d SQLDate_Ind s 5I 0
d SQLState s 5
d FuncName s 139 varying
d SpecName s 128 varying
d DiagMsg s 70 varying

c *entry plist
c parm SYear
c parm SMonth
c parm SDay
c parm SQLDate
c parm SYear_Ind
c parm SMonth_Ind
c parm SDay_Ind
c parm SQLDate_Ind
c parm SQLState
c parm FuncName
c parm SpecName
c parm DiagMsg
c*
c/free
if SYear_ind <> *zero
or SMonth_ind <> *zero
or SDay_ind <> *zero;
SQLDate_ind = -1; // Ergebnis ist NULL
else;
monitor;
SQLDate = %date('0001-01-01')
+ %Years(SYear-1)
+ %Months(SMonth-1)
+ %Days(SDay-1);
on-error *all;
SQLDate_ind = -1; // Ergebnis ist NULL
endmon;
endif;
/end-free
c*
c*
c return


Weiteres findest du im SQL-Referenzhandbuch
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/pdf_table/table/launcher.htm

Suche dort nach SQL.

Curan
18-09-09, 14:20
Hallo!

Herzlichen dank für diese ausführliche und sehr hilfreiche Antwort! Sie haben mir sehr weiter geholfen.

In unserer kleinen Gruppe, angehender RPG Programmierer, sind Sie sehr bekannt, dank diesem Forum! Ich glaube, ich werde Sie noch öfters um Rat erbitten müssen :o

Nochmals, tausend Dank!

lg

Curan
21-09-09, 15:29
Hallo!

Tut mir leid, aber ich muss wieder um hilfe erbitten :(

Der Programmaufruf via stored procedures funktioniert mit Java super. Jetzt versuche ich auch Parameter zu übergeben, aber das ist wieder eine Hürde die ich nicht alleine bewältigen kann.


CREATE PROCEDURE JT1
(IN nachricht CHAR(120),
IN empfaenger CHAR(15))
EXTERNAL NAME 'SRC25/JTST1' LANGUAGE CL
0001.00 PGM PARM(&NACHRICHT &EMPFAENGER) 090921
0002.00 DCL VAR(&NACHRICHT) TYPE(*CHAR) LEN(120) 090921
0003.00 DCL VAR(&EMPFAENGER) TYPE(*CHAR) LEN(15) 090921
0004.00 SNDMSG MSG(&NACHRICHT) TOUSR(&EMPFAENGER) 090921
0005.00 ENDPGM 090921
cstmt1 = con.prepareCall("{call qgpl.JT1(?, ?)}");
cstmt1.setString(1, "Hallo du hilfreiche AS400 Community!");
cstmt1.setString(1, "SCHULE25");
cstmt1.execute();

Vielleicht sehe ich auch einfach den Wald vor lauter Bäumen nicht, ich weiß es nicht, aber bedanke mich schonmal im vorraus bei allen!

liebe grüße

Fuerchau
21-09-09, 15:53
Hier ist das Problem der SQL-Signatur.

Wichtig ist also, dass die Parameter GENAU so übergeben werden, wie sie die Prozedur erwartet.
In deinem Fall übergibst du 2 Strings, also VARCHAR an Stelle von 2 fixen CHAR-feldern.

Hier hilft dann das Casting:
cstmt1 = con.prepareCall("{call qgpl.JT1(cast(? as char(120)), cast(? as char(15)))}");

Dann stimmt auch die Signatur und SQL findet die Prozedur.

Hintergrund:
SQL erlaubt genauso wie Java identische Prozedurnamen mit unterschiedlichen Parameterlisten.
An Hand dieser Signatur wird die passende Prozedur ermittelt.