PDA

View Full Version : SQL UDF mit RPGLE Programm



mk
16-06-10, 14:50
Hallo zusammen,

ich suche schon länger, habe aber auch im Inet nicht so das Richtige gefunden.

Was ich machen möchte:
Eine UDF die mir Kosten für einen Artikel zurückgibt.

Folgendes vorhandenes Serviceprogramm

PGet_HangTag_Cst B export
DGet_HangTag_Cst PI 7s 2
dSaison like(stssea) const
dSaisonYear like(styear) const
dDivision like(stdiv) const
dStyle like(ststyl) const
dToCurrency 3 const

.....


C RETURN Ht_Cost_All
PGet_HangTag_Cst E


Dafür habe ich folgende UDF erstellt


create function mk/htcost
(Saison char (1 ) , Saisonyear dec (4, 0),
Division dec( 2, 0), Style char(6),
Currency char(3) )
returns dec(7, 2)
language rpgle
deterministic
no sql
returns null on null input
no external action allow parallel
simple call
external name 'TSTLIBEDC/BY100SR(Get_HangTag_Cst)'


Der Aufruf erfolgt folgendermassen:

select stssea, styear, stdiv, ststyl,
htcost(stssea, styear, stdiv, ststyl , 'EUR' ) as cost
from tstdtaedc/stmastp
where styear=2008


Folgende Fragen:
1.
Wie kann man eine Konstante- und Variable definieren
( wie hier im Beispiel Konstante EUR )
mit VARCHAR in der Function funktioniert es auch nicht

2. Wie bekommt man das Ergebnis aus dem Return Ht_Cost_All
zurück


Z.Zt. bin ich irgendwie ein bischen Ratlos
Gruß
Michael

andreaspr@aon.at
16-06-10, 15:25
Hi,
was genau ist denn das Problem? Lässt es sich nicht kompelieren, oder aufrufen? Gibt es eine Fehlermeldung? ...
Ich hab mir angewöhnt grundsätzlich immer VARCHAR zu verwenden, da mit CHAR der Aufruf oft nicht funktioniert (keine Ahnung warum).

mk
16-06-10, 15:36
HI Andreas,

also erstens muss ich klären wie man eine Konstante
über die UDF an das Serviceprogramm übergeben kann.

Wenn ich statt der Konstante eine Variable übergebe
wird zwar die Prozedur im Serviceprogramm aufgerufen
aber mit Fehler beendet:

Nachrichten-ID . . . . : MCH3601 Bewertung . . . . . . : 40
Nachrichtenart . . . . : Abbruch
Sendedatum . . . . . . : 16.06.10 Sendezeit . . . . . . : 16:34:36

Nachricht . . . : Zeiger für angegebene Position nicht gesetzt.
Ursache . . . . : Es wurde ein Zeiger, entweder direkt oder als ein
Basiszeiger verwendet, für den keine Adresse festgelegt worden war.


Nachrichten-ID . . . . : CPF503E Bewertung . . . . . . : 30
Nachrichtenart . . . . : Hinweis
Sendedatum . . . . . . : 16.06.10 Sendezeit . . . . . . : 16:34:36

Nachricht . . . : Fehler bei benutzerdefinierter Funktion in Teildatei
STMASTP.
Ursache . . . . : Beim Aufrufen der benutzerdefinierten Funktion HTCOST in
Bibliothek MK ist ein Fehler aufgetreten. Der Fehler trat beim Aufrufen des
zugeordneten externen Programms oder Serviceprogramms BY100SR in Bibliothek
TSTLIBEDC, Programmeingangspunkt bzw. externem Namen Get_HangTag_Cst,
spezieller Name HTCOST, auf. Der Fehler trat bei Teildatei STMASTP Datei
STMASTP in Bibliothek TSTDTAEDC auf. Der Fehlercode ist 2. Fehlercodes und
ihre Bedeutung:
1 -- Das externe Programm oder Serviceprogramm hat SQLSTATE 00000
zurückgegeben. Die vom Programm zurückgegebene Textnachricht ist: .
2 -- Das externe Programm ist vor seiner Beendigung fehlgeschlagen.
3 -- Bei der Datenbank trat ein Zeitüberschreitungsfehler beim Warten auf
die Rückkehr zum Hauptprogramm auf. Der von der Datenbank verwendete
Zeitüberschreitungswert betrug 0 Minuten und 30 Sekunden.
4 -- Das externe Programm ist nicht mehr vorhanden oder wurde nicht
gefunden.
5 -- Bei einem der Eingabeparameter der Funktion ist ein
Datenabgleichungsfehler aufgetreten.
6 bis 20 -- Die vorangegangenen Nachrichten im Jobprotokoll beachten.
Für ein externes Programm ist der angezeigte Programmeingangspunkt *N.
ehlerbeseitigung: Bei Fehlercodes 1 und 2 die Fehlerursache anhand von
SQLSTATE oder einer zuvor aufgelisteten Nachricht feststellen.
Bei Fehlercode 3 entweder den Zeitüberschreitungswert mit Hilfe der
QAQQINI-Dateieinstellung erhöhen oder feststellen, weshalb das externe
Programm oder das Serviceprogramm nicht innerhalb der zugeordneten Zeit
zurückgekehrt ist.
Bei Fehlercode 4 sicherstellen, dass das Programm oder Serviceprogramm für
die Dauer der Abfrage vorhanden ist.
Bei Fehlercode 5 die Ursache für den Datenabgleichungsfehler bestimmen.
Bei Fehlercode 6 bis 22 die vorangegangenen Nachrichten im Jobprotokoll
beachten.
Weitere Informationen über benutzerdefinierte Funktionen enthält das Thema
"DB2 UDB for iSeries SQL Programming" im Information Center unter
http://www.ibm.com/eserver/iseries/infocenter.

Also stimmt etwas mit der Übergabe der Parameter noch nicht.

Im Debugger kommen bis auf die Currency alle Werte an.

Gruß
Michael

Fuerchau
16-06-10, 15:40
Das Problem ist, dass die Prozedur nicht richtig definiert ist.
Im Gegensatz zu ILERPG ruft SQL die Prozedur mit allen Feldern als Parameter auf, auch den Returnwert als letzten.
Einen Funktions-Returnwert kennt SQL nicht.

Du musst also auch den Returnwert als Übergabeparameter verwenden.

mk
16-06-10, 15:56
Hi Baldur,

aber wo ?

Am Anfang
oder am Ende der Definition.

Irgendwie ist es nicht meine Woche


Gruß
Michael

B.Hauser
16-06-10, 16:21
Um eine Konstante als CHAR zu übergeben musst Du sie beim Aufruf einfach casten:


Select ...
htcost(stssea, styear, stdiv, ststyl , Cast('EUR' as Char(3))
.....

Beim Registrieren sollte der Funktions-Name im External Name in Groß-Schrift angegeben werden.
Weiterhin ändere ALLOW PARALELL in DISALLOW PARALELL und gib außerdem noch FENCED an. Beides sollte verhindern, dass die Funktion in einem anderen Thread läuft.

@Baldur:
Das war vielleicht früher so und ist noch so, wenn man RPG Programme als UDF registrieren will. Eine RPG-Funktion kann so wie sie ist registriert werden und bei Parameter Style GENERAL (oder SIMPLE CALL) werden nur die in RPG definierten Parameter übergeben (allerdings alle, auch für die optionalen Paramter werden Null-Pointer übergeben).

Birgitta

mk
21-06-10, 11:42
Hallo,

entschuldigung für die späte Rückinfo. Hatte aber erst heute
wieder Gelegenheit mich damit zu beschäftigen.

Und hier die Lösung:

CREATE FUNCTION MK/HTCOST (
SAISON CHAR(1) ,
AYEAR DECIMAL(4, 0) ,
DIVISION DECIMAL(2, 0) ,
STYLE CHAR(6) ,
CURRENCY CHAR(3) )
RETURNS NUMERIC(7, 2) CAST FROM NUMERIC(7, 2)
LANGUAGE RPGLE
SPECIFIC MK/HTCOST
NOT DETERMINISTIC
NO SQL
CALLED ON NULL INPUT
DISALLOW PARALLEL
EXTERNAL NAME 'TSTLIBEDC/BY100SR(Get_HangTag_Cst)'
PARAMETER STYLE DB2SQL

Der OpsNav eignet sich sehr gut zur Anlage.

Vielen Dank an alle
Gruß
Michael