2011-09-07 5 views
12
SELECT COUNT (*) 
    FROM rps2_workflow 
WHERE  workflow_added > TO_DATE ('01.09.2011', 'dd.mm.yyyy') 
     AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy') 
     AND workflow_status IN (7, 12, 17) 
     AND workflow_worker = 159 

나는이 쿼리 때문에 유효하지 않은 날짜의 실패를 기대하지만이 쿼리에 대한 계획은 8 단계에서 무효 조항 이 처리되는 것을 알 수 0예상치 못한 쿼리 성공

를 반환

8 TABLE ACCESS BY INDEX ROWID TABLE RPS2.RPS2_WORKFLOW Object Instance: 1 Filter Predicates: ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy')) Cost: 11 Bytes: 33 Cardinality: 1 CPU Cost: 8 M IO Cost: 10 Time: 1      

것은 우리가 AND workflow_status IN (7, 12, 17) 조건을 주석하는 경우 - 우리가 012,318,861을 주석 경우 예상대로 우리가 ORA-01858: a non-numeric character was found where a numeric was expected

를 얻을 수그런 다음 해당 조건에 맞는 레코드를 얻습니다 (> 0)

어떻게 가능합니까?

UPD : (계획에서 우리가 FULLSCAN 수행되는 것을 볼 반면에) 최적화 프로그램이 필요하지 않음을 결정하면

힌트 /*+no_index(rps2_workflow) */

SELECT STATEMENT ALL_ROWSCost: 254 Bytes: 31 Cardinality: 1 CPU Cost: 34 M IO Cost: 248 Time: 4  
2 SORT AGGREGATE Bytes: 31 Cardinality: 1  
    1 TABLE ACCESS FULL TABLE RPS2.RPS2_WORKFLOW Object Instance: 1 Filter Predicates: "WORKFLOW_WORKER"=159 AND ("WORKFLOW_STATUS"=7 OR "WORKFLOW_STATUS"=12 OR "WORKFLOW_STATUS"=17) AND SYS_EXTRACT_UTC("WORKFLOW_ADDED")>SYS_EXTRACT_UTC(TIMESTAMP' 2011-09-01 00:00:00') AND SYS_EXTRACT_UTC("WORKFLOW_FINISHED")<SYS_EXTRACT_UTC(TO_DATE('wtf','dd.mm.yyyy')) Cost: 254 Bytes: 31 Cardinality: 1 CPU Cost: 34 M IO Cost: 248 Time: 4 
+0

@BoltClock : aw는 sql을 태그 목록의 끝에 넣을 수 없습니다. -S 문제는 일반적인 SQL 질문이 아닌 oracle-specific입니다. – zerkms

+0

나는 옵티마이 저가 작업자 159에 대한 레코드를 찾지 못했을 것이라고 추측합니다 7, 12 또는 17의 상태로 표시되므로 나머지 쿼리를 평가하는 데 별 문제가되지 않았습니다. 상태 검사를 제거하면 일부 레코드가 발견되므로 TO_DATE 함수를 평가해야하고 오류가 발생합니다. 비록 쿼리 최적화 프로그램이 무엇을하고 있는지 확실히 말하기가 어렵습니다 ... – Sparky

+0

@ Sparky : 마지막 단락을보십시오 - "잘못된"쿼리 조각을 제거하면 행을 반환합니다. 나도 잠시 생각했다. ** ** 지위가있는 기록이있다 ** – zerkms

답변

3

그것은 아마도 다른 모든 조건을 만족하는 모든 레코드가 NULLworkflow_finished 필드가 있음을 발견했다.

NULL과 비교되는 내용은 알 수 없으므로 다른 피연산자를 평가할 필요가 없습니다.

+1

+1 그냥 사소한 점 : 아무런 차이가 없지만 NULL과 비교되는 것이 알려지지 않은 것, 틀린 것은 아닙니다. 이리. –

7

아무것도 변경되지 않습니다 함수를 평가하면 예외가 발생하지 않으므로 예외가 발생하지 않습니다.

select 1 from dual where 1 = 1 OR to_date('asdasdasd','asdasdasdas') > sysdate ; 

     1 
---------- 
     1 

함수가 발생합니다. 실제로 평가됩니다 경우에만 예외 :

SQL> select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate ; 
select 1 from dual where 1 = 1 AND to_date('asdasd','asdas') > sysdate 
                * 
ERROR at line 1: 
ORA-01821: date format not recognized 

그러나, 파서가 정적으로을 를 결정할 수있는 경우 쿼리가 무효 인 - 함수는 인수의 잘못된 유형이 있거나 쿼리는 다음, 유효하지 않은 유형이 있기 때문에 옵티마이에서 스윙을 취득하기 전에 파서는 예외가 발생합니다 :

SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate ; 
select 1 from dual where 1 = 1 or to_date('asdasdasd',0) > sysdate 
                 * 
ERROR at line 1: 
ORA-00932: inconsistent datatypes: expected DATE got NUMBER 


SQL> select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42 ; 
select 1 from dual where 1 = 1 or to_date('asdasdasd','asdasdasdas') > 42 
                     * 
ERROR at line 1: 
ORA-00932: inconsistent datatypes: expected DATE got NUMBER 
+0

당신이 절대적으로 옳다고해도 - 대답이 아닙니다. 문제가 조금 더 깊기 때문에 (술어 수준이 아니라 피연산자 수준). 그리고 알렉시스는 그것을 정확하게 짐작했습니다. +1 어쨌든 – zerkms

+0

아, 대답하기 전에 모든 "read more"주석을 읽지 않았습니다 :) –

+0

하지만 어쨌든 당신은 훌륭한 일을했습니다. 이 정보는 다른 독자들에게 유용 할 것입니다. 만약 alexisdm이 대답을하지 않는다면 - 나는 당신의 것을 검사 할 것입니다 (그리고 "이상한"행동을 일으킨 경우를 추가 할 것입니다) – zerkms

관련 문제