PDA

View Full Version : Fehler bei SQL-Funktion



KM
24-05-18, 13:16
Hallo,

ich stehe bei einer SQL-Funktion vor einem Rätsel. Die Funktion GETFIRMENSPRACHE sieht folgendermaßen aus:


CREATE OR REPLACE FUNCTION DTOBJ/GETFIRMENSPRACHE(
P_FINR DECIMAL(2, 0) )
RETURNS VARCHAR(1)
LANGUAGE SQL
SPECIFIC DTOBJ/GETFIRMENSPRACHE
NOT DETERMINISTIC
READS SQL DATA
CALLED ON NULL INPUT

BEGIN
--‚Variablen
DECLARE SPRACHE VARCHAR(1) DEFAULT '';

--‚Firmensprache ermitteln
SELECT FIPSPR
INTO SPRACHE
FROM FIRMSTAM
WHERE FIFINR = P_FINR;

RETURN SPRACHE;
END;

Als Parameter wird also die Firmennummer 2-stellig numerisch übergeben.
Das merkwürdige ist jetzt, dass die Funktion bei manchen Leuten ganz normal funktioniert und somit die jeweilige Firmensprache zurückgibt.

Bei manchen Leuten tritt aber folgender Fehler auf:


Nachrichten-ID . . . . : CPD439C Bewertung . . . . . . : 40
Nachrichtenart . . . . : Diagnose
Sendedatum . . . . . . : 24.05.18 Sendezeit . . . . . . : 14:08:25

Nachricht . . . : Funktion GETFIRMENSPRACHE in Bibliothek *N nicht gefunden.
Ursache . . . . : Funktion GETFIRMENSPRACHE wurde bei der Funktionsauflösung
aufgrund von Ursachencode 3 nicht gefunden. Die Ursachencodes haben folgende
Bedeutung:
1 -- Es wurde keine Funktion mit dem angegebenen Namen gefunden.
2 -- Es wurde eine Funktion mit dem angegebenen Namen in der Bibliothek
 gefunden, für die jedoch eine andere Anzahl an Parametern als die
angegebene erforderlich ist.
3 -- Es wurde eine Funktion mit dem angegebenen Namen und der angegebenen
Anzahl an Parametern in der Bibliothek  gefunden, aber Parameter 1
hatte eine Datenart, die nicht auf die Datenart des für die Funktion
definierten Parameters hochgestuft werden kann.

Kann mir jemand sagen wo hier das Problem liegt?

Danke,
KM

Fuerchau
24-05-18, 13:20
Wie die Fehlermeldung schon sagt:
Der Parameter ist vom Typ Decimal(2, 0), also musst du auch genau dieses so übergeben.
Ein
GETFIRMENSPRACHE(1)

übergibt als Wert einen Integer und das passt leider nicht.

KM
24-05-18, 13:29
Doch, natürlich geht das. Ich kann Integer oder sogar Dezimalstellen übergeben. Der Parameter scheint dann intern entsprechend gecastet zu werden. Folgende Aufrufe funktionieren bei mir und liefern das korrekte Ergebnis:

getfirmensprache(17,2345)
getfirmensprache(int(17))

Nur bei anderen Benutzern funktioniert das nicht. Und ich weiß nicht warum. Und vor allem was bedeutet folgender Satz genau?

3 -- Es wurde eine Funktion mit dem angegebenen Namen und der angegebenen
Anzahl an Parametern in der Bibliothek  gefunden, aber Parameter 1
hatte eine Datenart, die nicht auf die Datenart des für die Funktion
definierten Parameters hochgestuft werden kann.

Pikachu
24-05-18, 13:46
Hast du ein Beispiel eines Aufrufs, der nicht geht?

AS/400 SQL user-defined functions (UDF) concepts (https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/sqlp/rbafyudfduvc.htm)

Overloaded function names

Function names can be overloaded. Overloaded means that multiple functions, even in the same schema, can have the same name. Two functions cannot, however, have the same signature. A function signature is the qualified function name and the data types of all the function parameters in the order in that they are defined.

Function resolution

It is the function resolution algorithm that takes into account the facts of overloading and function path to choose the best fit for every function reference, whether it is a qualified or an unqualified reference. All functions, even built-in functions, are processed through the function selection algorithm. The function resolution algorithm does not take into account the type of a function. So a table function may be resolved to as the best fit function, even though the usage of the reference requires an scalar function, or vice versa.

Fuerchau
24-05-18, 14:02
Dann must du genau gucken, der Autocast klappt nicht. Das kann bei embedded SQL schon mal eher passieren.

hatte eine Datenart, die nicht auf die Datenart des für die Funktion
definierten Parameters hochgestuft werden kann

KM
24-05-18, 14:37
Ich hab jetzt die UDF mal gelöscht mit "drop function" und danach nochmal neu erstellt. Damit scheint das Problem nun behoben zu sein. Ein "create or replace function" hatte nicht geholfen.

Trotzdem verstehe ich nicht warum die UDF bei manchen Leuten funktioniert hat und bei manchen nicht.

Gruß,
KM