Domanda

Ho una tabella che ha i seguenti dati

fromDate | toDate
20JAN11  | 29DEC30
sono

Entrambe le date per il 21 ° secolo (vale a dire il 2011 e il 2030), ma solo gli ultimi due caratteri sono memorizzati.

Perché è la seguente dichiarazione (quando eseguito dall'interno di un PL / SQL modulo) contro i dati di cui sopra restituisce sempre un valore positivo

dateDifference := (fromDate - toDate)

Se faccio funzionare la seguente dichiarazione del sqlplus ottengo il valore negativo corretto che è corretto.

select to_date('20JAN11','DDMONYY')-to_Date('29DEC30','DDMONYY') from dual;

Ricordo di aver letto da qualche parte che Oracle avrebbe a volte utilizzare il secolo sbagliato, ma io non ricordo bene lo scenario esatto in cui che sarebbe accaduto.

È stato utile?

Soluzione

Assuming those columns are of DATE datatype, which seems to be the case: Oracle always stores DATE values in an internal format which includes the full year. The fact that you are seeing only a 2-digit year has to do with the date format used to convert the date to a string for display. So most likely the stored century values are not what you think they are.

Try selecting the dates with an explicit format to see what you really have stored:

SELECT TO_CHAR( fromDate, 'DD-MON-YYYY' ), TO_CHAR( toDate, 'DD-MON-YYYY' )

Altri suggerimenti

Seems to work for me either way on my 10g database:

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> 

EDIT: works for YY instead of RR year format as well.

EDIT2: Something like this, you mean?

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> 

As @Alex states, you may want to verify your data.

works without formatting as well

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 

*/

try running the first query on your table:

SELECT TO_CHAR(FROMDATE,'ddMonrrrr hh24:mi:ss') FROMDATE, 
       TO_CHAR(TODATE,'ddMonrrrr hh24:mi:ss') TODATE
  from datetest ;

see if the years are what you actually expect.

(Edit: changed to use two digit years)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top