Anmelden

View Full Version : RPG Programm per UDF aufrufen mit Rückgabewert



RegFor
23-02-18, 14:14
Hallo miteinander,
ich bin neu hier und auch mehr als unerfahren mit ISeries. Ich greife im Regelfall per ODBC auf die Datenbanken und Tabellen der ISeries zu.
Für Preisermittlungen müsste ich jetzt auf ein Programm der ISeries zugreifen und die entsprechenden Rückgabe-Werte verarbeiten. Hab mich mit Google unterhalten und mal folgende Funktion geschrieben

CREATE FUNCTION PLAQUEPRIZES
( PARAM CHAR(163) )
RETURNS CHAR(163)
LANGUAGE RPGLE
EXTERNAL NAME 'ASTROFREMD/KSR100'
DETERMINISTIC
NO SQL
NO EXTERNAL ACTION
ALLOW PARALLEL
NOT FENCED

Im Programm KSR100 ist ein Parameter YPKSR100 mit 163 Zeichen definiert. Dieser Parameter ist auch der Rückgabeparameter.

Create Function hat soweit funktioniert, auch SQL mit ' SELECT .. , PLAQUEPRIZES( ) (mit einem Wert von exakt 163 Zeichen) FROM .... ' wird ausgeführt, aber ich erhalte keine Rückgabewerte.

Was mache ich falsch ? Was sollte ich noch prüfen ?

Dankeschön im voraus für die Unterstützung!

Fuerchau
23-02-18, 16:06
Schau noch mal nach Parameter Style General, da sonst noch erheblich mehr Parameter übergeben werden (Default ist glaube ich SQL).

Und auch sonst sind Parameter und Returnwert bei UDF eigenständige Parameter, zuerst alle Eingangsparameter anschließend der Returnwert.

andreaspr@aon.at
23-02-18, 16:23
Wenn das Ergebnis über den Parameter zurück geliefert werden soll, dann benötigst du hier eine SQL Prozedur und keine Funktion.
CREATE PROCEDURE ...

lg Andreas

Fuerchau
23-02-18, 19:45
Wobei eine Prozedur a) anders aufgerufen wird und b) nicht im Select (wie oben) funktioniert.

B.Hauser
25-02-18, 11:56
UDFs können keine Ein/Ausgabe Parameter handeln, sondern nur Eingabe-Parameter. Das Ergebnis wird immer über dien Rückgabe-Wert ausgegeben.
Du musst also Dein Programm so modifizieren, dass es der erwarteten Struktur entspricht.

Am einfachsten ist es Du wrappst Dein Original-Programm,
d.h. Du generierst eine RPG-Funktion (in einem Service-Programm), in der Dein eigentliches RPG-Programm aufgerufen wird. Die Funktion gibt dann das Ergebnis bzw. Deinen Ein/Ausgabe-Parameter über RETURN aus.

Diese Funktion wird dann im CREATE FUNCTION angegeben.

Etwa so:

Ctl-Opt NoMain;

DCL-Proc YourFunction Export;
DCL-PI *N Char(163);
YourPar Char(163);
End-PI;
CallP YourPGM(YourPar);
Return YourPar;
End-Proc;


Ich meine es wäre auch möglich ein Programm zu generieren mit 2 Parametern, der erste ist Dein normaler Ein/Ausgabe-Parameter und der zweite ist der Ausgabe-Parameter.
Dieses Programm ruft dann Dein Original-Programm auf.
Diese Klimmzüge musste man machen, bevor man Funktionen handeln konnte (also schon Jahrhunderte zurück und seither habe ich es nicht mehr probiert).
Die bessere Lösung ist allerdings eine zusätzliche Funktion.

Was den Parameter Style angeht:
Bei GENERAL werden nur die Parameter übergeben, die auch im RPG definiert sind.
Bei allen anderen Styles noch einige Parameter mehr. Das ist kein Problem, solange diese Parameter im RPG-Programm nicht angesprochen werden.
(Wie früher bei Entry-PLISTs, da was es auch kein Problem, wenn nicht alle Parameter übergeben wurden, solange die Parameter, die nicht übergeben wurden, nicht angesprochen wurden)

RegFor
26-02-18, 13:04
Erst mal dankeschön für die vielen Antworten.

Ich habe mich heute entsprechend Ihren Antworten noch mal mit Google unterhalten und auch das RED BOOK von IBM runtergeladen. Ich denke, eine STORED PROCEDURE wäre dann doch eher der richtige Weg, wenn ich mir das alles mal so zu Gemüte führe. Also habe ich das Ganze in eine stored procedure übertragen, hab das der Sicherheit und Einfachheit halber auch mit ISeries Navigator durchgeführt.

Ergebnis ist dann folgendes

CREATE PROCEDURE ASTRD.PRIZESPLAQ (
IN PLSIZE CHAR(163),
OUT PRIZES CHAR(163)
)
DYNAMIC RESULT SETS 1
LANGUAGE RPGLE
SPECIFIC ASTRD.PRIZESPLAQ
DETERMINISTIC
NO SQL
CALLED ON NULL INPUT
EXTERNAL NAME 'ASTROFREMD/KSR100'
PARAMETER STYLE SQL

Aufruf dann wie folgt:

CALL ASTRD.PRIZESPLAQ(Wert für 1.Parameter (exakt 163 Zeichen), '?')
oder mit 2. Parameter explicit als CAST
CALL ASTRD.PRIZESPLAQ(Wert für 1.Parameter (exakt 163 Zeichen), CAST ('?' as CHAR(163) ) )

Fehlermeldung:
Attribut IN, OUT oder INOUT für Parameter 2 in Prozedur PRIZESPLAQ ungültig

Ich hab das auch schon mit nur einem Parameter (INOUT) probiert, da erhalte ich dann die gleiche Fehlermeldung für diesen Parameter 1.

Syntax müsste eigentlich passen.
Was mache ich hier jetzt wieder falsch ?

B.Hauser
26-02-18, 13:34
Du solltest den 1. Parameter explizit auf CHAR(163) casten und bei dem 2. Parameter nur das Fragezeichen ohne die Hochkommata angeben.
Mach sicherheitshalber noch ein Blank vor dem Komma.

Birgitta

RegFor
27-02-18, 09:04
Hallo und dankeschön für die Unterstützung.

Habe mich jetzt gestern und heute nochmal intensiv mit den STORED PROCEDURE auseinander gesetzt.
Da ich über PHP und ODBC zugreife, rufe ich jetzt die STORED PROCEDURE über PDO auf.

Wie hier im Manual PHP beschrieben: http://php.net/manual/de/intro.pdo.php

Nach einigen Versuchen hat dann auch alles wie gewünscht funktioniert.

Dankeschön nochmals für die Unterstützung.