0

次のデータを持つテーブルがあります

fromDate | toDate
20JAN11  | 29DEC30

どちらの日付も 21 世紀 (つまり 2011 年と 2030 年) のものですが、最後の 2 文字だけが保存されます。

上記のデータに対して次のステートメントを (PL/SQL モジュール内から実行すると) 常に正の値が返されるのはなぜですか?

dateDifference := (fromDate - toDate)

sqlplus から次のステートメントを実行すると、正しい負の値が得られます。

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

オラクルが時々間違った世紀を使用することをどこかで読んだことを覚えていますが、それが起こる正確なシナリオはよく覚えていません。

4

3 に答える 3

4

これらの列がDATEデータ型であると仮定すると、これが当てはまるようです。Oracleは常にDATE、通年を含む内部形式で値を格納します。2桁の年しか表示されていないという事実は、日付を表示用の文字列に変換するために使用される日付形式と関係があります。したがって、保存されている世紀の値は、あなたが思っているものではない可能性があります。

明示的な形式で日付を選択して、実際に保存したものを確認してください。

SELECT TO_CHAR( fromDate, 'DD-MON-YYYY' ), TO_CHAR( toDate, 'DD-MON-YYYY' )
于 2011-01-24T18:14:44.047 に答える
2

フォーマットなしでも機能します

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 

*/

テーブルで最初のクエリを実行してみてください。

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

年が実際に期待するものであるかどうかを確認してください。

(編集:2桁の年を使用するように変更)

于 2011-01-24T17:47:33.360 に答える
2

私の10gデータベースではどちらの方法でもうまくいくようです:

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> 

編集: RR 年形式の代わりに YY でも機能します。

EDIT2:このようなものですか?

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> 

@Alexが述べているように、データを確認したい場合があります。

于 2011-01-24T17:39:09.180 に答える