oracle - 使用 CTE Oracle 生成日期范围

标签 oracle common-table-expression recursive-query

我想使用 Oracle 中的递归 WITH 子句生成两个不同日期之间的天数范围。

WITH CTE_Dates (cte_date) AS
  ( SELECT CAST(TO_DATE('10-02-2017', 'DD-MM-YYYY') AS DATE) cte_date FROM dual
  UNION ALL
  SELECT CAST( (cte_date + 1) AS DATE) cte_date
  FROM CTE_Dates
  WHERE TRUNC(cte_date) + 1 <= TO_DATE('20-02-2017', 'DD-MM-YYYY')
  )
SELECT * FROM CTE_Dates

返回的结果与预期完全不同:

10-02-2017
09-02-2017
08-02-2017
07-02-2017
06-02-2017
... (unlimited)

预期结果:

10-02-2017
11-02-2017
...
19-02-2017
20-02-2017

Oracle Database 11g Express 版本 11.2.0.2.0 - 64 位生产版。

编辑: 据我了解,这是Oracle中的一个已知Bug,该Bug在Oracle 11.2.0.2中存在,并在11.2.0.3中修复。

替代解决方案:

SELECT TRUNC (TO_DATE('10-02-2017', 'DD-MM-YYYY') + ROWNUM -1) dt
  FROM DUAL
 CONNECT BY ROWNUM  <= (TO_DATE('20-02-2017', 'DD-MM-YYYY') - (TO_DATE('10-02-2017', 'DD-MM-YYYY')))

最佳答案

这是 Oracle 11 中递归 CTE 的一个已知错误(特别是关于日期算术)。 Oracle 12 中已修复。正是这种行为:无论您在代码中添加还是减去,引擎总是减去,而从不添加。

编辑:实际上,正如 Alex Poole 在对原始帖子的评论中指出的那样,该错误在 Oracle 11.2.0.2 中存在,并在 11.2.0.3 中得到修复。 结束编辑

唉,我不是付费客户,所以我不能引用章节和诗句,但是通过谷歌搜索一下,你会找到指向此内容的链接(包括在 OTN 上,我参与了一些讨论此内容和其他内容的线程)递归 CTE 中的错误 - 有些已修复,有些仍然是 Oracle 12.1 中的错误)。

已添加 - 以下是这些讨论之一:https://community.oracle.com/thread/3974408

关于oracle - 使用 CTE Oracle 生成日期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42509494/

相关文章:

sql - 如何阻止我的 Postgres 递归 CTE 无限循环?

sql - 使用 SQL Server 获取层次结构

mysql - 如何创建一个 SQL 调用,以递归方式将 DISTINCT id 和父 id 合并到一个列中?

java - Java EE 教程源的链接已损坏

java - 在事务中插入后获取 id (Oracle)

oracle - 使用 PLSQL 发送电子邮件

java.sql.SQLException : OALL8 is in an inconsistent state on JBoss 6. 1 EAP

sql - PostgreSQL 嵌套 CTE 和 UNION

sql - 这个递归 SQL CTE 究竟是如何工作的?

sql - MSSQL中CTE、临时表和表变量的区别