2012-09-17 42 views
0

使用以下查詢引發Oracle異常。 但是,我不明白爲什麼。任何人都可以點亮一下嗎?選擇拋出一個ORA-01858異常

select visit_id, to_date(response, 'DD/MM/YYYY') as convertedDate from 
(
select * 
from dat_results_ext 
where item_name = 'CALLBACKDATE' 
) 
where to_date(response, 'DD/MM/YYYY') > sysdate 

我明白這個例外是指它試圖轉換'響應'字段,但它是滿足非數字。問題是它應該帶回的行中包含正確格式的所有內容。 '響應'字段是一個varchar字段,但所有返回'item_name ='CALLBACKDATE'子句的行都是正確的格式。

任何想法?

+1

這是因爲有些'response'價值是無法轉換爲日期。你能向我們展示一些內容嗎? –

+0

子查詢返回一行,其響應爲'28/09/2012'。 dat_results_ext表中有一些行具有不同的格式,但由於'where item_name ='CALLBACKDATE''子句,它們不會被查詢帶回。 – AndyMorton

+0

必須有一些與條件不匹配的響應值。 – vikiiii

回答

2

優化程序可以在嘗試查找最佳執行計劃之前重新編寫您的查詢。你的情況,因爲你沒有跡象表明將阻止優化這樣做,恐怕也會unnest your subquery和重寫查詢爲:

SELECT * 
    FROM dat_results_ext 
WHERE item_name = 'CALLBACKDATE' 
    AND to_date(response, 'DD/MM/YYYY') > sysdate 

您不必控制在報表的計算順序WHERE子句,因此Oracle可能首先在不能轉換爲日期的行上計算to_date函數,因此錯誤。

我看到兩個選項,迫使甲骨文以評估你想要的順序聲明:

  1. 使用ROWNUM。 ROWNUM一定會實現的子查詢,防止甲骨文從外部查詢合併它:

    SELECT visit_id, to_date(response, 'DD/MM/YYYY') AS convertedDate 
        FROM (SELECT r.*, 
           rownum /* will materialize the subquery */ 
          FROM dat_results_ext r 
         WHERE item_name = 'CALLBACKDATE') 
    WHERE to_date(response, 'DD/MM/YYYY') > sysdate 
    
  2. 使用NO_MERGE hint

    SELECT visit_id, to_date(response, 'DD/MM/YYYY') AS convertedDate 
        FROM (SELECT /*+ NO_MERGE */ * 
          FROM dat_results_ext 
         WHERE item_name = 'CALLBACKDATE') 
    WHERE to_date(response, 'DD/MM/YYYY') > sysdate 
    
+0

勝利安全! Oracle優化器似乎本身就是一個法律,但加入rownum卻迫使它!謝謝文森特 – AndyMorton

0

在確定WHERE子句的真值之前,必須先對TO_DATE子句進行評估。如果您的TO_DATE函數中無法評估的響應值,則會看到該錯誤。

+0

DCookie,'select * from dat_results_ext ....'查詢只返回一行,響應中有'28/09/2012'這一行領域。我會認爲主查詢的where子句只會影響子查詢中只返回一行的結果? – AndyMorton

+0

有一個簡單的方法來測試這個。建立一個沒有任何不良數據的表並嘗試它。你不能指望Oracle如何評估這一點。它可能決定將兩個查詢合併爲一個,其中兩個WHERE子句同時進行評估。你可能會使用提示來解決它,但我不會指望它。 – DCookie

0

確切地說,這是因爲某些值responseDD/MM/YYYY的格式掩碼不匹配。例如,如果您的會話設置爲默認的DD-MON-YY日期格式,請執行以下命令,您將收到錯誤消息: -

select to_date('17/SEP/2012','DD/MM/YYYY') from dual; 
ERROR: 
ORA-01858: a non-numeric character was found where a numeric was expected 

既然你傳遞的月份字段中輸入字符和Oracle預計的數字。