将迭代的提取替换为BULK COLLECT

时间:2011-09-30 03:29:54

标签: database oracle plsql cursor

有一个对象类型和表由这些对象组成。 所以我们走了:

create or replace type lpu.someobj_o as object
(      
  name VARCHAR2(75),     
  enroll_date DATE,
  id NUMBER(12)
)

CREATE OR REPLACE TYPE lpu."SOMEOBJ_T" IS TABLE OF someobj_o;

PL / SQL函数也可以在ETL principle中使用。这是一段代码函数:

  for some_cursor_rec in some_cursor(startTime, recordInterval) loop
  open some_cur2(some_cursor_rec.name, some_cursor_rec.id);
  fetch some_cur2 into some_cursor_rec2;
  if some_cur2%rowcount > 0 then
    loop
      pipe row (
        lpu.someobj_o(
        id => some_cursor_rec2.id, 
        name => some_cursor_rec2.name, 
        enroll_date => some_cursor_rec2.enroll_date
      )
      );
      fetch some_cur2 into some_cursor_rec2;
      exit when some_cur2%notfound;
    end loop;      
  end if;
  close some_cur2;
end loop;

好的,问题是性能不佳。如何提高完成此功能的速度?我已经读过BULK COLLECT应该提高性能。但是我怎么能在我的情况下使用它呢?我试过BULK COLLECT,但它给了我错误,那种集合是错误的。 提前致谢!非常希望得到你的帮助!

2 个答案:

答案 0 :(得分:4)

如果您关注性能,那么您应该开始考虑组合两个游标。

当前您正在some_cursor中执行一次查询,并且在游标some_cur2中执行查询的次数与第一次查询中选择的行数的次数相同。这很可能是你的性能瓶颈。

如果将两个查询组合到一个查询并为循环执行游标(仅执行一次查询),那么您将自动批量一次获取100行,因此可能不会是真实的需要手动将其转换为批量提取。

的问候,
罗布。

答案 1 :(得分:0)

以下是如何将bulk collect into与对象类型一起使用的基本示例。

create or replace type someobj_o as object
(      
  name varchar2(75),     
  enroll_date date,
  id number(12)
);
/

create or replace type someobj_t is table of someobj_o;
/

create table someobj_table of someobj_o;

insert into someobj_table values(someobj_o('Joe', current_date, 100));
insert into someobj_table values(someobj_o('Jack', current_date, 101));
insert into someobj_table values(someobj_o('John', current_date, 102));

declare
  v_objs someobj_t;
begin
  select someobj_o(name, enroll_date, id)
    bulk collect into v_objs
    from someobj_table;

  dbms_output.put_line('number of objects in a collection = ' || v_objs.count);
end;
/

<强>更新

与光标相同:

declare
  type objcur_t is ref cursor;
  v_objcur objcur_t;
  v_objs someobj_t;
begin
  open v_objcur for
    select someobj_o(name, enroll_date, id)
    from someobj_table;

  fetch v_objcur bulk collect into v_objs;

  close v_objcur;

  dbms_output.put_line('number of objects in a collection = ' || v_objs.count);
end;
/