gpt4 book ai didi

sql - 使用 Oracle 'with' 与使用表的行为不同

转载 作者:行者123 更新时间:2023-12-02 02:51:48 24 4
gpt4 key购买 nike

尝试了以下代码:

--------------- Setup ------------
drop table suk_rc_t1;

create table suk_rc_t1 (x number, y number);

insert into suk_rc_t1(x) values(1);

commit;

create or replace function suk_instn_id_wrap(
call_id pls_integer )
return pls_integer as
begin
dbms_output.put_line('suk_instn_id_wrap ' || call_id);
--return suk_instn_id;
return 123;
end;
/

--------------- How many RUNs of suk_instn_id_wrap in 2 queries below ? ------------

select 3 from suk_rc_t1
where (coalesce (y, suk_instn_id_wrap(1)) = suk_instn_id_wrap(2)
or suk_instn_id_wrap(3) is null);

begin
dbms_output.put_line('Done');
end;
/
with suk_rc_t1 as (select 1 x, null y from dual)
select 3 from suk_rc_t1
where (coalesce (y, suk_instn_id_wrap(1)) = suk_instn_id_wrap(2)
or suk_instn_id_wrap(3) is null);
begin
dbms_output.put_line('Done');
end;
/

我期望得到相同的输出。相反,我得到了:

suk_instn_id_wrap 3
suk_instn_id_wrap 1
suk_instn_id_wrap 2
Done

suk_instn_id_wrap 1
suk_instn_id_wrap 2
Done

有人对这种行为有解释吗?

最佳答案

这将是一个优化器的事情,虽然我不能肯定地说我怀疑推理可能如下:

在第一种情况下,Oracle 需要读取数据库以访问列y,如果没有必要,它宁愿不这样做,所以它更愿意评估suk_instn_id_wrap (3) 首先避免读取数据库。当然,事实证明它是假的,所以无论如何都要计算第一个表达式。运气不好。

在第二种情况下,Oracle 知道 y 为空,因此在这种情况下,OR 条件的任何一方都不再需要数据库访问。在这种情况下,它可能默认为表达式的原始顺序。您可能认为第二种情况会更好,因为只有一个函数调用,但也许没有考虑到这一点。

关于sql - 使用 Oracle 'with' 与使用表的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51930887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com