我得到 ORA-01722: invalid number 但只有当我select * from theView
而不是当我直接选择 theView 时(使用视图中的 SQL CREATE OR REPLACE...
)。
(我之前遇到并理解过这个错误,以及针对 NULL 值运行聚合,不应将 VARCHARS 存储在 NUMBER 列等中,但我很难理解这个问题)
通常,当 oracle 执行您的过滤谓词时,您会得到它,该过滤谓词应该只过滤数字,在您使用它作为数字的谓词之后。
简单的例子:
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);
即使我们xtype='num'
之前指定了过滤器,您也可以在这个非常简单的示例中看到我们得到 ORA-01722 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'))
从计划中可以看出,内联视图 wasmerged
和两个谓词处于同一级别。
现在比较一下:
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/