我使用 Oracle 資料庫 11g 版本 11.2.0.4.0
執行此查詢時:
SELECT
CASE WHEN (DATE '2005-11-25') IN ('25/11/05') THEN
'TRUE'
ELSE
'FALSE'
END
FROM DUAL;
我FALSE從 Oracle SQL Developer 21.4.1.349(法語版)和TRUEDBeaver 21.1.4.202108020335(法語版)獲得。
我知道我將日期與字串進行比較,所以我認為結果應該是FALSE,但這可能取決于我的實作。
Oracle 在這些情況下如何做出不同的回答?DBeaver 在提交請求之前是否對日期進行預處理?
uj5u.com熱心網友回復:
這取決于NLS_DATE_FORMAT正在使用的會話。
Oracle 會將您的查詢隱式轉換為以下內容:
SELECT CASE WHEN DATE '2005-11-25' IN (
TO_DATE(
'25/11/05',
(SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT')
)
)
THEN 'TRUE'
ELSE 'FALSE'
END
FROM DUAL;
由于它依賴于從字串到日期的隱式轉換,因此 Oracle 將在轉換中使用會話的日期格式。
例如:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/RR';
SELECT CASE WHEN DATE '2005-11-25' IN ('25/11/05')
THEN 'TRUE'
ELSE 'FALSE'
END
FROM DUAL;
輸出: TRUE
但:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';
SELECT CASE WHEN DATE '2005-11-25' IN ('25/11/05')
THEN 'TRUE'
ELSE 'FALSE'
END
FROM DUAL;
輸出: FALSE
您可以看到為什么使用:
SELECT TO_CHAR(CAST('25/11/05' AS DATE), 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
哪個輸出0005-11-25 00:00:00是 1 世紀,而不是 21 世紀,因為隱式轉換使用DD/MM/YYYY HH24:MI:SS格式模型并期望 4 位數的年份并獲取輸入05并假設它是 5 AD 的正確值而不是第 5 年當前世紀(您可以使用YY格式模型獲得)。
最好的解決方案是不依賴隱式字串到日期轉換。
使用日期文字:
SELECT CASE WHEN DATE '2005-11-25' IN (DATE '2005-11-25')
THEN 'TRUE'
ELSE 'FALSE'
END
FROM DUAL;
或者,為轉換提供顯式格式模型:
SELECT CASE WHEN DATE '2005-11-25' IN (TO_DATE('25/11/05', 'DD/MM/RR'))
THEN 'TRUE'
ELSE 'FALSE'
END
FROM DUAL;
db<>在這里擺弄
uj5u.com熱心網友回復:
因為您將日期與字串進行比較,所以使用會話的 NLS 設定將字串隱式轉換為日期。這些可能來自您的語言環境,或者可能由您的客戶明確設定,例如通過首選項。
如果NLS_DATE_FORMAT設定為“DD/MM/YYYY”,則“25/11/05”將轉換為 0005-11-25,因此比較為假。如果它設定為“DD/MM/YY”(或“DD/MM/RR”或“DD/MM/RRRR”),則將其轉換為 2005-11-25,因此比較為真。
db<>小提琴
您不應該依賴隱式轉換或 NLS 設定 - 因為您無法控制運行代碼的任何人的環境。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/414314.html
標籤:
