Bulk collect insert using forall

Hi all,
in the following statement:
declare
cursor C is select id,PEOPLE_ID from CN_ITEMS;
type T_A is table of cn_items%rowtype;
V_A T_A;
begin
open c;
LOOP
fetch c bulk collect into v_a;
forall  I in V_A.first..V_A.last 
    insert into CN_TAXES(id,CREATION_DATE,TAX_PRICE,ITEM_ID,PEOPLE_ID)
                 values (CN_TAX_S.NEXTVAL, sysdate,10.5,v_a.id(i),v_a.people_id(i));
  exit when c%notfound;
end loop;
end;
/i receive error:
ORA-06550: line 13, column 2:
PLS-00394: wrong number of values in the INTO list of a FETCH statement
ORA-06550: line 13, column 2:
PL/SQL: SQL Statement ignored
ORA-06550: line 20, column 61:
PLS-00302: component 'ID' must be declared
ORA-06550: line 20, column 71:
PLS-00302: component 'PEOPLE_ID' must be declared
ORA-06550: line 20, column 71:
PLS-00302: component 'PEOPLE_ID' must be declared
ORA-06550: line 20, column 67:
PL/SQL: ORA-00904: "V_A"."PEOPLE_ID": invalid identifier
ORA-06550: line 19, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:Any ideas how to use in this situation FORALL? If i select all values from one table and then i use FORALL to insert them in another table with same columns is ok, but here i just want to use values from fetching to insert them in 2 columns of other table...
Version : 11g
Thanks in advance,
Bahchevanov.

>
Any ideas how to use in this situation FORALL? If i select all values from one table and then i use FORALL to insert them in another table with same columns is ok
>
You have answered your own question. The solution is exactly what you just said above
>
select all values from one table and then i use FORALL to insert them in another table with same columns
>
The first error you were getting
PLS-00394: wrong number of values in the INTO list of a FETCH statementis because of this code
cursor C is select id,PEOPLE_ID from CN_ITEMS;
type T_A is table of cn_items%rowtype;Your T_A variable is based on the CN_ITEMS table but since you are using a cursor you should base it on the cursor
cursor C is select id,PEOPLE_ID from CN_ITEMS;
type T_A is table of C%rowtype;You are also selecting ID but never using it. And you have an OUTER loop but did not use a LIMIT clause. A straight BULK COLLECT will collect everything at once so there is no purpose for the outer loop. But you should always use a limit clause rather than any implicit one.
So if you must use a bulk collect solution (even though your specifics should be using pure SQL) then to fix your problem change that code to this
cursor C is select CN_TAX_S.NEXTVAL, sysdate, 10.5,PEOPLE_ID from CN_ITEMS;
type T_A is table of C%rowtype;In other words just construct a row that will match your target table. Then you can use the FORALL to insert the entire row at once (note the LIMIT clause)
LOOP
fetch c bulk collect into v_a LIMIT 1000;
forall  I in V_A.first..V_A.last 
    insert into CN_TAXES(id,CREATION_DATE,TAX_PRICE,ITEM_ID,PEOPLE_ID)
                 values (V_A(I));
  exit when c%notfound;
end loop;

