首页 > 解决方案 > oracle 使用 sys refcursor 批量收集限制子句执行详细信息

问题描述

我正在创建一个存储过程,以使用 limit 子句将数据从一个表(表 1)批量收集到另一个表(表 2)。

例如,如果我正在加载 80000 条记录,限制子句为 1000,那么 sys refcursor 中的 select 语句被执行了多少次?它会执行一次还是每个限制的迭代(80000/1000)= 80 次?

请有人提供有关处理的更多详细信息。

代码骨架片段

create or replace procedure <procedure_name> as
<curosor name> SYS_REFCURSOR;
< collection_name > ;
begin
  open <cursor_name> for <select statment>;
  loop 
    fetch <cursor_name> into < collection_name >  limit 1000;
    exit when <cursor_name>%not_found;
    forall i in 1..<collection_name>.count
        insert statement into to table 2 values <i>
  end loop;

标签: oracleplsqlsql-limitbulk-collect

解决方案


数据库将执行一次游标。但它会从中获取( # rows / limit ) + 1时间。

您可以通过跟踪会话和格式化跟踪文件来验证这一点:

create table t (
  c1 int
);

exec dbms_monitor.session_trace_enable ( waits => true, binds => true );
declare
  cur sys_refcursor; 

  arr dbms_sql.number_table;
begin
  open cur for
    select level c1 from dual
    connect by level <= 10000;
  loop
    fetch cur 
    bulk collect into arr
    limit 100;
    exit when arr.count = 0;

    forall rw in 1 .. arr.count 
      insert into t values ( arr ( rw ) );
  end loop;
  close cur;
end;
/
exec dbms_monitor.session_trace_disable ();

这将在数​​据库服务器上生成一个跟踪文件。您可以使用此查询找到位置:

select value
from   v$diag_info
where  name = 'Default Trace File';

使用TKPROF格式化文件,您会看到如下内容:

SELECT LEVEL C1 
FROM
 DUAL CONNECT BY LEVEL <= 10000


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch      101      0.00       0.01          0          0          0       10000
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      103      0.01       0.01          0          0          0       10000

执行 = 1,获取 = 101


推荐阅读