PDA

View Full Version : Java Aufruf an Stored Procedure RPG ServicePGM



Seiten : [1] 2

boonkelz
08-05-08, 07:50
Hallo zusammen !
Ich beschäftige mich schon seit einiger Zeit mit Stored Procedure Aufrufen von Java nach RPG Service Programmmen. Leider kommt beim Java Debug immer der Fehler, dass er mein Externes Programm S_TESTDP nicht gefunden hat.

Hintergrund: Ich versuche anhand von 4 numerischen Werten einen Text zurückzubekommen:

Procedure;
getObjektBez B Export
getObjektBez PI
p#firma 2 0
p#obj 7 0
p#objA 1 0
p#objG 1 0
p#obbzg 28

Local fields

Eval k#firma = p#firma
Eval k#obj = p#obj
Eval k#objA = p#objA
Eval k#objG = p#objG

ListObstdp Chain(N) OBSTDP
If not %found(Obstdp)
eval p#obbzg = *blanks
Else
eval p#obbzg = %trim(Obbzg)
Endif
getObjektBez E

Hier die Stored Procedure , die ich erstellt habe:

CREATE PROCEDURE STAMOBJ.SP_GETOBJ (
IN FIRMA DECIMAL(2, 0) ,
IN OBJEKT DECIMAL(7, 0) ,
IN OBJEKTART DECIMAL(1, 0) ,
IN OBJEKTGESHH DECIMAL(1, 0) ,
OUT OBJEKTBEZ CHAR(28) )
LANGUAGE RPGLE
SPECIFIC STAMOBJ.SP_GETOBJ
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
EXTERNAL NAME 'STAMOBJ/S_TESTDP(getobjektbez)'
PARAMETER STYLE GENERAL ;

COMMENT ON SPECIFIC PROCEDURE STAMOBJ.SP_GETOBJ
IS 'Objektbezeichnung aus OBSTDP' ;


Java PGM Aufruf

