Подзапрос работает в 9i, а не в 11g - PullRequest
1 голос
/ 28 декабря 2010

Оператор, приведенный ниже, работает в 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 игнорирует выражение где декодировать или даже где в подзапросе.Этот запрос должен возвращать две строки, как это происходит в Oracle 9i, но в Oracle 11g EE 11.2.0.1.0 - 64-битный результат ORA-01476: divisor is equal to zero.


Кто-нибудь может помочь?Спасибо!

Ответы [ 3 ]

5 голосов
/ 11 января 2011

Я обнаружил, что в Oracle 11.2.0.1.0 есть ошибка, которая вызывала эту проблему.

alter session set optimizer_features_enable='11.1.0.7'

Изменение функций оптимизатора решает эту проблему.

2 голосов
/ 09 января 2013

Если вы столкнулись с этой проблемой, и удаление подзапросов из ваших 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).

Если вы боитесь каких-либо побочных эффектов такого развертывания в масштабе всей системы, например, у вас работает кластер, и вы боитесь, что изменение параметров системы экземпляра Oracle может повлиять и на другие стороны (и повторное тестирование неt разумно)… Тогда ваш контейнер приложения может прийти на помощь, предоставив какой-то способ расширить конфигурацию своего ресурса JNDI DataSource с помощью некоторых операторов инициализации sql.Затем фабрика соединений будет выполнять эти операторы один раз при создании соединений с этим источником данных.

Если вы, например, используете Tomcat 7, используйте параметр initConnectionSqls :

    <Resource name="application.datasource" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
[...]
              initConnectionSqls="alter session set optimizer_features_enable=&apos;11.1.0.7&apos;" />

ПРИМЕЧАНИЕ : Если вы используете DBCP> = 1.3.1 / 1.4.1 (еще не выпущено), вам, вероятно, уже придется использовать параметр "connectionInitSqls" вместо "initConnectionSqls" в качестве версий 1.3и 1.4 DBCP неправильно использует "initConnectionSqls" в качестве имени этого свойства для конфигурации фабрики объектов JNDI.

Посмотрите Apache Tomcat 7 - HN-TO ресурсы JNDI и Apache Commons - Конфигурация пула соединений с базой данных для получения дополнительной информации об этом.

Да, и наконец: еще лучшим решением может быть, в конце концов, обновление до Oracle 11g версии 11.2.0.2.0; -)

0 голосов
/ 28 декабря 2010

К сожалению, я не могу воспроизвести его.

В качестве обходного пути попробуйте следующее:

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)
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...