这个问题几乎可以肯定是Oracle的策略造成的。
根据Oracle的策略,访问DUAL可以得到仅且唯一一条记录。如果dual表中存在多条记录或者缺少记录,那么很多Oracle的包都无法执行。
因此,Oracle的SQL解析器认为DUAL表中有且仅有一条记录,即使你插入新的记录,SELECT * FROM DUAL,仍然返回1条记录。
SQL> CONN SYS@TESTDATA AS SYSDBAITPUB个人空间9C#Wztx;BR
输入口令: *******ITPUB个人空间7[DN^;{%H(i
已连接。
tls7J&`(K\XUI0SQL> SELECT * FROM DUAL;
D
C c U X5tv{An0-ITPUB个人空间W8Z7X+pz
X
SQL> INSERT INTO DUAL VALUES ('X');
已创建1行。
SQL> SELECT * FROM DUAL;
DITPUB个人空间}8~5B0z1r&~bp
-ITPUB个人空间4~ehI)|v
X
SQL> SELECT COUNT(*) FROM DUAL;
COUNT(*)ITPUB个人空间0y]*}%j&Dl+ezT
----------
*c+X)B|H*^0qYZT.?0 2
SQL> ROLLBACK;
回退已完成。
因此,Oracle在处理下面的语句时,就犯了相同的错误:
SQL> SELECT * FROM V$VERSION;
BANNERITPUB个人空间&}b `yn@
----------------------------------------------------------------
l#EGV)jfX0Oracle9iEnterpriseEdition Release9.2.0.4.0 -ProductionITPUB个人空间"?ISL${&p
x+C
PL/SQL Release 9.2.0.4.0 - Production
F{hRRClR0CORE 9.2.0.3.0 ProductionITPUB个人空间-kkq^4j"h!]k
?
TNS for Linux: Version 9.2.0.4.0 - ProductionITPUB个人空间#aC(bW
n } FZ
NLSRTL Version 9.2.0.4.0 - Production
SQL> SELECT * FROM (SELECT ROWNUM RN FROM DUAL CONNECT BY LEVEL < 10);
RN
t%U+vKM D0----------
kd(V'B0u0 1
Y{p#EG6Y2t0 2
~:Z:H:`0~.`0 3ITPUB个人空间%G5H#l@Z?
4ITPUB个人空间-zG$ONvA2N
5
!_*ma*y$n0 6
K x|&[!b] P(O0 7ITPUB个人空间:F B0N2u2r
8ITPUB个人空间Orw)l/c5h&o
9
已选择9行。
虽然直接查询无法得到结果,但是通过嵌套查询还是可以得到正确的答案的。
这个问题在10g中已经被解决:
SQL> CONN TEST/TEST@TESTZJITPUB个人空间GM*W1tD6~2_]4o
已连接。
3ksO"R|BT]$YZJ0SQL> SELECT * FROM V$VERSION;
BANNERITPUB个人空间1w:}R,s~b$}1hG
----------------------------------------------------------------ITPUB个人空间D%I-DlS;}
Oracle Database10gEnterpriseEdition Release10.2.0.3.0 - 64bi