2012-09-17 5 views
0

다음 쿼리를 실행하면 Oracle 예외가 발생합니다. 그러나 나는 그 이유를 알지 못한다. 누구든지 약간의 빛을 비추 수 있습니까?Select가 ORA-01858 예외를 throw합니다.

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

. 그 중 일부 내용을 보여줄 수 있습니까? –

+0

하위 쿼리는 응답이 '28/09/2012 '인 행 하나를 반환합니다. 형식이 다른 dat_results_ext 테이블에는 일부 행이 있지만 'item_name ='CALLBACKDATE ''절로 인해 쿼리에서 다시 가져 오지 않습니다. – AndyMorton

+0

조건과 일치하지 않는 응답 값이 있어야합니다. – vikiiii

답변

2

최적화 프로그램은 최적의 실행 계획을 찾기 전에 쿼리를 다시 작성할 수 있습니다. 당신은에서 문의 평가 순서를 제어 할 필요가 없습니다

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

: 귀하의 경우에 당신은 아마 unnest your subquery을 뜻과 같이 쿼리를 다시 작성,이 일에서 최적화를 방해하는 힌트가 없기 때문에 WHERE 절에서 오라클은 아마도 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 : 일부`response` 값이 날짜로 변환하지 않기 때문에이다

    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

승리 확보! 오라클 옵티마이 저는 그 자체로 법칙 인 것처럼 보이지만, rownum을 추가하는 것은 그것을 강요했습니다! 감사합니다 빈센트 – AndyMorton

0

TO_DATE 절은 WHERE 절의 진위를 결정하기 전에 평가되어야합니다. TO_DATE 함수에서 평가할 수없는 응답 값이 있으면 오류가 표시됩니다.

+0

DCookie, 'select * from dat_results_ext ....'쿼리는 응답에서 '28/09/2012 '를 갖는 행 하나만 반환합니다 들. 나는 메인 쿼리의 where 절이 서브 쿼리에서 나오는 결과에만 영향을 줄 것이라고 생각했을 것이다. – AndyMorton

+0

간단한 방법으로이를 테스트 할 수 있습니다. 나쁜 데이터가없는 테이블을 만들고 시도하십시오. 오라클이이를 어떻게 평가하는지 믿을 수는 없습니다. 두 쿼리를 단일 쿼리로 병합하기로 결정할 수 있습니다. 두 테이블 모두 WHERE 절이 동시에 계산됩니다. 힌트를 사용하여 주위를 둘러 볼 수는 있지만 그다지 믿을 수는 없습니다. – DCookie

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 

당신이 달 필드에 문자를 통과하기 때문에 오라클은 숫자를 기대하고있다.

관련 문제