public void sucheObjektAdresse4() throws ClassNotFoundException, SQLException {


// Connection Variables
String AS400_ADDRESS = "xxx";
String AS400_USERNAME = "xxx";
String AS400_PASSWORD = "xxx";
String AS400_LIBRARY = "STAMOBJ";


START: Connection Block
Class.forName("com.ibm.as400.access.AS400JDBCDriver");

try {
the400 = DriverManager.getConnection("jdbc:as400://" + AS400_ADDRESS + "/" + AS400_LIBRARY, AS400_USERNAME, AS400_PASSWORD);
System.out.println("Connection successful!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// END: Connection Block

try{

// START: Call the Stored Procedure

CallableStatement cstmt = the400.prepareCall("{CALL " + AS400_LIBRARY + ".SP_GETOBJ(?, ?, ?, ?, ?)}",
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

System.out.println(cstmt.toString());

*** Hier steht dann STMT0001, statt der Aufruf ***

// set inputs
cstmt.setDouble(1, 01); // firma
cstmt.setDouble(2, 2215); // objekt
cstmt.setDouble(3, 1); // objektArt
cstmt.setDouble(4, 1); // objektGeshh


// set outputs
cstmt.registerOutParameter(5, java.sql.Types.CHAR); // objektbezeichnung

// execute
ResultSet rs = cstmt.executeQuery();
System.out.println(rs.toString());

*** das executeQuery geht nicht auf ***


// display returned values
System.out.println("\nreturned parameters...");

System.out.println("Objektbezeichnung: " + cstmt.getString(5));

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Es kommt folgende Fehlermeldung:


[SQL0444] Externes Programm S_TESTDP in STAMOBJ nicht gefunden.

Bitte um Eure Hilfe ! :confused::confused::confused::confused::confused: :confused:

Vielen Dank

Fuerchau
08-05-08, 08:50
Das liegt an der Deklaration der Prozedur, die ein *PGM und kein *SRVPGM erwartet.


PROGRAM TYPE MAIN Specifies that the routine executes as the main entry point in a program. The external program must be a *PGM object. PROGRAM TYPE SUB Specifies that the procedure executes as a procedure in a service program. The external program must be a *SRVPGM object.

boonkelz
08-05-08, 09:29
OK Vielen Dank, aber wenn ich das in unserem SQL Tool ausführe:
CREATE PROCEDURE STAMOBJ.SP_GETOBJ (
IN FIRMA DECIMAL(2, 0) ,
IN OBJEKT DECIMAL(7, 0) ,
IN OBJEKTART DECIMAL(1, 0) ,
IN OBJEKTGESHH DECIMAL(1, 0) ,
OUT OBJETKBEZ CHAR(28) )
LANGUAGE RPGLE
SPECIFIC STAMOBJ.SP_GETOBJ
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
PROGRAM TYPE SUB
EXTERNAL NAME 'STAMOBJ/S_TESTDP(getobjektbez)'
PARAMETER STYLE GENERAL


und dann im ISeries Navigator mir die SQL generieren lasse, dann steht wieder nicht diese Anweisung drinnen, oder mache ich etwas falsch ??


-- SQL generieren
-- Version: V5R3M0 040528
-- Generiert am: 08.05.08 10:29:52
-- Relationale Datenbank: S44A0340
-- Standardauswahl: DB2 UDB iSeries

CREATE PROCEDURE STAMOBJ.SP_GETOBJ (
IN FIRMA DECIMAL(2, 0) ,
IN OBJEKT DECIMAL(7, 0) ,
IN OBJEKTART DECIMAL(1, 0) ,
IN OBJEKTGESHH DECIMAL(1, 0) ,
OUT OBJETKBEZ CHAR(28) )
LANGUAGE RPGLE
SPECIFIC STAMOBJ.SP_GETOBJ
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
EXTERNAL NAME 'STAMOBJ/S_TESTDP(getobjektbez)'
PARAMETER STYLE GENERAL ;

:confused::confused::confused::confused::confused: :rolleyes::confused::confused::confused::confused:

Fuerchau
08-05-08, 09:47
Stimmt, wenn man nachliest ist das eh nur Kommentar.
Ich denke es ist der Prozedurname.
Beim Export wird "getObjektBez" angegeben, in der Prozedur aber "getobjektbez", siehst du den Unterschied ?
SRVPGM-Prozeduren sind casesensitive !

boonkelz
08-05-08, 11:45
OK, Zunächst mal, herzlichen Dank für diese tolle Unterstützung hier im Forum ! :D:D:D

Ich habe nun den Namen total groß geschrieben und ich komme zunächst mal, so denke ich, in das ServicePgm rein.

Es kommt aber leider folgender Fehler:

[CEE9901] Anwendungsfehler. RNX1216 nicht überwacht durch S_TESTDP bei Anweisung 0001000001, Instruktion X'0000'

Ich habe gegoogelt und ich fand einen Hinweis bezüglich Activation Groups
und das man *NEW nehmen soll, das geht aber bei CRTSRVPGM nicht.

Oder hat diese Fehlermeldung, garnichts damit zu tun ?
Bitte um neuerliche Hilfe !

Danke
:):):)

Fuerchau
08-05-08, 13:47
Wieder mal ein Definitionsfehler:
p#firma 2 0
p#obj 7 0
p#objA 1 0
p#objG 1 0

Deine Parameter definierst du als Zoned, in der Prozedur als DECIMAL, das ist für RPG Packed, also
p#firma 2p 0
p#obj 7p 0
p#objA 1p 0
p#objG 1p 0

Dann machst du einen Dateizugriff, bist du sicher dass diese auch offen ist ?

Serviceprogramme unterliegen da gewissen Restriktionen.

Ich mache daher immer *PGM-Objekte, da ich dann mittels *INLR besseren Einfluss auf die Performance habe.

Fuerchau
08-05-08, 13:48
Nachtrag:

Nachrichten-ID . . . . . . . : RNX1216
Nachrichtendatei . . . . . . : QRNXMSG
Bibliothek . . . . . . . . : QSYS

Nachricht . . . : Fehlernachricht &5 wurde während &13 für Datei &7
angezeigt.
Ursache . . . . : RPG-Prozedur &1 in Programm &3/&2 hat die Nachricht &5
empfangen, während eine implizite Operation &13 für Datei &7 ausgeführt
wurde. Die tatsächliche Datei ist &8.
Fehlerbeseitigung: Das Jobprotokoll auf eine vollständige Beschreibung von
Nachricht &5 prüfen und den für die Programmpflege verantwortlichen Benutzer
benachrichtigen. Lautet der Eintrag für die Ein-/Ausgabeeinheit für die
Datei SPECIAL, ist unter Umständen keine Nachricht im Jobprotokoll
vorhanden.

boonkelz
09-05-08, 08:22
Guten Morgen

Danke für die Info und ich habe dazu auch gleich 2 Fragen:

1. :cool::cool::cool::cool:
Ich verzweifel langsam aber sicher mit den Parametern:

Ich habe laut Liste
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/sqlp/rbafyppcsp.htm
nun folgendes angegeben und es kommt immer ein Dezimaldatenfehler im Joblog:

Java:

CallableStatement cstmt = the400.prepareCall("{CALL " + AS400_LIBRARY + ".SP_GETOBJ(?, ?, ?, ?, ?)}",
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); BigDecimal firma = new BigDecimal ("01");
BigDecimal objekt = new BigDecimal ("0002215");
BigDecimal objektArt = new BigDecimal ("1");
BigDecimal objektGeshh = new BigDecimal ("1");

// set inputs
cstmt.setBigDecimal(1, firma); // firma
cstmt.setBigDecimal(2, objekt); // objekt
cstmt.setBigDecimal(3, objektArt); // objektArt
cstmt.setBigDecimal(4, objektGeshh); // objektGeshh


// set outputs
cstmt.registerOutParameter(5, java.sql.Types.CHAR); // objektbezeichnung

Stored Procedure:
CREATE PROCEDURE STAMOBJ.SP_GETOBJ (
IN FIRMA NUMERIC(2, 0) ,
IN OBJEKT NUMERIC(7, 0) ,
IN OBJEKTART NUMERIC(1, 0) ,
IN OBJEKTGESHH NUMERIC(1, 0) ,
OUT OBJETKBEZ CHAR(28) )
LANGUAGE RPGLE
SPECIFIC STAMOBJ.SP_GETOBJ
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT
PROGRAM TYPE SUB
EXTERNAL NAME 'STAMOBJ/S_TESTDP(GETOBJEKTBEZ)'
PARAMETER STYLE GENERAL

RPG Prozedur:
getObjektBez B Export
getObjektBez PI
p#firma 2 0
p#obj 7 0
p#objA 1 0
p#objG 1 0
p#obbzg 28

2. :cool::cool::cool::cool:
Die Sache, welche von Dir vorher angesprochen wurde, bezüglich des offenen Dateizugriffes:
Hier kam nämlich zuerst auch ein Fehler
und als ich in die Bilbiotheksliste schaute, die dieser Job gerade offen hatte, war die Bibliothek nicht vorhanden.

Der Job hatte nur Bibliotheken der QSYSLIBL und unsere Daten sind in einer Bilbiothek, die in der QUSRLIBL definiert ist. Kann man hier einfach die Bibliothek der Dateien von der QUSRLIBL in die QSYSLIBL geben, oder gibt es da auch noch eine andere Möglichkeit ?

Vielen Dank im Voraus
:p:p:p:p:p:p:p:p:p

BenderD
09-05-08, 09:23
auf Wunsch des Fragers gelöscht!

boonkelz
09-05-08, 09:42
die libl kann man in den Treiber Properties setzen, aber warum dieser ganze Wackelhaufen mit dem RPG Java Mix??? Das ist aus Java 1 (in Worten eins) SQL Statement!!!

D*B

Treiber Properties: wäre nett, wenn du genau schreibst, wo dies ist.

Wackelhaufen: danke für den tollen Input. Ich habe nicht erst gestern zu programmieren begonnen. Aber ob du es glaubst oder nicht, es gibt Möglichkeiten auch komplexen RPG Code aus Java aufzurufen (diese Strategie soll sogar von sogenannten Profis empfohlen sein). Und diese eine Methode ist einfach ein Test um das ganze anzuleiern.

Ich denke, ein Forum ist dazu da, um Hilfestellung zu bekommen.
Auf Besser-wissende-Antworten kann ich gut und gerne verzichten.

Lg