如果您的日期格式模型(無論是明確的還是通過您的NLS_DATE_FORMAT會話參數)不包含年份的符號或AD/BC指標,那麼一旦它們是字符串,就無法區分2016年和2016年。
with t (dt) as (
select date '2016-03-22' from dual
union all select date '-2016-03-22' from dual
union all select date '0001-01-01' from dual
union all select date '-0001-01-01' from dual
)
select to_char(dt, 'SYYYY-MM-DD') as dt1,
to_char(dt, 'YYYY-MM-DD') as dt2,
to_char(dt, 'DD/MM/YYYY') as dt3,
to_char(dt, 'DD/MM/SYYYY') as dt4,
to_char(dt, 'DD/MM/YYYY AD') as dt5
from t;
DT1 DT2 DT3 DT4 DT5
----------- ---------- ---------- ----------- -------------
2016-03-22 2016-03-22 22/03/2016 22/03/ 2016 22/03/2016 AD
-2016-03-22 2016-03-22 22/03/2016 22/03/-2016 22/03/2016 BC
0001-01-01 0001-01-01 01/01/0001 01/01/ 0001 01/01/0001 AD
-0001-01-01 0001-01-01 01/01/0001 01/01/-0001 01/01/0001 BC
注意,dt2
和dt3
列出現兩對正面和負面的價值觀是相同的,即使實際日期是不同的。
你的日期值沒有變化,你是如何顯示它們的。他們不會'變成負面的' - 他們是負面的,無論出於何種原因,有時你把它們轉換爲表示的字符串。如果您將NLS_DATE_FORMAT更改爲'SYYYY-MM-DD'
,則select *
也會通過使用該NLS參數的隱式轉換將它們顯示爲負數。
如果您只希望獲得數據中的AD值,那麼您需要調查BC(負)值的插入方式和原因。這與你看到它們顯示的方式完全不同。
「正確書寫」是什麼意思?最簡單的解釋似乎是,無論插入這些值的應用程序插入2016 BC日期。 'select *'會使用會話的'nls_date_format'將日期轉換爲一個字符串,大概不包含AD/BC後綴。如果您只顯示2位數年份,即使年份爲0016而不是2016年,也可以使日期看起來一樣。 –
或者如果您離開符號,則爲四位數年份。您正在過濾日期<0001-01-01,因此它們必須在邏輯上都是BC。你也可以使用'to_char(start_date,'SYYYY-MM-DD')'這將顯示爲-2016。正如賈斯汀所說,你的問題似乎與插入負數據(BC)年的數據無關。 –
感謝您的答案,請參閱我的編輯。 好吧,錯誤來自任何插入的日期格式不正確。 我在流浪,如果有to_char等東西... –