FORALL 循环中的多个 SQL 语句

Posted

技术标签:

【中文标题】FORALL 循环中的多个 SQL 语句【英文标题】:Multiple SQL statements in FORALL loop 【发布时间】:2012-03-14 13:13:10 【问题描述】:

我想在 oracle 中只用一个 FORALL 循环插入不同的表。但是 FORALL 不支持它。知道我该怎么做吗??

   create or replace PROCEDURE test IS
      TYPE avl_web_details IS TABLE OF available_web_details%ROWTYPE;
      var_avl_web_details avl_web_details := avl_web_details();
      UNIONTABLE VARCHAR2(30000);
      TYPE RepCurTyp IS REF CURSOR; 
      Rep_cv RepCurTyp; 
   BEGIN
      UNIONTABLE := '';
  execute immediate 'update tbl_used_webuda1 set flag=1';
  FOR tbl IN (SELECT tablename FROM tbl_used_webuda1 where flag=1)
      LOOP             
    UNIONTABLE := UNIONTABLE || 'select *' || ' from ' || tbl.tablename || 'union all ';     
END LOOP;

       IF (LENGTH(UNIONTABLE) > 10) THEN
      UNIONTABLE := '( ' || SUBSTR(UNIONTABLE,1, length(UNIONTABLE)-10) || ' ) ';            
     end if;
      OPEN Rep_cv FOR 'select from_unixtime("5mintime") as "5mintime",username,host,src_zone,domain,dst_zone,content,category,url,hits ,bytes,appid ,application,categorytype,usergroup from'|| uniontable;
LOOP 
    FETCH Rep_cv BULK COLLECT INTO var_avl_web_details LIMIT 200000;
        FORALL i IN 1..var_avl_web_details.COUNT
            insert into available_web_details values var_avl_web_details(i);
    insert into web_ap_ca_co_do_ur_us_5min values(ts ,var_avl_web_details(i).application ,var_avl_web_details(i).category ,var_avl_web_details(i).content ,var_avl_web_details(i).domain ,var_avl_web_details(i).dst_zone ,var_avl_web_details(i).url ,var_avl_web_details(i).username ,var_avl_web_details(i).hits,var_avl_web_details(i).bytes,var_avl_web_details(i).appid);     
    insert into web_user_5min values(ts,var_avl_web_details(i).username,var_avl_web_details(i).hits,var_avl_web_details(i).bytes,var_avl_web_details(i).appid);
    EXIT WHEN Rep_cv%NOTFOUND; 
end loop; 
close rep_cv; 
end;**

【问题讨论】:

【参考方案1】:

FORALL 不是“循环命令”,它是批量插入语句语法的一部分。所以正确的解决方案是在每次插入时都写 FORALL 子句:

FORALL i IN 1..var_avl_web_details.COUNT
    insert into available_web_details values var_avl_web_details(i);

FORALL i IN 1..var_avl_web_details.COUNT 
    insert into web_ap_ca_co_do_ur_us_5min values(ts ,var_avl_web_details(i).application ,var_avl_web_details(i).category ,var_avl_web_details(i).content ,var_avl_web_details(i).domain ,var_avl_web_details(i).dst_zone ,var_avl_web_details(i).url ,var_avl_web_details(i).username ,var_avl_web_details(i).hits,var_avl_web_details(i).bytes,var_avl_web_details(i).appid);      

FORALL i IN 1..var_avl_web_details.COUNT
    insert into web_user_5min values(ts,var_avl_web_details(i).username,var_avl_web_details(i).hits,var_avl_web_details(i).bytes,var_avl_web_details(i).appid);

【讨论】:

即使我无法在 FORALL 循环中调用过程..?? 不是一个“循环”!不,您只能将 FORALL 与 DML 语句一起使用。【参考方案2】:

无需多次调用 FORALL。只需使用 INSERT ALL DML 语句。


forall i in v_list.first..v_list.last
  insert all
    into t116 (id) values (v_list(i))
    into t117 (id) values (v_list(i))
      select 1 from dual;

【讨论】:

以上是关于FORALL 循环中的多个 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL 如何输出在 FORALL 语句中进行了多少次插入

在 PL/SQL Oracle 中将 FOR 语句转换为 FORALL

PL/SQL批处理语句BULK COLLECT

如何使用多个 for 循环在 php 中创建 sql 语句

Forall 语句适用于 PDDL 域中的元素子集?

Fortran forall 限制