2011-09-07 7 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 

私は無効なため、日付の、このクエリが失敗することを期待しますが、このクエリの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)条件をコメントアウトした場合 - その後、予想通り、我々はORA-01858: a non-numeric character was found where a numeric was expected

を取得し、我々はをコメントアウトした場合その条件に合致するレコードの量が得られます(> 0)

これはどのように可能ですか?

UPD:(計画で、我々はフルスキャンが実行されていることがわかり一方)オプティマイザはそれが必要ないと判断した場合

ヒント/*+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固有のものです – 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

関連する問題