关于 Oracle PL SQL 循环
Posted
技术标签:
【中文标题】关于 Oracle PL SQL 循环【英文标题】:regarding Oracle PL SQL Loop 【发布时间】:2018-10-24 14:43:05 【问题描述】:今天做一些编码。遇到以下序列问题。 PL/SQL 中的这段代码:
没有按预期工作,即序列没有按我的意愿增加 10 - 仅增加 1。这段代码:
工作正常。序列按预期递增 10。
为什么要这样解释?
【问题讨论】:
Please post formatted text, not images. 我认为您不需要输入此代码并查看..我希望在这里得到概念性答案..因为在这些图像中我也没有提供完整代码..我只需要知道为什么这种事情发生 你为什么用图片替换你的代码? 【参考方案1】:您可以通过添加一些调试来查看发生了什么:
create sequence s42;
set serveroutput on
declare
cursor c is
select s42.nextval from dual;
n pls_integer;
begin
open c;
for i in 1..5 loop
fetch c into n;
dbms_output.put_line('i: ' || i
|| '; n: ' || n
|| '; found: ' || case when c%found then 'true' else 'false' end);
end loop;
close c;
end;
/
i: 1; n: 1; found: true
i: 2; n: 1; found: false
i: 3; n: 1; found: false
i: 4; n: 1; found: false
i: 5; n: 1; found: false
PL/SQL procedure successfully completed.
您只打开一次游标,游标只返回一行。因此,第一次 fetch 找到了一个值(c%found
为真)。由于单行结果集已经用完,第二次和后续的提取没有找到行。
简而言之,nextval
只执行一次,所以序列只递增一次。
在您的第二个版本中,整个查询在循环内重新执行,因此nextval
被多次调用,因此序列也被多次递增。
如果你在循环内重新打开光标,你会看到同样的结果:
declare
cursor c is
select s42.nextval from dual;
n pls_integer;
begin
for i in 1..5 loop
open c;
fetch c into n;
dbms_output.put_line('i: ' || i
|| '; n: ' || n
|| '; found: ' || case when c%found then 'true' else 'false' end);
close c;
end loop;
end;
/
i: 1; n: 2; found: true
i: 2; n: 3; found: true
i: 3; n: 4; found: true
i: 4; n: 5; found: true
i: 5; n: 6; found: true
但这实际上只是一种更长、更复杂的 select ... into
方法,因为它一次只能返回一行。
【讨论】:
【参考方案2】:仅在第二个代码中执行 nextval 10 次,因为 NEXTVAL 在循环内调用
NEXTVAL 导致增量
NEXTVAL:递增序列并返回下一个值
第一个代码调用nextval一次并将值存储在游标中,然后相同的值在循环中更新10次
【讨论】:
以上是关于关于 Oracle PL SQL 循环的主要内容,如果未能解决你的问题,请参考以下文章