2

我得到 ORA-01722: invalid number 但只有当我select * from theView而不是当我直接选择 theView 时(使用视图中的 SQL CREATE OR REPLACE...)。

(我之前遇到并理解过这个错误,以及针对 NULL 值运行聚合,不应将 VARCHARS 存储在 NUMBER 列等中,但我很难理解这个问题)

4

1 回答 1

3

通常,当 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/

于 2020-08-25T16:34:54.547 回答