SELECT COUNT(1) FROM (SELECT USER_ID FROM T_USER_INFO UI WHERE UI.USER_ID <> 'SYS_000') WHERE USER_ID > 21361059; ERROR: ORA-01722: invalid number
该sql统计排除用户“SYS_000”后用户ID大于“21361059”的用户数量(用户ID自增长,只是个别用户可能来自于特殊生成方式)。sql很简单,简单从表面逻辑上理解,在排除特殊的用户后,语句不应该再报 ORA-01722 invalid number 错误。接下来我们看看这到底是怎么回事。
环境
项目
说明
操作系统
CentOS 6.5 64位
数据库版本
11.2.0.1、11.2.0.4
RAC
否
模拟环境
1 2 3 4 5 6 7 8 9 10
SQL>createtable test(id int,user_id varchar2(30)); SQL>insertinto test values(1,'111'); SQL>insertinto test values(2,'222'); SQL>insertinto test values(3,'333'); SQL>insertinto test values(4,'444'); SQL>insertinto test values(5,'sys01'); SQL>insertinto test values(6,'666'); SQL>insertinto test values(7,'777'); SQL>commit; Commit complete.
SQL> exec dbms_stats.gather_table_stats('XWY','TEST'); PL/SQL proceduresuccessfullycompleted. SQL> select * from(select * from test t where t.user_id<>'sys01') whereto_number(user_id)>1; ERROR: ORA-01722: invalid number
SELECT /*+ NO_UNNEST(@AA)*/* FROM TEST A WHERE A.USER_ID <> 'sys01' AND EXISTS (SELECT /*+ QB_NAME(AA)*/ * FROM TEST T WHERE A.USER_ID = T.USER_ID AND T.USER_ID > 1);
ID USER_ID ---------- ------------------------------ 1 111 2 222 3 333 4 444 6 666 7 777 6 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 1194824156 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT || 1 | 7 | 12 (0)| 00:00:01 | |* 1 | FILTER |||||| |* 2 | TABLE ACCESS FULL| TEST | 6 | 42 | 3 (0)| 00:00:01 | |* 3 | TABLE ACCESS FULL| TEST | 1 | 5 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter( EXISTS (SELECT /*+ NO_UNNEST QB_NAME ("AA") */ 0 FROM "TEST""T" WHERE "T"."USER_ID"=:B1 AND TO_NUMBER("T"."USER_ID")>1)) 2 - filter("A"."USER_ID"<>'sys01') 3 - filter("T"."USER_ID"=:B1 AND TO_NUMBER("T"."USER_ID")>1)