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
Spodziewam ta kwerenda się niepowodzeniem, z powodu nieprawidłowej daty, ale zwraca 0nieoczekiwany sukces zapytania
Plan dla tego zapytania wynika, że w dniu 8 kroku nieważna klauzula jest przetwarzane:
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
Gdybyśmy wykomentuj AND workflow_status IN (7, 12, 17)
warunku - wtedy expectedly otrzymujemy ORA-01858: a non-numeric character was found where a numeric was expected
Gdybyśmy wykomentuj AND workflow_finished < TO_DATE ('wtf', 'dd.mm.yyyy')
następnie otrzymujemy ilość rekordów, które pasują do tych warunków (> 0)
Jak to jest możliwe?
UPD:
Podpowiedź /*+no_index(rps2_workflow) */
niczego nie zmienia (podczas gdy w planie widzimy, że jest wykonywana 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
@BoltClock: aw, nie można umieścić sql na końcu listy tagów: -S Problem jest specyficzny dla oracle, a nie tylko ogólne pytanie sql – zerkms
Zgaduję, że optymalizator nie znalazł rekordów (przy użyciu indeksów) dla pracownika 159 ze statusem 7, 12 lub 17, więc nie zawracało sobie głowy oceną reszty zapytania. Po usunięciu sprawdzania stanu niektóre rekordy zostaną znalezione, więc musi ocenić funkcję TO_DATE i powoduje błąd. Trudno powiedzieć na pewno, co robi optymalizator zapytań ... – Sparky
@Sparky: spójrz na ostatni akapit - jeśli usuniemy "nieprawidłowy" fragment zapytania - zwróci on wiersze. Pomyślałem tak za chwilę, ale ** są ** rekordy o określonych statusach – zerkms