PDA

View Full Version : jjjj + mm +tt mit sql 5 tage drauf



Seiten : 1 [2]

Fuerchau
02-08-12, 11:06
Nun ja, dann nimm ein anderes Jahr und rechne dieses wieder runter:

date('1900-01-01') + (case JJJJ when 0 then 0 else -1900 end) years + (MM - 1) months + (TT - 1) days

Ob das dann ein sinnvolles Datum ist :)...

ILEMax
02-08-12, 11:07
knallt auch ....


SELECT dec(coalesce(replace(char( date('0001-01-01') +
(dec(digits(jjjj), 4, 0)-1) years +
(dec(digits(mm), 2, 0)-1) month +
(dec(digits(tt), 2, 0)-1) days - 5 days, iso
), '-', ''), 0), 8, 0) AS DATUM, jjjj*10000+mm*100+tt from datei

Fuerchau
02-08-12, 11:16
Da machst du doch einiges zu viel.
Die Felder JJJJ, MM, TT sind doch numerisch!!!
Was soll das Casten auf Char und DEC?
Und coalesce hilft dir da nicht, da die Berechnung nicht NULL ergibt sondern einen Fehler.

Versuch es doch mal mit meinem Bespiel.

Fuerchau
02-08-12, 11:25
Ich hatte mir da mal was gebastelt:

<code>
CREATE FUNCTION USMOD_16/DATESERIAL
(YEAR INTEGER,
MONTH INTEGER,
DAY INTEGER)
RETURNS DATE
LANGUAGE RPGLE
EXTERNAL NAME 'USMOD_16/DATSER'
DETERMINISTIC
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
PARAMETER STYLE SQL
ALLOW PARALLEL
NOT FENCED

hactgrp(*caller) dftactgrp(*no) datfmt(*iso)

d SYear s 10I 0
d SMonth s 10I 0
d SDay s 10I 0

d SQLDate s d
d SYear_Ind s 5I 0
d SMonth_Ind s 5I 0
d SDay_Ind s 5I 0

d SQLDate_Ind s 5I 0
d SQLState s 5
d FuncName s 139 varying
d SpecName s 128 varying
d DiagMsg s 70 varying

c *entry plist
c parm SYear
c parm SMonth
c parm SDay
c parm SQLDate
c parm SYear_Ind
c parm SMonth_Ind
c parm SDay_Ind
c parm SQLDate_Ind
c parm SQLState
c parm FuncName
c parm SpecName
c parm DiagMsg
c*
c/free
if SYear_ind <> *zero
or SMonth_ind <> *zero
or SDay_ind <> *zero;
SQLDate_ind = -1; // Ergebnis ist NULL
else;
monitor;
SQLDate = %date('0001-01-01')
+ %Years(SYear-1)
+ %Months(SMonth-1)
+ %Days(SDay-1);
on-error *all;
SQLDate_ind = -1; // Ergebnis ist NULL
endmon;
endif;
/end-free
c*
c return
</code>

Man kann das auch alles native in einer SQL-Prozedur kodieren.

Der Aufruf erfolgt dann in SQL so:

dateserial(JJJJ, MM, TT + n)

Bei Fehlern wird halt NULL geliefert.
Kleine Schmankerln:

1. des Monats: dateseriel(JJJJ, MM, 1)
Letzter des Monats: dateseriel(JJJJ, MM+1, 0)

ILEMax
02-08-12, 11:26
ja, danke
da war wohl was mit dem Wald und den Bäumen ...

habe dein

date('1900-01-01') + (case JJJJ when 0 then 0 else -1900 end) years + (MM - 1) months + (TT - 1) days

in
date('1900-01-01') + (case JJJJ when 0 then 0 else jjjj-1900 end) years + (MM - 1) months + (TT - 1) days

geändert, dann geht es

nicht schön, aber selten ...

Danke
der ILEMax

Fuerchau
02-08-12, 11:28
Gegen Tippfehler ist ja niemand gefeit :).
Und was das selten angeht: wenn mans braucht ?