Oracle時間型別資料為0的Bug

2021-05-09 23:43:43 字數 3037 閱讀 2883

開發組在資料遷移時,報告發現一些數值為'0000/00/00'的date資料,導致資料遷移失敗。

這個問題有點奇怪,因為在oracle

中,date型別的資料的取值範圍是從-4712/12/31到9999/12/31之間,並且年份不能為0。也就是說

'0000/00/00'

是乙個非法資料,不為oracle

所接受。

sql> select to_date('0000-00-00', 'yyyy-mm-dd') from dual;

select to_date('0000-00-00', 'yyyy-mm-dd') from dual

ora-01843: not a valid month

sql> select to_date('0000-01-01', 'yyyy-mm-dd') from dual;

select to_date('0000-01-01', 'yyyy-mm-dd') from dual

ora-01841: (full) year must be between -4713 and +9999, and not be 0

但為什麼在資料中還是出現了'0000/00/00'呢?對此問題稍微研究了一下,發現oracle

在date型別的資料問題上確實存在一些bug,通過一些特殊方法還是能使date型別儲存'0000/00/00'資料。先看以下操作,這是bug之一。

sql> select date '0000-01-01' from dual;

date'0000-01-01'

----------------

0/0/0000

sql> select date '0000-11-22' from dual;

date'0000-11-22'

----------------

0/0/0000

在使用date關鍵字時,時間格式是羅馬格式。此時,我們發現oracle

沒有對年份是否為0進行校驗。並且,只要年份為0,資料都會被轉變為'0000/00/00'。

再看另外一種情況,

sql> select to_date('0001-01-01', 'yyyy-mm-dd')-365 from dual;

to_date('0001-01-01','yyyy-mm-

------------------------------

0/0/0000

sql> select to_date('0001-01-01', 'yyyy-mm-dd')-360 from dual;

to_date('0001-01-01','yyyy-mm-

------------------------------

0/0/0000

可以看到,oracle

對時間表示式的結果也沒有校驗年份是否為0,結合上面的bug,只要計算結果年份為0,無論月、日數值,結果都為'0000/00/00'。

再看第三種情況,就更加特殊了:只要對100到2023年之內的所有整百年的日期進行計算,如果結果為2月29的話,結果都為'0000/00/00'。

sql> select date '0099-2-28' +1 from dual;

date'0099-2-28'+1

-----------------

3/1/0099

sql> select date '0100-2-28' +1 from dual;

date'0100-2-28'+1

-----------------

0/0/0000

sql> select date '1000-2-28' +1 from dual;

date'1000-2-28'+1

-----------------

0/0/0000

sql> select date '1000-2-28' +2 from dual;

date'1000-2-28'+2

-----------------

3/1/1000

sql> select date '1000-2-27' +2 from dual;

date'1000-2-27'+2

-----------------

0/0/0000

sql> select date '1500-2-28' +1 from dual;

date'1500-2-28'+1

-----------------

0/0/0000

sql> select date '1600-2-28' +1 from dual;

date'1600-2-28'+1

-----------------

2/29/1600

最後一種情況,如果日期表示式的結果小於0,結果都為'0000/00/00'。

sql> select date '-0001-11-11' +1 from dual;

date'-0001-11-11'+1

-------------------

0/0/0000

sql> select date '-4712-11-11' +15 from dual;

date'-4712-11-11'+15

--------------------

0/0/0000

sql> select date '-1111-10-11' +0 from dual;

date'-1111-10-11'+0

-------------------

0/0/0000

sql> select to_date('01/01/01', 'yyyy/mm/dd') - 900 from dual;

to_date('01/01/01','yyyy/mm/dd

------------------------------

0/0/0000

順便要說的是,以上結果不僅可以被查詢出來,而且也能被儲存在字段型別為date的表中。

Oracle時間型別

sql alter session set nls date format yyyy mm dd hh24 mi ss 會話已更改。sql select to date 2006 05 01 19 25 34 yyyy mm dd hh24 mi ss from dual to date 2006 ...

oracle資料型別number 為null 判斷

number 可以是整數,也可以是含小數點的小數 操作項 a number 18,2 b number 18,2 相加 1.如果操作項有乙個為 null,相加結果為null a null null 2.正確寫法 nvl a,0 nvl b,0 sum 求和並相加 sum求和 會自動把null值補0 ...

Oracle自動補全日期,空資料為0

1.問題描述 在資料庫查詢中計算年月週日的資料時候,會發現日期並不完整,希望日期可以自動補全,並且沒有資料的字段補0 最開始的資料展現為如下圖 select nvl sum synnum 0 value to char syntime,yyyy mm dd lable from synlog whe...