2012-03-14 12 views
5

Voglio inserirmi in tabelle diverse con solo un singolo ciclo FORALL in oracle.but FORALL non supportarlo.anche idea come posso farlo ??Più istruzioni SQL nel ciclo 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;** 

risposta

10

FORALL non è un "comando di loop", è parte della sintassi per un'istruzione inserimento di massa. Quindi la soluzione corretta è scrivere la clausola FORALLA con ogni inserto:

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); 
+0

Anche io non sono in grado di chiamare la procedura all'interno di FORALL Loop .. ?? –

+3

È ** non ** un "loop"! No, puoi utilizzare solo FORALL con istruzioni DML. –

2

Non c'è bisogno di chiamare FORALL molte volte. Basta usare INSERT ALL istruzione 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;