LOOP 循环
说明:
LOOP是基础循环,一般配合其他循环语句一起使用
语法:
LOOP --循环开始
【...】--循环内容
EXIT WHEN ...; --退出条件
END LOOP; --循环结束
示例:
declare
x number;
begin
x := 0;
dbms_output.put_line('lopp循环');
loop
x := x + 1;
dbms_output.put_line(x);
exit when x > 4;
end loop;
end;
输出结果:
lopp循环
1
2
3
4
5
FOR循环
说明:
FOR循环用于循环次数已知的场景,一般配合COUNT和SUM函数连用。
语法:
for 自定义变量 in 开始数字..结束数字 loop --数字只能从小到大
【...】--循环内容
END LOOP; --循环结束
示例:
declare
x number;
begin
x := 0;
dbms_output.put_line('for 循环');
for aa in reverse 1 .. 5 loop --reverse关键字可以进行顺序反转
dbms_output.put_line(aa);
end loop;
end;
输出结果
for 循环
5
4
3
2
1
FORALL循环
说明
FORALL循环使用方法与FOR循环基本一致,在执行DML语句时,效率显著高于后者。FORALL循环一般与BULK COLLECT关键字连用,进行百万数据以上的批量更新与插入。
语法:
declare
--定义变量,游标,常量
begin
open 游标名称 for 'SQL语句'
loop
exit when 游标名称%notfound; --当游标未找到记录退出循环
fetch 游标名称 bulk collect into 集合类型变量1,集合类型变量2 limit 最大值;
--bulk collect会一次性把游标里的数据缓存进PGA,需要限定合理的记录数,不然会导致撑爆PGA。
forall i in 1 .. 集合类型变量1.count --根据集合变量的总数进行循环
update table set column1=集合类型变量1(i) where column2= 集合类型变量2(i);
--根据集合变量的数据批量更新表
commit;
end loop;
end;
示例:
--创建测试环境
create table test1(id varchar2(1),cost varchar2(10));
insert into test1 values(1,10);
insert into test1 values(2,20);
insert into test1 values(3,30);
create table test2(id varchar2(1),cost varchar2(10));
insert into test2 values(1,40);
insert into test2 values(2,50);
insert into test2 values(3,60);
commit;
--使用FORALL根据ID批量更新test1表的cost为test2的cost。
declare
maxrows number default 2000;
--定义一次获取游标行数最大值默认2000
array1 dbms_sql.Varchar2_Table;
--定义一个字符串的数组
array2 dbms_sql.Varchar2_Table;
type c_cur is ref cursor;
--定义一个引用类型的游标
test_cur c_cur;
begin
open test_cur for 'select * from test2';
loop
exit when test_cur%notfound;
fetch test_cur bulk collect into array1, array2 limit maxrows;
forall i in 1 .. array1.count
update test1 set cost = array2(i) where id = array1(i);
commit;
--每2000行提交一次,防止锁表。
end loop;
end;
执行结果:
select * from test1;
ID | COST | |
---|---|---|
1 | 1 | 40 |
2 | 2 | 50 |
3 | 2 | 60 |
WHILE循环
说明:
while语句可以在循环开始时指定循环条件。只有条件成立时,才会进行循环处理。
语法:
while 条件判断 loop
循环语句
end loop;
示例:
declare
x number;
begin
x := 0;
dbms_output.put_line('while循环');
while x < 6 loop
x := x + 1;
dbms_output.put_line(x);
end loop;
end;
输出结果:
while循环
1
2
3
4
5
GOTO循环
说明:
GOTO循环可以通过操作标识将多种操作在一个过程中进行处理。
语法:
if 表达式 then goto 节点1;
else if 表达式 then goto 节点2;
end if;
<<定义节点1>>
节点语句1...
return; --结束节点定义
<<定义节点2>>
节点语句2...
return;
示例:
declare
v_flag varchar2(2);
begin
v_flag := 'U'; --操作标识
if v_flag = 'I' then
goto p_insert;
elsif v_flag = 'U' then
goto p_updete;
elsif v_flag = 'D' then
goto p_delete;
end if;
<<p_insert>>
dbms_output.put_line('p_insert操作入口');
return;
<<p_updete>>
dbms_output.put_line('p_update操作入口');
return;
<<p_delete>>
dbms_output.put_line('p_delete操作入口');
end;
输出结果:
p_update操作入口