Similar Messages

  • Bulk collect into using vector in where clause

    Hi,
    I have a java stored procedure which takes an array as input and returns an array as output.
    I want to select a column in to a collection of array, using array as the select criteria.
    For example
    create or replace type My_list as table of varchar(20);
    create or replace type outarray as table of BLOB;
    create or replace function myfunction ( inputlist My_list)
    return outarray
    AS
    o_data := outarray();
    BEGIN
    SELECT mycolumn from mytable BULK COLLECT INTO o_data where my_creteria=inputlist
    retrun o_data;
    END;
    Unless I use FORALL I can not retrieve the inputlist values. I am not sure how I can use the bulk collect and forall in the same statement?
    My data is arranged such that , for each value in the inputlist one row will be fetched. I want to fetch all these rows at one go using the inputlist as select criteria,
    I can use the for i in inputlist.first .. inputlist.LAST and iterate the inputlist but that process is quite expensive interms of the latency.
    You help in optimizing my query would be highly appreciated.
    Regards,
    Syam

    That only leaves ugly solutions, like:
    <ul>
    <li>Using dynamic SQL to create a temporary table, doing a bulk insert of the incoming array and then reading the table values using a subquery with the IN opeartor.</li>
    <li>Building a dyanmic list, like ('value1','value2', ..) and use it with the IN operator, this is a variable list and requires DBMS_SQL package.</li>
    <li>Ignore the bulk operations. :-(</li>
    </ul>

  • Two inserts using FORALL in oracle version 10.1.0.5.0 - 64bi.

    Hi all,
    I am trying to insert values into one table based on the another table insert statement returning values.
    but i am unable to achieve this requirement using below code.
    DB Version :
    BANNER                                                        
    Oracle Database 10g Enterprise Edition Release 10.1.0.5.0 - 64bi
    PL/SQL Release 10.1.0.5.0 - Production                          
    CORE     10.1.0.5.0     Production                                        
    TNS for HPUX: Version 10.1.0.5.0 - Production                   
    NLSRTL Version 10.1.0.5.0 - Production
    sample code:
    CREATE TABLE EMP1 (EMPNO NUMBER(4));  
       CREATE TABLE EMP2 (EMPNO NUMBER(4));  
       DECLARE
    TYPE te_emp is table of  emp.empno%type;
    t_empno te_emp;
    l_empno NUMBER;
    begin
    select emp.empno bulk collect into t_empno from emp;
    forALL  i in 1..t_empno.COUNT 
        execute immediate
         'BEGIN
         insert into emp(empno) values(:1) RETURNING EMPNO into '||l_empno||';
         insert into emp(empno) values('||l_empno||');
         END;' using t_empno(i);
    end;  Please help me to achieve the requirement as mentioned above.
    Edited by: Rama Krishna.CH on Nov 7, 2012 6:39 PM

    SY,
    Thank you very much sir.But our DB's not interest to creating objects for this requirement. so I can achieve this requirement using below code.
      DECLARE
    TYPE td_empno is table of  number(4);
    t_empno td_empno;
    TYPE td_sal is table of  number;
    t_sal td_sal;
    l_empno NUMBER;
    begin
    select empno,sal  bulk collect into t_empno,t_sal from emp;
    forALL  i in 1..t_empno.COUNT 
    execute immediate
    'BEGIN
    insert into emp(empno,sal) values(:1,:2) RETURNING EMPNO into :3;
    insert into emp(empno,ename) values(:3,:4);
    END;' using t_empno(i),t_sal(i),in out l_empno,'rama';
    end; Is there any other way achieve this requirement with out declaring multiple pl/sql tables and type objects like below example.
    Using record data type.
    DECLARE
    TYPE rd_emp IS RECORD ( empno emp.empno%type
                           ,sal emp.sal%type
                           ,comm emp.comm%type);
    TYPE td_emp is table of  rd_emp;
    t_emp td_emp;
    l_empno NUMBER;
    begin
    select empno,sal,comm bulk collect into t_emp from emp;
    forALL  i in 1..t_emp.COUNT 
        execute immediate
          'DECLARE
           ere rd_emp;
          BEGIN
          ere := :1;
          ere := :2;
         insert into emp(empno,sal) values(ere.empno,ere.sal) RETURNING EMPNO into :2;
         insert into emp(empno) values(:2);
         END;' using t_emp(i),t_emp(i),in out l_empno;
    end;
      Sorry for not providing exact information at first time.

  • Bulk Collect Forall with CLOB

    I have a 10.2.0.4 database that contains a PL/SQL procedure that copies data from a singe remote 10.2.0.4 database table. The procedure will return anywhere from 50,000 to 500,000 rows of data. In testing I have made this a pretty speedy process using BULK COLLECT and using FORALL to load them in 2000 row batches. It has now been requested that I include an additional column from my source table which happens to be a CLOB datatype. However, when I try to perform this with the extra column I get the standard "cannot select remote lob locators" or whatever. Does anyone know of a way to perform this using BULK COLLECT? I've seen countless examples of doing it using "INSERT INTO TABLEX SELECT COL1, COL2, COL3, etc FROM TABLE Y@DBLINK". I don't want to do it this way for performance reasons. Any suggestions would be greatly appreciated.

    sjm133 wrote:
    I've seen countless examples of doing it using "INSERT INTO TABLEX SELECT COL1, COL2, COL3, etc FROM TABLE Y@DBLINK". I don't want to do it this way for performance reasons.What performance reasons are those then?
    Best thing to do would be to give it a go and see, and then if you find problems with it look for alternatives. Don't dismiss solutions without trying them. ;)

  • Where to put the commit in the FORALL BULK COLLECT LOOP

    Hi,
    Have the following LOOP code using FORALL and bulk collect, but didnt know where to put the
    'commit' :
    open f_viewed;
    LOOP
    fetch f_viewed bulk collect into f_viewed_rec LIMIT 2000;
    forall i in 1..f_viewed_rec.count
    insert into jwoodman.jw_job_history_112300
    values f_viewed_rec(i);
    --commit; [Can I put this 'commit' here? - Jenny]
    EXIT when f_viewed%NOTFOUND;
    END LOOP;
    commit;
    Thanks,
    - Jenny

    mc**** wrote:
    Bulk collect normally used with large data sets. If you have less dataset such as 1000-2000 records then you canot get such a performance improvent using bulk collect.(Please see oracle documents for this)
    When you update records Oracle acquire exclusive lock for that. So if you use commit inside the loop then it will process number of records defined by limit parameter at ones and then commit those changes.
    That will release all locks acquired by Oracle and also teh memory used to keep those uncommited transactions.
    If you use commit outside the loop,
    Just assume that you insert 100,000 records, all those records will store in oracle memory and it will affect all other users performance as well.
    Further more if you update 100,000 records then it will hold exclusive lock for all 100,000 records addtion to the usage of the oracle memory.
    I am using this for telco application which we process over 30 million complex records (one row has 234 columns).
    When we work with large data sets we do not depends with the oracle basic rollback function. because when you keep records without commit itb uses oracle memory and badly slowdown all other processes.Hi mc****,
    What a load of dangerous and inaccurate rubbish to be telling a new Oracle developer. Commit processing should be driven by the logical unit of a transaction. This should hold true whether that transaction involves a few rows or millions. If, and only if, the transaction is so large that it affects the size constraints of the database resources, in particular, rollback or redo space, then you can consider breaking that transaction up to smaller transactions.
    Why is frequent committing undesirable I hear you ask?
    First of all it is hugely wasteful of rollback or redo space. This is because while the database is capable of locking at a row level, redo is written at a block level, which means that if you update, delete or insert a million rows and commit after each individual statement, then that is a million blocks that need to go into redo. As many of these rows will be in the same block, if you instead do these as one transaction, then the same block in redo can be transacted upon, making the operation more efficient. True, locks will be held for longer, but if this is new data being done in batches then users will rarely be inconvenienced. If locking is a problem then I would suggest that you should be looking at how you are doing your processing.
    Secondly, committing brings into play one of the major serialization points in the database, log sync. When a transaction is committed, the log buffer needs to be written to disc. This occurs serially for multiple commits. Each commit has to wait until the commit before has completed. This becomes even more of a bottleneck if you are using Data Guard in SYNC mode, as the commit cycle does not complete until the remote log is notified as written.
    This then brings us two rules of thumb that will always lead a developer in the right direction.
    1. Commit as infrequently as possible, usually at the logical unit of a transaction
    2. When building transactions, first of all seek to do it using straight SQL (CTAS, insert select, update where etc). If this can't be easily achieved, then use PL/SQL bulk operations.
    Regards
    Andre

  • Forall with bulk collect .. getting error

    it's 10 g.
    gettting this error.
    drop table t2;
    create table t2
    ( seq_id number,
      act number,
       is_p varchar2(1),
      other varchar2(20)
    insert into t2 values(1,2,'N','Test 1');
    drop table t3;
    create table t3
    ( seq_id number
    -- ,act number
    --  ,is_p varchar2(1)
    set serveroutput on
    declare
    type t2_r is table of t2%ROWTYPE;
    cursor c1 is select * from t2 ;
      t t2_r;
    begin
    open c1;
    fetch c1 BULK collect into t;
    forall i in 1..t.count
       insert into t3(seq_id) values (t(i).seq_id);
    end;
    ORA-06550: line 10, column 35:
    PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
    ORA-06550: line 10, column 35:
    PLS-00382: expression is of wrong type
    ORA-06550: line 10, column 35:
    PL/SQL: ORA-22806: not an object or REF
    ORA-06550: line 10, column 4:
    PL/SQL: SQL Statement ignored

    The PLS-00436 is an annoying error message indeed.
    On 10g:
    rwijk@ORA10GR2> create table t2
      2  ( seq_id number,
      3    act number,
      4     is_p varchar2(1),
      5    other varchar2(20)
      6  );
    Tabel is aangemaakt.
    rwijk@ORA10GR2> insert into t2 values(1,2,'N','Test 1');
    1 rij is aangemaakt.
    rwijk@ORA10GR2> create table t3
      2  ( seq_id number
      3   -- ,act number
      4   --  ,is_p varchar2(1)
      5  );
    Tabel is aangemaakt.
    rwijk@ORA10GR2> declare
      2   type t2_r is table of t2%ROWTYPE;
      3   cursor c1 is select * from t2 ;
      4    t t2_r;
      5  begin
      6    open c1;
      7    fetch c1 BULK collect into t;
      8    forall i in 1..t.count
      9     insert into t3(seq_id) values (t(i).seq_id);
    10    close c1;
    11  end;
    12  /
       insert into t3(seq_id) values (t(i).seq_id);
    FOUT in regel 9:
    .ORA-06550: Regel 9, kolom 35:
    PLS-00436: Implementatierestrictie: kan niet verwijzen naar velden van BULK In-BIND-recordtabel..
    ORA-06550: Regel 9, kolom 35:
    PLS-00382: Uitdrukking heeft onjuist type..
    ORA-06550: Regel 9, kolom 35:
    PL/SQL: ORA-22806: Geen object of REF..
    ORA-06550: Regel 9, kolom 4:
    PL/SQL: SQL Statement ignored.You can code it slightly different using SQL object types like this, to make the code work in 10g:
    rwijk@ORA10GR2> create type t2_otype is object
      2  ( seq_id number
      3  , act number
      4  , is_p varchar2(1)
      5  , other varchar2(20)
      6  );
      7  /
    Type is aangemaakt.
    rwijk@ORA10GR2> create type t2s is table of t2_otype;
      2  /
    Type is aangemaakt.
    rwijk@ORA10GR2> declare
      2    cursor c1 is select t2_otype(seq_id,act,is_p,other) from t2 ;
      3    t t2s;
      4  begin
      5    open c1;
      6    fetch c1 BULK collect into t;
      7    forall i in 1..t.count
      8      insert into t3(seq_id) values (treat(t(i) as t2_otype).seq_id);
      9    close c1;
    10  end;
    11  /
    PL/SQL-procedure is geslaagd.On 11g, as said, you don't have to modify your code:
    rwijk@ORA11G> create table t2
      2  ( seq_id number,
      3    act number,
      4     is_p varchar2(1),
      5    other varchar2(20)
      6  );
    Tabel is aangemaakt.
    rwijk@ORA11G> insert into t2 values(1,2,'N','Test 1');
    1 rij is aangemaakt.
    rwijk@ORA11G> create table t3
      2  ( seq_id number
      3   -- ,act number
      4   --  ,is_p varchar2(1)
      5  );
    Tabel is aangemaakt.
    rwijk@ORA11G> declare
      2   type t2_r is table of t2%ROWTYPE;
      3   cursor c1 is select * from t2 ;
      4    t t2_r;
      5  begin
      6    open c1;
      7    fetch c1 BULK collect into t;
      8    forall i in 1..t.count
      9     insert into t3(seq_id) values (t(i).seq_id);
    10    close c1;
    11  end;
    12  /
    PL/SQL-procedure is geslaagd.Regards,
    Rob.

  • ORA-22167 when using RETURNING... BULK COLLECT INTO feature

    I posted this on the General Board, but I'm still having the issue. Any help would be appreciated!
    I'm loading raw data into a staging table, and want to perform a series of validations before moving it into the system. Records that fail are marked invalid in the stage table, and then an error message written to another table. When updating the 'invalid' flag in the (database) stage table, I return the record identifier into a pl/sql table, then iterate through said table to insert into my (database) error table. This works great for my first validation, but when I use the pl/sql table for the second validation, I get ORA-22167, which basically complains about the subscript supplied to TRIM being out of range. I've tried DELETEing the pl/sql table, setting it to NULL, re-initializing it... none of which works. I have also tried using a brand new table for each validation, but I still get the same message. What am I missing?
    Psuedo-code is like this (please ignore any syntax errors... real code is syntactically correct) :
    DECLARE
    TYPE RECORD_SEQ_TBL IS TABLE OF fcsf_arc.record_seq_nbr%TYPE;
    lt_bad_fcsf_tbl RECORD_SEQ_TBL := NULL;
    BEGIN
    UPDATE <stg_tbl>
    SET valid_ind = 'N'
    WHERE <error condition 1>
    RETURNING seq_nbr BULK COLLECT INTO lt_bad_fcsf_tbl;
    FORALL j IN lt_bad_fcsf_tbl.FIRST..lt_bad_fcsf_tbl.LAST
    INSERT INTO <error_tbl>
    VALUES ('message', lt_bad_fcsf_tbl(j));
    -- works ok so far...
    -- I've tried various combinations of the next three comments to no avail (including doing nothing at all)
    -- lt_bad_fcsf_tbl.DELETE;
    -- lt_bad_fcsf_tbl := NULL;
    -- lt_bad_fcsf_tbl := RECORD_SEQ_TBL();
    -- now I want to do my second validation
    UPDATE <stg_tbl>
    SET valid_ind = 'N'
    WHERE <error condition 2>
    RETURNING seq_nbr BULK COLLECT INTO lt_bad_fcsf_tbl;
    -- and THAT is where I get the ORA-22167

    Thanks for the pointer, Sy. I'm trying to track down soembody with a valid metalink account... everybody I know that has one is getting 'invalid login' messages.
    In the meantime, I have switched from nested tables to associative arrays, and this change seems to be working (so far).
    Thanks again for your feedback!

  • Approach of using Bulk Collect

    Hi Experts,
    how to use bulk collect for uncertain number of columns of select statement.
    Master table structure:
    Create table tabmst
    (id number,
    cls_input varchar2(2000),
    price number);
    insert into tabmst(1,'select product, price from product',500);
    insert into tabmst(2,'select product, price,purchase_dt from product',100);
    insert into tabmst(3,'select * from product',1000);
    Currently I want to store Select statement of cls_input column in a local variable like
    dyn_qry:= cls_input; by using a cursor.
    Now my question is how to use Bulk Collect by using "Execute Immediate" in Bulk collect variable as there is not certainity of the number of columns from "Select Statment". Please suggest.
    Sample code:
    I created TYPE variable for Bulk Collect also support blk_var;
    Declare
    dyn_qry varchar2(3000);
    cursor c1 is select * from tabmst;
    begin
    for i in c1 loop
    dyn_qry:= cls_input;
    Execute immediate dyn_qry into blk_var;
    End Loop;
    End;
    Now I want to store values of Each "Select statements columns" which is executing by dynamic SQL. but it is uncertain that how many columns with return from dynamic SQL.
    Please suggest the approach on the same. Thanks in advance.

    >
    I don't think you can use bulk collect with EXECUTE IMMEDIATE. They do two different things. EXECUTE IMMEDIATE allows the execlution of dynamic SQL. BULK COLLECT provides optimization of SELECT statements when loading the contents into collections. I am not aware of any support for BULK COLLECT with EXECUTE IMMEDIATE.
    You may be able to do this a different way. If you must use dynamic SQL (I suggest you don't unless it is absolutely necessary. Dynamic SQL is hard to write, hard to debug, hard to maintain, and hard to tune) use a reference cursor instead. You can use the BULK COLLECT with the standard fetch.

  • FORALL inserts using database link

    Hi,
    is there any way work around by which we can implement bulk inserts using FORALL across database link ?
    regards
    nic

    How about using a view as a layer to hide the db-link?
    Don't know if that will work.
    Also possible:
    Instead of "INSERT INTO targetTable@dbLink as SELECT * FROM sourceTable"
    do "INSERT INTO myTable AS SELECT * FROM sourcetable@dbLink" on the other database.

  • How to call BULK COLLECT using JDBC in JSP?

    Hi
    I am using BULK COLLECT instead of CURSOR in my Stored Procedure.
    How to use these stuff in JDBC.
    If i am using CURSOR means
    cs.registerOutParameter(1,oracle.jdbc.driver.OracleTypes.CURSOR);
    is used.
    Which types i have to use?
    I am retriving morethan one record using FOR. LOOP in SP and before that
    BULK COLLECT is used in SELECT query..
    Can you give jsp code for this?
    Thanks

    you may find related sample jdbc code on otn - http://www.oracle.com/technology/sample_code/tech/java/sqlj_jdbc/index.html
    Best regards.

  • Bulk collect into statement

    Hello All,
    I am trying to copy data using database link.
    I am using Oracle 11g on Windows.
    I check data in source table and it exists. When I execute below block it successfully executes but return no data in target database.
    SET SERVEROUTPUT ON
    DECLARE
      TYPE t_bulk_collect_test_1 IS TABLE OF NT_PROP%ROWTYPE;
      l_tab1 t_bulk_collect_test_1;
      CURSOR c_data1 IS
        SELECT *
        FROM NT_PROP@dp_copy;
    BEGIN
      OPEN c_data1;
      LOOP
        FETCH c_data1
        BULK COLLECT INTO l_tab1 LIMIT 10000;
        commit;
      EXIT WHEN l_tab1.count = 0;
      END LOOP;
      CLOSE c_data1;
    END;
    Could someone please let me know what is the eror in this code.
    Thanks in advance

    I think you are expecting BULK INSERT using FORALL. Please see below example.
    See below link also
    http://www.oracle-base.com/articles/9i/bulk-binds-and-record-processing-9i.php#save_exceptions
    DECLARE
      TYPE t_bulk_collect_test_1 IS TABLE OF NT_PROP%ROWTYPE;
      l_tab1 t_bulk_collect_test_1;
      CURSOR c_data1 IS
        SELECT *
        FROM NT_PROP@dp_copy;
        ex_dml_errors EXCEPTION;
         PRAGMA EXCEPTION_INIT(ex_dml_errors, -24381);
    BEGIN
      OPEN c_data1;
      LOOP
        FETCH c_data1
        BULK COLLECT INTO l_tab1 LIMIT 10000;
        BEGIN
          forall i in l_tab1.first..l_tab1.count  save exceptions
           insert into target_tab values l_tab1(i);
        EXCEPTION
              WHEN ex_dml_errors THEN
              l_error_count := SQL%BULK_EXCEPTIONS.count;
              DBMS_OUTPUT.put_line('Number of failures: ' || l_error_count);
          FOR i IN 1 .. l_error_count LOOP
            DBMS_OUTPUT.put_line('Error: ' || i ||
              ' Array Index: ' || SQL%BULK_EXCEPTIONS(i).error_index ||
              ' Message: ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
          END LOOP;
        END;
      EXIT WHEN l_tab1.count = 0;
      END LOOP;
      CLOSE c_data1;
    END;
    Cheers,
    Suri

  • Bulk Collect Problem

    I have table Tab1 has 20 columns
    i have table tab2 has 10 columns , i want you uses the bulk collect insert in tab2 to tab 1 only selected columns from the tab1 .
    TYPE ARRAY IS TABLE OF tab2%ROWTYPE;
    l_tab_array ARRAY;
    BEGIN
    SELECT * BULK COLLECT INTO l_tab_array
    FROM tab1;
    FORALL x in l_tab_array.First..l_tab_array.Last
    INSERT INTO tab2(column1,column2 ) VALUES l_tab_array(x) ; --please tell me how to access the array column.
    END;
    i tried INSERT INTO tab2(column1) VALUES (l_tab_array(x).col1)
    10:21:07 AM 47/61 PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
    10:21:07 AM 47/61 PLS-00382: expression is of wrong type
    10:21:07 AM 47/61 PL/SQL: ORA-22806: not an object or REF
    please give the insert statement with array .
    Regards
    ram
    Edited by: Mani on Feb 10, 2011 3:19 PM

    Yep - this is a right pain in older versions of Oracle.
    You need to have one associative array per column.
    Also see this article from Adrian Billington about alternatives:
    http://www.oracle-developer.net/display.php?id=410
    However, it may be that you're misusing collections etc when the best solutions is always a SQL single statement:
    INSERT
    INTO ...
    SELECT..
    Edited by: Dom Brooks on Feb 10, 2011 3:25 PM

  • Bulk Collect for Uncertain columns

    Hi Experts,
    how to use bulk collect for uncertain number of columns of select statement.
    Master table structure:
    Create table tabmst
    (id number,
    cls_input varchar2(2000),
    price number);
    insert into tabmst(1,'select product, prod_price from product',500);
    insert into tabmst(2,'select product, prod_price,purchase_dt from product',100);
    insert into tabmst(3,'select * from product',1000);
    Currently I want to store Select statement of cls_input column in a local variable like
    dyn_qry:= cls_input; by using a cursor.
    Now my question is how to use Bulk Collect by using "Execute Immediate" in Bulk collect variable as there is not certainity of the number of columns from "Select Statment". Please suggest.
    Sample code:
    I created TYPE variable for Bulk Collect also support blk_var;
    Declare
    dyn_qry varchar2(3000);
    v_id number;
    v_prod_price number;
    v_product number;
    cursor c1 is select * from tabmst;
    begin
    for i in c1 loop
    v_id:=i.id;
    dyn_qry:= i.cls_input;
    Execute immediate dyn_qry into blk_var;
    (Here I want to store the columns values from "blk_var" in local variables "v_prod_price" ; "v_product" ;. But it is uncertains of the columns of "Select statement")
    End Loop;
    End;
    Now I want to store values of Each "Select statements columns" which is executing by dynamic SQL. but it is uncertain that how many columns will return from dynamic SQL.
    Please suggest the approach on the same. Thanks in advance.

    Hi,
    please do not post duplicated questions. Close (marking as answered and putting a note) your other thread regarding the same topic: {message:id=10890093}.
    Additionally when you put some code or output please enclose it between two lines starting with {noformat}{noformat}
    i.e.:
    {noformat}{noformat}
    SELECT ...
    {noformat}{noformat}
    Regards.
    Al                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • What is differenct between normal insert and forall insert.

    Hi,
    i am little bit confused about following 2 types of inserts.
    insert into TableA
    select * from TableB
    and
    insert using forAll statment.
    which one is faster and why.

    Pankaj M wrote:
    insert into TableA
    select * from TableB
    and
    insert using forAll statment.
    which one is faster and why.The first, insert ... select.
    Because you just insert and don't need to fetch the results anywhere and allocate memory and less code executes in less time.

  • Issue in using Cursor+Dynamic SQL+ Bulk collect +FORALL

    Hi,
    I have a dynamic query which I need to use as a cursor to fetch records that inturn need to be inserted into a staging table.
    The issue I am facing is I am not sure how to declare the variable to fetch the records into. Since I am using a dynamic cursor how do I declare it?
    My code looks something like this -
    TYPE c_details_tbl_type IS REF CURSOR;
    c_details c_details_tbl_type;
    TYPE c_det_tbl_type IS TABLE OF c_details%ROWTYPE INDEX BY PLS_INTEGER;
    c_det_tbl c_det_tbl_type; -- ???
    BEGIN
    v_string1 := 'SELECT....'
    v_string2 := ' UNION ALL SELECT....'
    v_string3 := 'AND ....'
    v_string := v_string1||v_string2||v_string3;
    OPEN c_details FOR v_string;
    LOOP
    FETCH c_details BULK COLLECT
    INTO c_det_tbl LIMIT 1000;
    IF (c_det_tbl.COUNT > 0) THEN
              DELETE FROM STG;
              FORALL i IN 1..c_det_tbl.COUNT
              INSERT INTO STG
              VALUES (c_det_tbl(i));
    END IF;
    EXIT WHEN c_details%NOTFOUND;
    END LOOP;
    CLOSE c_details;
    END
    Thanks

    Why the bulk collect? All that this does is slow down the read process (SELECT) and write process (INSERT).
    Data selected needs (as a collection) to be pushed into the PGA memory of the PL/SQL engine. And then that very same data needs to be pushed again by the PL/SQL engine back to the database to be inserted. Why?
    It is a lot faster, needs a lot less resources, with fewer moving parts, to simply instruct the SQL engine to do both these steps using a single INSERT..SELECT statement. And this can support parallel DML too for scalability when data volumes get large.
    It is also pretty easy to make a single SQL statement like this dynamic and even support bind variables.
    Simplicity is the ultimate form of elegance. Pushing data needlessly around is not simple and thus not a very elegant way to address the problem.

Maybe you are looking for

  • Runtime Error while creation of rule for IU elimination

    Hi, Following runtime error occuring while creating a rule under IU elimination method. Error analysis                                                                                A RAISE statement in the program "CL_UC_SINGLESELCOND_FACTORY===CP"

  • Problem with Model View

    hi friends, i am working with ALE to transfer data across two clients. i had created two logical system EDI900, EDI950 and model view MODEL_VIEW but when i am distribute this model view i am getting error as model view MODEL_VIEW has  not been update

  • Steps on ecc6 installation in suse linux

    hi sir/madams i am new in ecc6 installation on linux systesm please provide a sap installation steps on suse linux...and thankul to all regads suresh

  • Do we need to create another account?

    We have multiple ipod owners in our family. We keep out music together and up until now we have had one account which we used to purchase music. Now a couple of family members have received gift cards and we would like to make sure they get to use th

  • Change billed Qty from Billing Due List

    Hi, I want to edit the billed Qty from an SO item that is displayed after selection in my Maintain Billing Due List.  The ...Overview of Billing Items screen does not have the Selection List button, as compared to the VF01 screen which has the button