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
我希望此查询失败,因为日期无效,但它返回0
此查询的计划显示,在第8步,无效条款 已处理:
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)
条件 - 那么我们应该得到ORA-01858: a non-numeric character was found where a numeric was expected
如果我们注释掉AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy')
,那么我们会得到符合条件的记录数量(&gt; 0)
这怎么可能?
UPD :
提示/*+no_index(rps2_workflow) */
不会改变任何内容(而在计划中我们看到执行了fullscan)
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 :(得分: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
答案 1 :(得分:3)
可能发现满足所有其他条件的每条记录都有一个NULL
workflow_finished
字段。
与NULL
进行比较的任何内容都是未知的,因此不需要评估其他操作数。