今天做一些编码。遇到以下序列问题。PL/SQL 中的这段代码:
没有按预期工作,即序列没有按我的意愿增加 10 - 仅增加 1。这段代码:
工作正常。序列按预期增加 10。
为什么要这样解释?
今天做一些编码。遇到以下序列问题。PL/SQL 中的这段代码:
没有按预期工作,即序列没有按我的意愿增加 10 - 仅增加 1。这段代码:
工作正常。序列按预期增加 10。
为什么要这样解释?
您可以通过添加一些调试来查看发生了什么:
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
为 true)。由于单行结果集已用尽,第二次和后续提取未找到行。
简而言之,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
但这实际上只是一种更长、更复杂的 a 方法select ... into
,因为它一次只能返回一行。
只有在第二个代码中执行 nextval 10 次,因为 NEXTVAL在循环内被调用
NEXTVAL导致增量
NEXTVAL:递增序列并返回下一个值
第一个代码调用 nextval 一次并将值存储在游标中,然后相同的值在循环中更新 10 次