两条SQL语句分别在上线系统与测试系统中执行,一条在上线中通过测试通不过,一条在上线中通不过测试中通过
今天,在测试系统中有发现一条SQL语句无法执行,而上线系统中却没见有用户反映有问题,于是将测试系统中的语句修改了一下,并测试通过,然后导入上线系统,然而,问题来了,有用户反映系统出错,一查,发现是那条改过的语句,拿到测试系统一试可以通过而上线系统却通不过。见下面的过程,由此可见,Oracle对SQL语句的Where条件解析顺序应该不是固定的。
出现这样的问题,需要研究一下它到底与什么有关,以避免出现在不同数据库中的表现不同。
SQL> connect itedev@eimslive.world
输入口令:
已连接。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.2.0 - 64bit Production
PL/SQL Release 9.2.0.2.0 - Production
CORE 9.2.0.2.0 Production
TNS for HPUX: Version 9.2.0.2.0 - Production
NLSRTL Version 9.2.0.2.0 - Production
SQL> DESC SOM.SOAD_DET;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
SOAD_NBR NOT NULL VARCHAR2(18)
SOAD_LINE NOT NULL NUMBER
SOAD_SO_LINE NUMBER
SOAD_TYPE CHAR(1)
SOAD_HOLD_DATE DATE
SOAD_OLD_VALUE VARCHAR2(50)
SOAD_NEW_VALUE VARCHAR2(50)
SOAD_RMKS VARCHAR2(200)
SOAD_QTY NUMBER
SQL> SELECT SOAD_NEW_VALUE,SOAD_OLD_VALUE
2 FROM SOM.SOAD_DET
3 WHERE SOAD_NBR = 'A4120000001'
4 AND SOAD_TYPE = 'G';
未选定行
SQL> SELECT COUNT(*)
2 FROM SOM.SOAD_DET
3 WHERE SOAD_NBR = 'A4120000001'
4 AND SOAD_TYPE = 'G'
5 AND TO_NUMBER(SOAD_NEW_VALUE) = 0;
AND TO_NUMBER(SOAD_NEW_VALUE) = 0
*
第 5 行出现错误:
ORA-01722: invalid number
SQL> SELECT COUNT(*)
2 FROM (SELECT SOAD_NEW_VALUE,SOAD_OLD_VALUE
3 FROM SOM.SOAD_DET
4 WHERE SOAD_NBR = 'A4120000001'
5 AND SOAD_TYPE = 'G')
6 WHERE TO_NUMBER(SOAD_NEW_VALUE) > TO_NUMBER(SOAD_OLD_VALUE);
COUNT(*)
----------
0
SQL>
SQL> connect itedev@eimstest.world
输入口令:
已连接。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.2.0 - 64bit Production
PL/SQL Release 9.2.0.2.0 - Production
CORE 9.2.0.2.0 Production
TNS for HPUX: Version 9.2.0.2.0 - Production
NLSRTL Version 9.2.0.2.0 - Production
SQL> DESC SOM.SOAD_DET;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
SOAD_NBR NOT NULL VARCHAR2(18)
SOAD_LINE NOT NULL NUMBER
SOAD_SO_LINE NUMBER
SOAD_TYPE CHAR(1)
SOAD_HOLD_DATE DATE
SOAD_OLD_VALUE VARCHAR2(50)
SOAD_NEW_VALUE VARCHAR2(50)
SOAD_RMKS VARCHAR2(200)
SOAD_QTY NUMBER
SQL> SELECT SOAD_NEW_VALUE,SOAD_OLD_VALUE
2 FROM SOM.SOAD_DET
3 WHERE SOAD_NBR = 'A4120000001'
4 AND SOAD_TYPE = 'G';
未选定行
SQL> SELECT COUNT(*)
2 FROM SOM.SOAD_DET
3 WHERE SOAD_NBR = 'A4120000001'
4 AND SOAD_TYPE = 'G'
5 AND TO_NUMBER(SOAD_NEW_VALUE) = 0;
COUNT(*)
----------
0
SQL> SELECT COUNT(*)
2 FROM (SELECT SOAD_NEW_VALUE,SOAD_OLD_VALUE
3 FROM SOM.SOAD_DET
4 WHERE SOAD_NBR = 'A4120000001'
5 AND SOAD_TYPE = 'G')
6 WHERE TO_NUMBER(SOAD_NEW_VALUE) > TO_NUMBER(SOAD_OLD_VALUE);
WHERE TO_NUMBER(SOAD_NEW_VALUE) > TO_NUMBER(SOAD_OLD_VALUE)
*
第 6 行出现错误:
ORA-01722: invalid number
SQL>