簡體   English   中英

Oracle TO_DATE:在SELECT中工作; 在WHERE子句中不是有效月份

[英]Oracle TO_DATE: Works in SELECT; Not a Valid Month in WHERE Clause

我編寫了一個包含2個子查詢的查詢。 子查詢會格式化結果字段名稱和數據類型,因此它們是相同的。 主要查詢是直接的UNION。

這兩個子查詢都從托管的Oracle服務器檢索數據。 我們無法控制數據庫結構。 兩個子查詢之一使用字符串數據類型包含DateTime。 我在SELECT中使用以下代碼將值轉換為DateTime並添加2小時以調整時區:

TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') + 2/24 AS TRANS_DT,

這將產生正確的值。

麻煩的是:WHERE子句中相同的TO_DATE產生錯誤ORA-01843:無效的月份。 這是完整的WHERE子句:

WHERE TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') + 2/24 >= {?START_DT}

顯而易見的問題是,為什么上面的方法在SELECT中起作用,但是在WHERE子句中拋出了此錯誤?

字段中的值的格式設置為TO_DATE語句中指定的格式。 是不是我不希望SELECT語句產生錯誤,但是刪除WHERE子句時沒有錯誤。

我嘗試將TRUNC()添加到WHERE子句,因為參數{?START_DT}是Date數據類型。 我還用硬編碼代替了使用該參數的有效日期。 這些都不對錯誤有任何影響。

完成第二個子查詢的WHERE子句對我來說就是完成此項目並繼續進行的全部工作。 我正在使用具有成熟可靠連接的Crystal Reports訪問數據庫。 任何想法或建議,表示贊賞。

供您參考,這是整個查詢:

SELECT DISTINCT TCF.TRIPCARD_UNIT_NO AS UNIT_NO,
TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') AS TRANS_DT2,
TCF.ODOMETER AS METER
FROM MFIVE.VIEW_TRIPCARD_FAILED_TRANS TCF
WHERE TO_DATE(TCF.TRANS_DATE, 'MM-DD-YYYY HH24:MI:SS') >= TO_DATE('02-01-2019 00:00:00', 'MM-DD-YYYY HH24:MI:SS')

出於沮喪,我從TRANS_DT字符串中解析了月,日和年的值。 沒有超出適當范圍的值; 具體來說,所有月份的值都在1到12之間,符合預期。

我在WHERE子句中針對上述串聯的部分創建了一個新的TO_DATE語句。 檢查並仔細檢查了格式...然后我得到了相同的錯誤。

在我看來,WHERE子句中不允許TO_DATE。 還有其他人聽說過此限制嗎? 有什么方法可以在SQL中創建DateTime變量並將其傳遞給WHERE子句?

更新#3:

省略WHERE子句,我將查詢的其余部分用作子查詢,並對SELECT語句使用EXTRACT MONTH FROM TRANS_DT。 此子查詢運行精美,並產生了從1到12的整數。這再次確認沒有涉及格式錯誤的日期。

擴展子查詢概念,我嘗試使用此語句應用WHERE子句: WHERE TRUNC(TCF2.TRANS_DT) >= TO_DATE('02/01/2019', 'MM/DD/YYYY')這產生了相同的錯誤! 我聞到一個錯誤,但如果我知道是什么,該死的。

我可以想到兩個可能的原因:

首先,您正在運行查詢,但只查看幾行結果,而不是整個結果集。 您看到的行日期沒有問題。 如果滾動到末尾,則會看到問題。

第二個原因是select表達式在所有過濾之后運行(至少在某些情況下)。 錯誤的值可能會被其他過濾條件過濾掉。 當表達式移到where子句時,所有數據都可能通過此條件傳遞。

等於或匹配時,請檢查數據類型:

WITH S_DT AS 
(
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') START_DT FROM DUAL
),
TAB AS
(
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') + 2/24 AS TRANS_DT FROM DUAL
UNION ALL
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY HH24:MI:SS'), 'MM-DD-YYYY HH24:MI:SS') - 2/24 FROM DUAL
UNION ALL
SELECT TO_DATE(TO_CHAR(SYSDATE,'MM-DD-YYYY'), 'MM-DD-YYYY') + 2/24 FROM DUAL
)
SELECT * FROM TAB,S_DT WHERE TAB.TRANS_DT >= S_DT.START_DT;

輸出:

TRANS_DT  START_DT 
--------- ---------
2/22/2019 2:09:39 PM    2/22/2019 12:09:39 PM

或者,您也可以嘗試使用此NEW_TIME函數更改time zone

SELECT SYSDATE, 
       NEW_TIME(SYSDATE, 'GMT', 'EST') 
FROM dual;

輸出:

SYSDATE   NEW_TIME(SYSDATE,'GMT','EST')
--------- -----------------------------
2/22/2019 12:10:10 PM   2/22/2019 7:10:10 AM

暫無
暫無

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

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