PDA

View Full Version : DatFmt in UDF



x00
20-11-20, 07:22
Guten Morgen,
in der Firma in der ich aktuell arbeite werden viele Datumsfelder als sammlung von decimals behandelt. Da dadurch häufig eine Konvertierung beim zugriff auf die DB2 notwendig ist habe ich eine UDF geschrieben.



-- Konvertiert 3 Zahlen zu einem Datum
create or replace function dateConverter(day decimal(2, 0), month decimal(2, 0), year decimal(4, 0)) returns date
language sql
fenced
deterministic
returns null on null input
no external action
not secured
set option datFmt = *ISO
begin
declare returnValue date default '1940-01-01';
-- on conversion error
declare continue handler for sqlstate '22007'
return null;

set returnValue = date(digits(year) || '-' || digits(month) || '-' || digits(day));
return returnValue;
end;


Die Funktion arbeitet grundsätzlich korrekt, jedoch ist sie nur in der Lage Daten vom 1940-01-01 - 2039-12-31 umzuwandeln. Nach einiger Recherche habe ich herausgefunden das bei verwendung des ISO-Datumsformat daten zwischen dem 0001-01-01 - 9999-12-31 verwendet werden können. Mein Ansatz war jetzt die sql option datFmt zu setzen. Das Ergebnis ist jedoch nicht zufriedenstellend, da bei enem Datum größer 2039-12-31 immer noch NULL ausgegeben wird. Habe ich etwas vergessen?

Vielen Dank für Ihre Hilfe.
Gruß x00

B.Hauser
20-11-20, 07:55
Die Funktion funktioniert korrekt.
SQL arbeitet bei dem Datum immer mit der Scaliger No (einer internen laufenden Nr.).
Das Datums-Format wird nur zur (lesbaren) Anzeige der Scaliger No verwendet.
Welches Format verwendet wird, hängt von dem Datums-Format, das im Job/Verbindung verwendet wird.

Ich vermute, in deiner Umgebung wird ein Datums-Format mit einem 2-stelligen Jahr verwendet. Ändere das Datums-Format im Job/Verbindung und Du wirst sehen, dass alles korrekt funktioniert.

Wenn Du ++++++++ siehts bedeutet das lediglich, dass das Datum im aktuellen Format nicht angezeigt werden kann.

NULL-Werte werden entweder mit einem - oder null oder überhaupt nicht angezeigt.

Wenn Du Deine UDF debugst wirst Du feststellen, dass bei einem Datum vor 1940 oder nach 2039 der Handler nicht aktiviert wird.

Ich habe eine ähnliche Funktion (außer, dass ich im Fehler-Fall keine NULL-Werte, sonder echte Datums-Werte ausgebe).

589



Birgitta

Fuerchau
20-11-20, 10:19
Wie Birgitta schon ausführte, die SQL-Funktion selber interessiert sich für kein Datumformat, da der Inhalt immer vom Typ DATE ist.
Entscheidend ist hier das Datumformat deiner Programme!

Wenn du in RPGLE als DATFMT kein EUR oder ISO verwendest sondern normal YMD oder DMY, kann dein RPG nur den eingeschränkten Datenbereich.
Der Fehler passier dann nicht unbeding im SQL-Bereich.

Es nützt also nichts, wenn du per "set option datfmt=*ISO" verwendest, dein RPG aber nur mit 6-stelligem Datum arbeitet. Die SQL-Variablen werden korrekt definiert (10-stellig), allerdings wird vom Precompiler ja eine Zuweisung "MyRpgDate = SQLnnnn;" generiert und da bekommst du dann einen Fehler.

Du kannst es ganz einfach auch mit STRSQL ausprobieren.
Setze per F13 ein Format wie DMY dann siehst die die Ausgabe als ++++++.
Setze *ISO oder *EUR dann kommt das Format korrekt.