Connect By 子句适用于 11g,但不适用于 Oracle 8i:“ORA-01436:用户数据中的 CONNECT BY 循环”

Posted

技术标签:

【中文标题】Connect By 子句适用于 11g,但不适用于 Oracle 8i:“ORA-01436:用户数据中的 CONNECT BY 循环”【英文标题】:Connect By clause works on 11g but not on Oracle 8i : "ORA-01436: CONNECT BY loop in user data" 【发布时间】:2019-03-25 20:46:54 【问题描述】:

我从这个问题Create View with 365 days中找到了行生成器的代码

CREATE VIEW year_days (the_day) AS
SELECT TRUNC(SYSDATE, 'YYYY') + (LEVEL-1) AS the_day
FROM DUAL
CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'),11)), 'DDD'))
/
SELECT * FROM year_days

由于我没有CREATE权限,我将其修改为内联查询表单:

SELECT
    year_days.* 
FROM
    (
    SELECT TRUNC(SYSDATE, 'YYYY') + (LEVEL-1) AS the_day
    FROM DUAL
    CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'),11)), 'DDD'))
    ) year_days

上面的内联查询代码在我们的一个 Oracle 11g R2 (v11.2.0.3.0) 实例以及 Oracle 自己的 LiveSQL (19c, v19.2.0.0.0) 上运行良好。

但是,它不适用于需要运行的实例,即 8i (v8.1.7.4.0)。 我得到ORA-01436: CONNECT BY loop in user data

乍一看,8i 似乎在该代码中看到了无限循环,但在 11g 及更高版本中却没有。为什么?

注意:我知道 8i 已经过时了。我无法控制。

【问题讨论】:

【参考方案1】:

如果它不必是 connect by 查询,那么更简单的东西怎么样,例如

select rownum
from all_objects
where rownum <= to_number(to_char(last_day(add_months(trunc(sysdate, 'YYYY'),11)), 'DDD'));

或许

select rownum 
from (select null from dual
      group by cube (1, 2, 3, 4, 5, 6, 7, 8, 9, 20)
     )
where rownum <= to_number(to_char(last_day(add_months(trunc(sysdate, 'YYYY'),11)), 'DDD'));

两者都应该适用于 Oracle 8i。

OraFAQ 论坛上更多漂亮的行生成器技术,这里:http://www.orafaq.com/forum/t/95011/102589/

【讨论】:

我知道存在其他行生成技术。但是,这并不能回答问题。 好的,没问题。我希望其中至少有一个能满足您(和 8i)的需求。 为了将来参考和帮助他人,这是我找到的关于行生成器主题的最佳文章/脚本集合:“ROW GENERATOR - 生成系列的方法”,livesql.oracle.com/apex/livesql/file/… 我的偏好是基于上述 Oracle 参考的“分层查询方法”。它应该适用于 8i。我需要发现和理解该特定版本的一些复杂之处才能使其发挥作用。

以上是关于Connect By 子句适用于 11g,但不适用于 Oracle 8i:“ORA-01436:用户数据中的 CONNECT BY 循环”的主要内容,如果未能解决你的问题,请参考以下文章

有子句适用于mysql中的where

SELECT 语句中的 select_expr 子句适用于啥? [复制]

在 c# where in 子句适用于整数?

MySQL UDF 仅适用于 `IF` 中的 `WHERE` 子句

from 子句中的语法错误,而相同的代码适用于其他表

适用于多种数据类型的通用 SQL UPDATE 子句