sql - 为什么确定性函数在 CONNECT BY LEVEL 查询中返回意外数字?

标签 sql oracle deterministic oracle18c connect-by

测试 #1:

我有一个用户定义的函数和一个 CONNECT BY LEVEL 查询:

with function custom_function(p_id in number) return number 
    is
begin
    return p_id;
end;

select 
    custom_function(level)
from 
    dual
connect by level <= 1000

ID
--
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

...
10 rows of 1000

该非确定性函数按预期工作。它返回序列号,类似于未使用该函数。


测试 #2:

此测试与第一个相同,只是函数是确定性的:

with function custom_function(p_id in number) return number 
    deterministic is  --this is what I changed
begin
    return p_id;
end;

select 
    custom_function(level) id
from 
    dual
connect by level <= 1000

ID
--
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
...

10 rows of 1000

确定性函数没有按预期工作。与测试 #1 不同,它不返回序列号。如果我们查看完整的结果集,它会返回:

  • 1 x 100
  • 101 x 100
  • 202 x 100
  • 303 x 100
  • 404 x 100
  • 505 x 100
  • 606 x 100
  • 707 x 100
  • 808 x 100
  • 909 x 100

db<>fiddle


为什么 DETERMINISTIC 函数在 CONNECT BY LEVEL 查询中返回意外数字?

最佳答案

根据神谕 docs当数据库遇到确定性函数时,它会尽可能尝试使用先前计算的结果,而不是重新执行该函数。在您的情况下,没有使用先前计算结果的范围。

使属于这些类别的函数具有确定性是一种良好的编程习惯:

->WHERE、ORDER BY 或 GROUP BY 子句中使用的函数

->SQL 类型的 MAP 或 ORDER 方法的函数

->帮助确定行是否出现在结果集中或出现在结果集中的位置的函数

附带说明一下,这似乎是 18C 中的错误,因为相同的查询在 19c 和 21c 中运行良好,结果正确。

关于sql - 为什么确定性函数在 CONNECT BY LEVEL 查询中返回意外数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72871656/

相关文章:

java - 从多个输入字符串生成确定性唯一固定长度文件名字符串

sql - 在两列中选择具有相似数据的不同数据

c# - Oracle/SQL 命令仅显示条件发生更改的行

excel - 想要通过 PL/SQL 将两个 Excel 工作表作为邮件附件

mysql - JPA Hibernate - 多种数据库方言和 nvarchar(length) 数据类型

c - 实时系统和确定性系统之间有区别吗?

python - Pymc3 python函数确定性

mysql - 如何在 LEFT OUTER JOIN 上使用索引

sql - 递归复制条目

sql - 为什么 SELECT * 被认为是有害的?