以下声明适用于Oracle 9i,但不适用于Oracle 11g
SELECT *
FROM
(
SELECT 0 scrnfail_rate, '9' zz, 7 hh FROM DUAL
UNION ALL
SELECT 0 scrnfail_rate, '9' zz, 7 hh FROM DUAL
)
WHERE zz IS NOT NULL
AND TO_CHAR (hh) NOT IN
(
SELECT
DECODE
(
scrnfail_rate, 0, -1,
ROUND (LEVEL * 1 / (scrnfail_rate / 100))
-
ROUND (1 / (2 * (scrnfail_rate / 100)))
) AS nno
FROM DUAL
WHERE NVL (scrnfail_rate, 0) > 0
CONNECT BY LEVEL <= ROUND(9 * scrnfail_rate / 100)
)
看起来Oracle 11g忽略了子查询中解码甚至where子句的位置。
此查询应返回两行,就像在Oracle 9i上一样,但在Oracle 11g EE 11.2.0.1.0 - 64位上返回ORA-01476: divisor is equal to zero
。
有人可以帮忙吗?谢谢!
答案 0 :(得分:5)
我发现Oracle 11.2.0.1.0中存在导致此问题的错误。
alter session set optimizer_features_enable='11.1.0.7'
更改优化器功能解决了这个问题。
答案 1 :(得分:2)
如果您遇到此问题并且从您的SQL脚本中删除子查询不适合您,我建议您使用Zsuetams解决方案并使用:
alter session set optimizer_features_enable='11.1.0.7';
您甚至可能希望更改Oracle实例的系统设置,以便只要通过执行以下方式挂载数据库,此优化程序设置将自动对所有会话保持有效:
alter system set optimizer_features_enable='11.1.0.7' scope=both;
作为具有ALTER SYSTEM系统特权的用户(例如SYS用户)。
如果您担心此类系统广泛部署的任何副作用,例如: G。您正在运行集群,并且您担心使用Oracle实例系统设置进行调整也可能会对其他方产生影响(并且重新测试所有内容都不合理)...然后您的应用程序容器可能会通过提供某种方式来扩展其JNDI来解决问题使用一些sql初始化语句的DataSource资源配置。然后,连接工厂将在创建与此数据源的连接期间执行一次这些语句。
如果您使用的是Tomcat 7,请使用 initConnectionSqls 参数:
<Resource name="application.datasource" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
[...]
initConnectionSqls="alter session set optimizer_features_enable='11.1.0.7'" />
注意:如果您使用的是DBCP&gt; = 1.3.1 / 1.4.1(尚未发布),您可能必须使用参数“connectionInitSqls”而不是“initConnectionSqls”作为版本DBCP的1.3和1.4错误地使用“initConnectionSqls”作为JNDI对象工厂配置的此属性的名称。
有关详细信息,请查看Apache Tomcat 7 - JNDI Resources HOW-TO和Apache Commons - Database Connection Pooling Configuration。
哦,最后:一个更好的解决方案可能是升级到Oracle 11g版本11.2.0.2.0毕竟; - )
答案 2 :(得分:0)
不幸的是,我无法重现它。
作为解决方法,请尝试以下方法:
SELECT *
FROM (
SELECT 0 scrnfail_rate, '9' zz, 7 hh
FROM DUAL
UNION ALL
SELECT 0 scrnfail_rate, '9' zz, 7 hh
FROM DUAL
)
WHERE zz IS NOT NULL
AND TO_CHAR (hh) NOT IN
(
SELECT DECODE
(
scrnfail_rate, 0, -1,
ROUND (LEVEL * 1 / (DECODE(scrnfail_rate, 0, 1, scrnfail_rate) / 100)) - ROUND (1 / (2 * (DECODE(scrnfail_rate, 0, 1, scrnfail_rate) / 100)))
) AS nno
FROM DUAL
WHERE NVL (scrnfail_rate, 0) > 0
CONNECT BY
LEVEL <= ROUND(9 * scrnfail_rate / 100)
)