美文网首页
Oracle PL/SQL (6) - 集合运算符、FORALL

Oracle PL/SQL (6) - 集合运算符、FORALL

作者: 乘风破浪的姐姐 | 来源:发表于2020-04-06 16:16 被阅读0次

1、集合运算符的使用
set操作符用于取消特定嵌套表中的重复值。

DECLARE
 TYPE my_array_type IS TABLE OF VARCHAR2(50) not null;
 my_array1 my_array_type:=my_array_type(2,4,3,1,2);
 my_array2 my_array_type;
 my_array3 my_array_type:=my_array_type();
 my_array4 my_array_type:=my_array_type('beijing','shanghai','wuhan');
 my_array5 my_array_type:=my_array_type('beijing','java');
 my_array6 my_array_type:=my_array_type('beijing','shanghai');

 v_str varchar2(10):=4;
  
BEGIN
 
 my_array2 :=set(my_array1);
  FOR i in 1..my_array2.count LOOP
   dbms_output.put_line(' '||my_array2(i));-- 输出  2 4 3 1
 END LOOP;
 dbms_output.put_line('集合中所有元素的个数为: '||CARDINALITY(my_array1));--输出 5
 -- empty运算符
 if  my_array2 is not empty then
      dbms_output.put_line('my_array2是不是空集合! ');
 end if;
 if my_array3 is empty then
        dbms_output.put_line('my_array3是一个空集合! ');
 end if;
 
 --member of 运算符
 if v_str member of my_array2 then
          dbms_output.put_line('my_array2中包含数字! '||v_str);
 end if ;
 
 --multiset except  以my_array4集合为参考,删除与my_array5中相同的部分
 my_array3:=my_array4 multiset except my_array5;
 FOR i in 1..my_array3.count LOOP
   dbms_output.put_line(' '||my_array3(i));-- 输出 shanghai wuhan
 END LOOP;
 
 --multiset intersect 保留两个集合中相同的部分
 my_array3:=my_array4 multiset intersect my_array5;
 FOR i in 1..my_array3.count LOOP
   dbms_output.put_line(' '||my_array3(i));-- 输出 beijing
 END LOOP;
 
 --  multiset union 将两个集合的数据合并在一起
  my_array3:=my_array4 multiset union my_array5;
 FOR i in 1..my_array3.count LOOP
   dbms_output.put_line(' '||my_array3(i));-- 输出 beijing shanghai wuhan beijing java
 END LOOP;
 
 -- submultiset 判断一个集合是否为另一个集合的子集
 if my_array6 submultiset my_array4 then
   dbms_output.put_line('my_array6集合是my_array4的子集。 ');
 end if;
END;

2、使用FORALL批量绑定
当使用PL/SQL执行一条更新语句时,SQL会将执行更新的数据返回给PL/SQL,这样用户才可以取得更新后的数据。但是要进行大量的数据操作时,这种方式就会使程度的执行性能大大降低。
如:通过PL/SQL程序快执行多条数据的更新操作。

declare
  type user_array is varray(10) of user.userno%type;
  v_userno user_array :=user_array(222,333,444,555,666);
begin
  for x in v_userno.first .. v_userno.last loop
      update user set username='AAA' where userno=v_userno(x);
  end loop;
end;

但是使用FORALL语句,记录集合中要用于更新操作的数据,记录完成之后向数据库中一次性发出多条更新语句。更新完成之后,可以使用SQL%BULK_ROWCOUNT(x)取得操作中所影响的数据行数。
FORALL语句语法:

FORALL 变量 IN 集合初值..集合最高值 SQL语句
declare
  type user_array is varray(10) of user.userno%type;
  v_userno user_array :=user_array(222,333,444,555,666);
begin
  forall x in v_userno.first..v_userno.last
      update user set username='AAA' where userno=v_userno(x); 
  for x in v_userno.first .. v_userno.last loop
      dbms_output.put_line('用户'||v_userno(x)||'更新数据受影响的行数为:'||SQL%BLUK_ROWCOUNT(x));--SQL%BULK_ROWCOUNT(x)取得更新操作影响的行数
  end loop;
end;

3、BULK COLLECT 批量接收数据
上面例子中使用FORALL语句可以一次性向数据库中发出多条SQL语句,而使用BULK COLLECT 可以一次性从数据库中取出多条数据。

declare
  type claimno_varray is varray(5) of claim.claimno%type;
  v_claimno claimno_varray;
begin
  select claimno bulk collect into v_claimno from claim where acc_no='claim01';
  for i in v_claimno.first .. v_claimno.last loop
     dbms_output.put_line('定损单号:'||v_claimno(i));  
  end loop;
end;

输出结果:
定损单号:claim01_05
定损单号:claim01

declare  
 v_acc_no   emb.claim.acc_no%type;     
 type varray_claimno is varray(5) of emb.claim.claimno%type;  
 type varray_amount is varray(5) of emb.claim.estimate_amt%type;  
   
 v_claimno    varray_claimno:=varray_claimno();  
 v_amount     varray_amount:=varray_amount();  
begin  
 v_acc_no:='claim01';
 select t.claimno,t.estimate_amt
 bulk collect into v_claimno, v_amount
 from claim t where t.acc_no = v_acc_no;
 
 /*输出定损单信息*/  
 for  v_index in v_claimno.first .. v_claimno.last loop  
     dbms_output.put_line('定损单号:'||v_claimno(v_index)||' 定损总金额:'||v_amount(v_index));  
 end loop;  
end;

输出结果:
定损单号:claim01_05 定损总金额:73446
定损单号:claim01 定损总金额:128327

以上只是取出表中的一部分字段 数据进行保存。实际也可以结合嵌套表将多个字段的数据一起保存。

declare
 type company_array is table of emb.company%rowtype;
 v_company company_array;
begin
 select * bulk collect into v_company from company;
 for i in v_company.first .. v_company.last loop
     dbms_output.put_line('公司code:'||v_company(i).company_code||' 公司名称:'||v_company(i).company_name||' 公司等级:'||v_company(i).company_level);  
 end loop;
end;

输出结果:
公司code:10001 公司名称:总2公司 公司等级:1
公司code:2025 公司名称:深圳2分公司 公司等级:2
公司code:333 公司名称:测试分公司 公司等级:2

相关文章

网友评论

      本文标题:Oracle PL/SQL (6) - 集合运算符、FORALL

      本文链接:https://www.haomeiwen.com/subject/drxfphtx.html