批量收集和ForAll - Oracle

时间:2016-04-26 22:03:53

标签: oracle bulk forall

我正在寻找从记录类型(按表索引)访问列的语法。下面是示例代码。我如何在下面的Declare块中运行Update脚本,该块需要来自V_Emprec记录类型的empid。我创建了一个proc,它也需要相同的参数(empid)。

可以使用%Rowtype完成,还是需要使用emp_stage.empid%type创建类型? 如果我为Empid和Ename创建2个TYPES为emp_stg.column_name%type,我可以使用它们来替换使用Rowtype v_emprec的Insert脚本吗?

请告诉语法执行此操作。

create table emp_master(empid number, ename varchar2(50));
create table emp_stage (empid number, ename varchar2(50));
create procedure update_emp_name(P_empid in emp_master.empid%type)
is
begin
Update emp_stage set ename =INITCAP(ename) WHERE EMPID =P_empid;
commit;
end;

Declare
Type emprec is table of emp_master%rowtype index by pls_integer;
v_emprec emprec;
Begin
Select empid,ename bulk collect into v_emprec from emp_master;
ForAll i in 1..v_emprec.count
Insert into emp_stage values v_emprec(i);
Update emp_stage set ename =INITCAP(ename) WHERE EMPID =v_emprec.empid(i);
 /*Need Correct Syntax to use empid from the v_emprec type*/           
update_emp_name(); 
commit;
End;

由于

1 个答案:

答案 0 :(得分:0)

您可以在第二个forall中执行更新,并像引用任何记录字段或表列一样引用记录字段;你只是在错误的地方索引引用:

ForAll i in 1..v_emprec.count
  Insert into emp_stage values v_emprec(i);
ForAll i in 1..v_emprec.count
  Update emp_stage set ename = INITCAP(ename)
  WHERE EMPID = v_emprec(i).empid;

您无法使用forall调用过程,它只允许使用DML。您可以使用正常的for循环:

for i in 1..v_emprec.count loop         
  update_emp_name(v_emprec(i).empid);
end loop;

但是,由于这会进行单行逐行更新,并产生额外的上下文切换,因此效率低于forall方法;或者确实是所有行的单个更新。您还可以在执行插入之前循环集合并插入字段:

for i in 1..v_emprec.count loop         
  v_emprec(i).ename := INITCAP(v_emprec(i).ename);
end loop;
ForAll i in 1..v_emprec.count
  Insert into emp_stage values v_emprec(i);

或者更改插入以分别引用字段并在插入期间执行initcap(这也不适用于10g)。或者在查询中执行initcap:

Select empid, INITCAP(ename) bulk collect into v_emprec from emp_master;
ForAll i in 1..v_emprec.count
  Insert into emp_stage values v_emprec(i);