Обычно вы получаете его, когда оракул выполняет ваш предикат фильтра, который должен фильтровать только числа, после предикатов, где вы используете его как число.
Простой пример:
create table t as
select '1' x, 'num' xtype from dual union all
select 'A' x, 'str' xtype from dual
/
create index t_ind on t(x);
Вы можете видеть, что в этом очень простом примере мы получаем ORA-01722, несмотря на то, что мы указали фильтр xtype='num'
перед x > 0
:
select x
from (
select x
from t
where xtype='num'
) v
where v.x > 0;
ERROR:
ORA-01722: invalid number
План выполнения:
Plan hash value: 1601196873
---------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
|* 1 | TABLE ACCESS FULL| T | 1 | 6 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$F5BB74E1 / T@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter((TO_NUMBER("X")>0 AND "XTYPE"='num'))
Как видно из плана, встроенное представление было merged
и оба предиката находятся на одном уровне.
Теперь сравните с этим:
select/*+
no_merge(v)
opt_param('_optimizer_filter_pushdown' 'false')
*/
x
from (
select x
from t
where xtype='num'
) v
where v.x > 0;
X
-
1
План выполнения:
Plan hash value: 3578092569
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
|* 1 | VIEW | | 1 | 3 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| T | 1 | 6 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$2 / V@SEL$1
2 - SEL$2 / T@SEL$2
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("V"."X")>0)
2 - filter("XTYPE"='num')
Подробнее об этом: http://orasql.org/2013/06/10/too-many-function-executions/
person
Sayan Malakshinov
schedule
25.08.2020