0

次のクエリでは、Oracle例外がスローされます。しかし、その理由はわかりません。誰かが光を当てることができますか?

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

例外は、「応答」フィールドを変換しようとしていることを意味することを理解していますが、数値以外のものを満たしています。問題は、戻す必要のある行にすべてが正しい形式で含まれていることです。

'response'フィールドはvarcharフィールドですが、'item_name='CALLBACKDATE'句で返されるすべての行はすべて正しい形式です。

何か案は?

4

3 に答える 3

2

オプティマイザは、最適な実行プランを見つける前にクエリを書き直すことができます。あなたの場合、オプティマイザーがこれを行うのを妨げるヒントがないので、おそらくサブクエリをアンネストし、クエリを次のように書き直します。

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

WHERE句のステートメントの評価順序を制御できないため、Oracleはおそらくto_date、日付に変換できない行で関数を最初に評価したため、エラーが発生します。

Oracleにステートメントを希望の順序で評価させるための2つのオプションがあります。

  1. rownumを使用します。Rownumはサブクエリを実体化し、Oracleがサブクエリを外部クエリとマージできないようにします。

    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ヒントを使用してください:

    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
    
于 2012-09-17T13:53:29.577 に答える
0

WHERE句の真偽を判別する前に、TO_DATE句を評価する必要があります。TO_DATE関数で評価できない応答の値がある場合は、エラーが表示されます。

于 2012-09-17T13:26:15.617 に答える
0

正確に言うと、これは、の一部の値がresponseのフォーマットマスクと一致しないために発生しますDD/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は数値を予期しています。

于 2012-09-17T13:32:11.020 に答える