2017-05-03 46 views
1

當我檢查了我的NLS_DATE_FORMATDD-MM-RR無法理解價值如何轉換成日期格式隱含

考慮MYTABLE與日期欄,當我執行以下語句,則會引發錯誤「ORA-01840:輸入值不夠長日期格式」,這是合理的理解。

insert into mytable values('10'); //Error: reason understandable 

那爲什麼下面的語句有效,其中明確了輸入大小比默認DATE Format的尺寸更大。

insert into mytable values('10AUGUST2016'); //reason not understandable 

而且,這裏我沒有使用任何TO_DATE功能,我想隱式轉換正在發生?

+0

是的'插入到mytable的值('10');'會拋出'ORA-01861:'錯誤,正如我所解釋的,我理解它背後的原因。 「insert into mytable values('10AUGUST2016');' –

回答

4

String-to-Date Conversion Rules的允許(被施加而沒有任何其他修飾)附加格式規則。所以:

  • MM也匹配MONMONTH;
  • MON匹配MONTH(反之亦然);
  • RR匹配RRRR;和
  • 標點符號是可選的。

所以:

SELECT TO_DATE('10AUGUST2016', 'DD-MM-RR' ) FROM DUAL UNION ALL 
SELECT TO_DATE('10AUGUST2016', 'DD-MON-RR' ) FROM DUAL UNION ALL 
SELECT TO_DATE('10AUGUST2016', 'DD-MONTH-RR') FROM DUAL UNION ALL 
SELECT TO_DATE('10AUG2016', 'DD-MM-RR' ) FROM DUAL UNION ALL 
SELECT TO_DATE('10AUG2016', 'DD-MON-RR' ) FROM DUAL UNION ALL 
SELECT TO_DATE('10AUG2016', 'DD-MONTH-RR') FROM DUAL; 

所有生成的日期2016-08-10T00:00:00

您可以通過使用FX format model

FX

格式確切防止這一點。此修飾符指定精確匹配用於TO_DATE函數的字符參數和日期時間格式模型:

  • 標點和在字符參數引用文字必須完全匹配的格式模型的相應部分(除了情況)。

  • 字符參數不能有額外的空格。如果沒有FX,Oracle會忽略額外的空白。

  • 字符參數中的數字數據必須具有與格式模型中相應元素相同的位數。如果沒有FX,字符參數中的數字可以忽略前導零。

    當啓用FX時,您也可以通過使用FM修飾符來禁用前導零的檢查。

如果字符參數的任何部分違反了任何這些條件,那麼Oracle會返回一條錯誤消息。

然後:

SELECT TO_DATE('10-AUGUST-2016', 'FXDD-MM-RR' ) FROM DUAL; 

給出:ORA-01858: a non-numeric character was found where a numeric was expected,並且其中一個確切的圖案發現匹配只能相匹配(儘管仍然RR將匹配RRRR)。

我猜隱含轉換正在發生?

是的,oracle默認使用TO_DATE('10AUGUST2016', NLS_DATE_FORMAT)來進行轉換。

如果你使用:

ALTER SESSION SET NLS_DATE_FORMAT = 'FXDD-MM-RR'; 

然後您的插入會失敗。

+2

'出現錯誤[稍後在同一文檔中]顯示格式替換(https://docs.oracle.com/cd/B19306_01/server.102/) b14200/sql_elements004.htm#sthref478)(或[12cR2版本](https://docs.oracle.com/database/122/SQLRF/Format-Models.htm#GUID-5B755E80-3CB2-4901-BBCF-F0FC764E0BB5),其中有一些關於標點字符的額外符號)。 –

+1

@AlexPoole謝謝,我通過該文件掃描,但沒有發現它。我假設我在達到倒數第二部分之前已經融化了大腦。現在更新以指向您引用的部分。 – MT0

+0

@ MT0我不認爲即使在使用FX之後RR仍然可以符合RRRR。正如我所看到的'從雙重'選擇to_date('20-04-2017','fxdd-mm-rr')失敗ORA-01830。 –