[英]SQL WHERE statements, where column may be value or may be NULL
[英]Not a valid month-Oracle query when casting string to date where some column value may be null
我有一個查詢
SELECT DISTINCT ID
From ACCUSED
WHERE CAST(DATE_ENTERED AS date) BETWEEN '12-Apr-2013' and '12-Apr-2013'
此查詢顯示錯誤“不是有效月份”
如果我在我的另一個表上應用相同的查詢,其中字符串日期不為null它工作正常。 這工作很好
SELECT DISTINCT ID
From Customer
WHERE CAST(DATE_ENTERED AS date) BETWEEN '12-Apr-2013' and '12-Apr-2013'
假設DATE_ENTERED
是VARCHAR2
列
DATE
列中。 使用錯誤的數據類型是問題的根源,修復數據模型以使用正確的數據類型是正確的解決方案。 TO_DATE
函數。 沒有格式掩碼的CAST
或TO_DATE
將導致會話的NLS_DATE_FORMAT
指定為格式掩碼。 由於每個會話可能會有所不同,這意味着您的代碼可能適用於某些客戶端的某些用戶而不適用於其他用戶或其他客戶端,並且這些錯誤將不可避免地難以找到。 DATE
與另一個DATE
進行比較,而不是與字符串進行比較。 將日期與字符串進行比較會強制Oracle執行隱式轉換,再次使用會話的NLS_DATE_FORMAT
並再次使您的代碼不可靠。 如果要指定文字日期,請使用TO_DATE
函數將字符串轉換為日期(使用顯式格式掩碼)或使用ANSI日期文字 ID
是主鍵, DISTINCT
充其量只是毫無意義,最壞的情況是迫使Oracle進行不必要的排序。 第一個最佳解決方案是修改數據模型,以便DATE_ENTERED
實際上是DATE
。 如果這樣做,您的查詢將變為(使用ANSI日期文字)
SELECT id
FROM accused
WHERE date_entered BETWEEN date '2013-04-12' and date '2013-04-12'
或者使用明確的TO_DATE
SELECT id
FROM accused
WHERE date_entered BETWEEN to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
AND to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
如果由於某種原因,您遇到了錯誤的數據模型,如果您存儲的所有字符串實際上都是有效的,那么您可以執行類似的操作
SELECT id
FROM accused
WHERE to_date( date_entered, 'DD-Mon-YYYY' ) BETWEEN to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
AND to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
但是,鑒於您遇到的錯誤,表中至少有一些行很可能表中存儲在表中的字符串不代表有效日期。 然后問題就是試圖找出哪些行無效。 一種選擇是創建一個新功能
CREATE OR REPLACE FUNCTION my_to_date( p_date_str IN VARCHAR2,
p_format_mask IN VARCHAR2 )
RETURN DATE
IS
l_date DATE;
BEGIN
l_date := to_date( p_date_str, p_format_mask );
RETURN l_date;
EXCEPTION
WHEN others THEN
RETURN NULL;
END;
然后在查詢中使用該函數。
SELECT *
FROM accused
WHERE date_entered IS NOT NULL
AND my_to_date( date_entered, 'DD-Mon-YYYY' ) IS NULL
將以DD-Mon-YYYY
格式返回DATE_ENTERED
不表示有效日期的所有行。 您最終必須更正此數據。 如果您可以忽略任何包含無效數據的行,則可以編寫查詢
SELECT id
FROM accused
WHERE my_to_date( date_entered, 'DD-Mon-YYYY' ) BETWEEN to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
AND to_date( '12-Apr-2013', 'DD-Mon-YYYY' )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.