Anmelden

View Full Version : UDF nicht verwendbar



Peder
05-12-06, 17:57
Hallo

ich habe das Problem, dass eine von mir definierte UDF in der Verwendung nicht funktioniert. Dies sowohl bei einer SQL-UDF wie auch bei einer Externen UDF. Die UDF ist Scalar, und soll aus einer Allgemeinen Tabelle unserer Anwendung den Übersetzungstext eines Tabellenwertes zurückgeben.

Hier die SQL-Anweisung für die Funktionsregistrierung:

Create Function cmxtblobj/S_TBLREAD
(FIR CHAR(3), SAR CHAR(3), RKEY CHAR(10))
Returns CHAR(64)
LANGUAGE SQL
READS SQL DATA
NO EXTERNAL ACTION
DETERMINISTIc
Begin
Declare inhalt char(64);
Set inhalt =(select tblinh from tbl01p where tblanw = 'CMX' and
tblfir = fir and tblsar = sar and tblspr = ' ' and tblkey = rkey);
Return inhalt;

In dieser Anweisung will ich Beispielsweise die UDF verwenden:

SELECT asabtei, S_TBLREAD((asfirma), ('ABT'), (ASABTEI)) FROM
cartalgp

Ich bekomme dann immer den Fehler SQL0204-S_TBLREAD der Art *N in *LIBL nicht gefunden.

Eine Analoge RPG-Prozedur, (als SRVPGM mit korr. Exportsignatur) und als ext. Funktion registriert führt zum gleichen Ergebnis.

Vielleicht habt ihr ja einen Tip
Vielen Dank

B.Hauser
05-12-06, 19:31
Hallo Peder,

das Problem ist der zweite Parameter, den Du als Ausdruck ('ABT') über gibst.

SQL interpretiert Ausdrücke als Datentyp VARCHAR(). Dein Parameter ist jedoch als CHAR() definiert. VARCHAR() und CHAR() sind für SQL unterschiedliche Datentypen.

SQL UDFs können überladen werden können, d.h. in der gleichen Bibliothek kann eine UDF mit dem gleichen Namen, jedoch unterschiedlichen Parametern (Anzahl und/oder Datentyp, jedoch unabhängig von Längenangaben) vorhanden sein. In Deinem Beispiel wird nach einer Funktion mit Namen S_TBLREAD gesucht, deren zweiter Parameter vom Typ VARCHAR() ist. Diese Funktion exisitiert jedoch nicht, wie die SQL-Nachricht mitteilt.

Um dieses Problem zu umgehen, muss der Ausdruck ('ABT') in den Datentyp CHAR() konvertiert (neuhochdeutsch gecasted) werden.


SELECT asabtei,
S_TBLREAD(asfirma,
Cast('ABT' as Char(3)),
ASABTEI)
FROM cartalgp


Birgitta

Peder
06-12-06, 07:06
Hallo Birgitta

viele Dank für deine schnelle Antwort. Die UDF funktioniert jetzt. Ich habe den Parameter als VARCHAR definiert, da der Cast in der Anwendung etwas umständlich ist.

Peder

Peder
06-12-06, 08:15
Hallo

eine Frage habe ich noch zum gleichen Thema. Die gleiche Funktion als Externe UDF scheitert auch bei der Übergabe des 2. Parameters. Im Debug, sehe ich, dass die Parameter 1 und 3 korrekt sind, der 2. enthält einen falschen Wert.

Hier die Definition der Funktion:
Create Function cmxtblobj/S_R_TBL
(FIR CHAR(3), SAR VARCHAR(3), RKEY CHAR(10))
Returns CHAR(64)
Language RPGLE
Specific S_R_TBL
Not Deterministic
No SQL
DisAllow Parallel
External Name 'CMXTBLOBJ/TBLPROT(S_R_TBL)'
Parameter Style SQL

und hier die Defintion der Paramter in der Prozedur:

d s_r_tbl pr like($t2inh)
d pr$fir like($t2fir)
d pr$infa like($t2sar)
d pr$key like($t2key)
**
p s_r_tbl b export
d s_r_tbl pi like($t2inh)
d pr$fir like($t2fir)
d pr$infa like($t2sar)
d pr$key like($t2key)
d pr$out s like($t2inh)


Die Like's verweisen alle auf entsprechende Char-Felder.

Vielen Dank
Peder

B.Hauser
06-12-06, 08:15
Hallo Peder,

anstatt die Funktion zu ändern hättes Du eine weitere Funktion generieren können, die auf der ersten Funktion basiert und nur mit abweichenden Parametern definiert ist. (Sourced Function)

Bei sourced Function wird nichts anderes gemacht, als die Parameter gecasted und anschließend die Basis-Funktion aufgerufen.

Damit wird die Funktion überladen und kann sowohl mit CHAR als auch VARCHAR-Datentyp für den 2. Parameter aufgerufen werden.



Create Function cmxtblobj/S_TBLREAD
(FIR CHAR(3), SAR VARCHAR(3), RKEY CHAR(10))
Returns CHAR(64)
Specific cmxtblobj/S_TBLREAD1
Source Specific cmxtblobj/S_TBLREAD;


Das Problem mit der externen Funktion liegt darin, dass VARCHAR empfangen wird, RPG jedoch CHAR erwartet. Ich denke auch hier kann eine Sourced Function weiterhelfen.

Birgitta