Unterschied zwischen zwei Daten
-
24-10-2019 - |
Frage
Ich habe eine Tabelle mit den folgenden Daten
fromDate | toDate
20JAN11 | 29DEC30
Beide Daten sind für das 21. Jahrhundert (dh 2011 und 2030), aber nur die letzten beiden Charaktere werden gespeichert.
Warum ist die folgende Aussage (wenn sie innerhalb eines PL/SQL -Moduls ausgeführt wird) gegen die oben genannten Daten zurück, gibt immer einen positiven Wert zurück
dateDifference := (fromDate - toDate)
Wenn ich die folgende Anweisung von SQLPLUS ausführe, erhalte ich den richtigen negativen Wert, der korrekt ist.
select to_date('20JAN11','DDMONYY')-to_Date('29DEC30','DDMONYY') from dual;
Ich erinnere mich, dass ich irgendwo gelesen habe, dass Oracle manchmal das falsche Jahrhundert benutzte, aber ich erinnere mich nicht ganz an das genaue Szenario, in dem das passieren würde.
Lösung
Angenommen, diese Säulen sind von DATE
Datentyp, der anscheinend der Fall zu sein scheint: Oracle speichert immer DATE
Werte in einem internen Format, das das gesamte Jahr umfasst. Die Tatsache, dass Sie nur ein zweistelliges Jahr sehen, hat mit dem Datumsformat zu tun, mit dem das Datum in eine Zeichenfolge für die Anzeige konvertiert wird. Höchstwahrscheinlich sind die gespeicherten Century -Werte nicht das, was Sie glauben.
Versuchen Sie, die Daten mit einem expliziten Format auszuwählen, um zu sehen, was Sie wirklich gespeichert haben:
SELECT TO_CHAR( fromDate, 'DD-MON-YYYY' ), TO_CHAR( toDate, 'DD-MON-YYYY' )
Andere Tipps
Scheint für mich in meiner 10G -Datenbank für mich zu funktionieren:
SQL> set serveroutput on
SQL>
SQL> DECLARE
2 d1 DATE := to_date('20JAN11','DDMONRR');
3 d2 DATE := to_date('29DEC30','DDMONRR');
4 diff INTEGER;
5 BEGIN
6 diff := d1 - d2;
7 dbms_output.put_line(diff);
8 END;
9 /
-7283
PL/SQL procedure successfully completed
SQL>
Bearbeiten: funktioniert auch für YY anstelle des RR -Jahres -Formats.
Edit2: so etwas, meinst du?
SQL> create table t (d1 date, d2 date);
Table created
SQL> insert into t values (to_date('20JAN11','DDMONYY'), to_date('29DEC30','DDMONYY'));
1 row inserted
SQL> commit;
Commit complete
SQL>
SQL> DECLARE
2 R t%ROWTYPE;
3 diff INTEGER;
4 BEGIN
5 SELECT d1, d2
6 INTO R
7 FROM t;
8 diff := R.d1 - R.d2;
9 dbms_output.put_line(diff);
10 END;
11 /
-7283
PL/SQL procedure successfully completed
SQL>
Wie @alex sagt, möchten Sie möglicherweise Ihre Daten überprüfen.
funktioniert auch ohne Formatierung
CREATE TABLE DATETEST(FROMDATE DATE, TODATE DATE);
insert into DATETEST (fromdate,todate) values (to_date('20Jan11','ddMonrr'),to_date('29DEC30','ddMonrr'));
SELECT TO_CHAR(FROMDATE,'ddMonrrrr hh24:mi:ss') FROMDATE,
TO_CHAR(TODATE,'ddMonrrrr hh24:mi:ss') TODATE
from datetest ;
/*
FROMDATE TODATE
------------------ ------------------
20Jan2011 00:00:00 29Dec2030 00:00:00
*/
set serveroutput on
DECLARE
l_FROMDATE DATETEST.FROMDATE%type ;
L_TODATE DATETEST.TODATE%TYPE;
dateDifference number;
BEGIN
--notice -- no formatting just putting them into a variable for test
SELECT FROMDATE, TODATE
INTO L_FROMDATE, L_TODATE
from datetest;
DATEDIFFERENCE := L_FROMDATE - L_TODATE ;
DBMS_OUTPUT.PUT_LINE('DATEDIFFERENCE = ' || DATEDIFFERENCE );
end ;
--DATEDIFFERENCE = -7283
SELECT FROMDATE-TODATE
from datetest ;
/* --still not formatting
FROMDATE-TODATE
----------------------
-7283
*/
SELECT (FROMDATE - TODATE) DATEDIFF,
TO_CHAR(FROMDATE,'ddMonrrrr') FROMDATE,
to_char(todate,'ddMonrrrr') todate
from (
SELECT TO_DATE('20JAN11','DDMONYY') FROMDATE,
TO_DATE('29DEC30','DDMONYY') TODATE
FROM DUAL)
;
/*
DATEDIFF FROMDATE TODATE
---------------------- --------- ---------
-7283 20Jan2011 29Dec2030
*/
Versuchen Sie, die erste Abfrage auf Ihrem Tisch auszuführen:
SELECT TO_CHAR(FROMDATE,'ddMonrrrr hh24:mi:ss') FROMDATE,
TO_CHAR(TODATE,'ddMonrrrr hh24:mi:ss') TODATE
from datetest ;
Sehen Sie, ob die Jahre das sind, was Sie tatsächlich erwarten.
(Bearbeiten: Änderung, um zwei Ziffernjahre zu verwenden)