簡體   English   中英

不是有效月份 - 在 Oracle 中使用日期

[英]Not a Valid Month - Working with Dates in Oracle

我發現在我的自定義環境中處理日期很費勁。 我有一個要求添加一個適合特定日期的 where 子句,但我無法讓 oracle 做出讓步。 任何想法請任何人。

 select created_date, cast(created_date as date) as created_date_cast
   from mytable;

 created_date                                  created_date_cast
 04-Mar-20 05.21.15.772000 AM                  3/4/2020 5:21:15 AM
 04-Mar-20 05.21.15.709000 AM                  3/4/2020 5:21:15 AM
 04-Mar-20 05.17.14.902000 AM                  3/4/2020 5:14:14 AM
 28-Feb-20 01.15.25.702700 AM                  2/28/2020 1:15:25 AM

當我嘗試添加一個where子句時,該代碼段因錯誤而炸毀:

select created_date, cast(created_date as date) as created_date_cast
  from mytable
 where cast(created_date as date) <= '02/28/2020';

ORA-01843: not a valid month

我也試過to_date(created_date, 'MM/DD/YYYY')在 from 但證明是錯誤的:

ORA-01858: a non-numeric character was found where a numeric was expected

首先轉換為日期,將時間戳值轉換為日期值,然后不要忘記添加trunc()函數以包含邊界值(在本例中為date'2020-02-28' )也為

where trunc(cast(created_date as date)) <= date'2020-02-28'

演示

不要使用CAST並且不要使用TRUNC (因為 Oracle 將無法在您的列上使用索引,而是需要在TRUNC(created_date)上創建基於函數的索引)只需添加一天並使用文字:

SELECT created_date
FROM   mytable
WHERE  created_date < DATE '2020-02-29';

或者

SELECT created_date
FROM   mytable
WHERE  created_date < TIMESTAMP '2020-02-29 00:00:00';

或者,如果您想指定確切日期,則只需添加一天。 例如:

SELECT created_date
FROM   mytable
WHERE  created_date < DATE '2020-02-28' + INTERVAL '1' DAY;

所有這些選項都應該能夠在created_date列上使用索引。

我也試過to_date(created_date, 'MM/DD/YYYY')在 from 但證明是錯誤的:

 ORA-01858: a non-numeric character was found where a numeric was expected

TO_DATE( value_string, format_model )將字符串作為其參數,但CREATED_DATETIMESTAMP數據類型而不是字符串,因此 Oracle 必須進行隱式TIMESTAMP到字符串的轉換,並且它使用NLS_TIMESTAMP_FORMAT會話參數執行此操作; 所以你的表達是有效的:

TO_DATE(
  TO_CHAR(
    created_date,
    ( SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_TIMESTAMP_FORMAT' )
  ),
  'MM/DD/YYYY'
)

如果您的NLS_TIMESTAMP_FORMAT不是MM/DD/YYYY那么很可能會引發異常(即像您擁有的ORA-01858 )。

您永遠不應該依賴隱式字符串轉換,因為任何用戶都可以隨時更改他們自己的會話參數,並且對一個用戶有效的隱式轉換可能不適用於另一個用戶,因為他們具有不同的參數值(即使查詢是相同的)。

使用日期文字:

cast(created_date as date) <= date '2020-02-28'

我還建議免除cast() - 假設created_date正確存儲為datetimestamp

created_date < (date '2020-02-28' + interval '1' day)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM