bulk collect with limit

code is: cursor here can fetch a large amount of data (22000 records). So I have to go with the limit clause. I use two foralls. This code snippet is correct with regard to the two foralls, exit and % bulk_rowcount sql statement? I have to use in production. Is there something that can break the code?

OPEN c1;
LOOP
C1 FETCH BULK COLLECT WITHIN the limits of the 100 id_array;
FORALL i IN id_array. FIRST... id_array. LAST
Update statement;
BECAUSE me IN id_array. FIRST... id_array. LAST
LOOP
v_cnt: = v_cnt + SQL % BULK_ROWCOUNT (i);
END LOOP;
FORALL i IN id_array. FIRST... id_array. LAST
Insert statement;
WHEN id_array EXIT. COUNT = 0;
END LOOP;
CLOSE c1;

In addition, how context switching works when we use the llimit clause?
without limit:
collection is completely filled. then prepares to all the DML statements and go to sql and exeutes one by one.
right?
tasted clause say limit = 100
100 indexes collection gets populated.then prepares all the DML statements for these 100 indices and go to the DTF sql and exeutes. And then back to pl/sql. fills the same 100 indices collection with 100 records and prepares the DML and goes to sql to run and returns to pl/sql and so on? Is this true?
right?

large volume of data (22000 records)

This isn't a large volume of data.

In addition, how context switching works when we use the llimit clause?

You will find some good explanations here:

http://www.Oracle.com/technology/tech/pl_sql/PDF/doing_sql_from_plsql.PDF

Tags: Database

Similar Questions

  • Doubt on bulk collect with LIMIT

    Hello

    I have a doubt on in bulk to collect, when did Commit

    I have an example in PSOUG
    http://psoug.org/reference/array_processing.html
    CREATE TABLE servers2 AS
    SELECT *
    FROM servers
    WHERE 1=2;
    
    DECLARE
     CURSOR s_cur IS
     SELECT *
     FROM servers;
    
     TYPE fetch_array IS TABLE OF s_cur%ROWTYPE;
     s_array fetch_array;
    BEGIN
      OPEN s_cur;
      LOOP
        FETCH s_cur BULK COLLECT INTO s_array LIMIT 1000;
    
        FORALL i IN 1..s_array.COUNT
        INSERT INTO servers2 VALUES s_array(i);
    
        EXIT WHEN s_cur%NOTFOUND;
      END LOOP;
      CLOSE s_cur;
      COMMIT;
    END;
    If my table servers were 3 000 000 files, when do we commit? When I insert all records?
    could crash redo log?
    using 9.2.08

    muttleychess wrote:
    If my table servers were 3 000 000 files, when do we commit?

    Commit point has nothing to do with how many rows treat you. It's purely commercial leads. Your code implements a commercial operation, right? So if you're getting into before any trancaction (from the commercial point of view) other sessions will be already see changes that are (from a business point of view) incomplete. In addition, what happens if rest of trancaction (from the commercial point of view) goes down?

    SY.

  • Bulk Collect and limit the rows

    Hello Oracles,

    I feel a strange (at least to me) behavior with lines in BULK COLLECT and LIMIT.
    For test purposes, I've written a procedure that uses a CURSOR, explicit AND implicit.
    When I use the explicit CURSOR and the LOOP, I use BULK COLLECT and LIMIT lines.
    I do not ROWNUM limit with my SELECT INTO. I know for a fact ROWNUM works very well since the last millennium.
    When I look at the number of rows returned when I put the LIMIT, I get weird number of extractions...

    I recover in a TABLE INDEX BY which is based on a TYPE of ENTRY.
    Here are a few results with different LIMIT values for a small group of key PRIMARIES.
    The figures below are the value of my_table . COUNTY

    Any idea would be apreciated.

    THX

    . .
    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 78 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 78 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 78 retrieves: 27
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . Retrieves LOOP IN BULK COLLECT LIMIT 78: 37
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . Excerpt from LOOP BULK COLLECT LIMIT 78: 47

    *************************************************
    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 100 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 100 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 100 retrieves: 83
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 100 retrieves: 93
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 100 retrieves: 93

    *************************************************

    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 140 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 140 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 140 retrieves: 43
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 140 retrieves: 53
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 140 retrieves: 33

    *************************************************
    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 183 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 183 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 183 retrieves: 0
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 183 retrieves: 10
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 183 retrieves: 44

    *************************************************

    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 200 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 200 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 200 retrieves: 183
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 200 retrieves: 193
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 200 retrieves: 193

    *************************************************

    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 600 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 600 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 600 retrieves: 183
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 600 retrieves: 193
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 600 retrieves: 593

    *************************************************
    Actual number of CURSOR EXPLICIT 470553 PK = 17
    . LOOP IN BULK COLLECT LIMIT 593 retrieves: 17
    .
    Actual number of CURSOR EXPLICIT 100991 PK = 38
    . LOOP IN BULK COLLECT LIMIT 593 retrieves: 38
    .
    Actual number of CURSOR EXPLICIT 100981 PK = 183
    . LOOP IN BULK COLLECT LIMIT 593 retrieves: 183
    .
    Actual number of CURSOR EXPLICIT 101001 PK = 193
    . LOOP IN BULK COLLECT LIMIT 593 retrieves: 193
    .
    Actual number of CURSOR EXPLICIT 101033 PK = 593
    . LOOP IN BULK COLLECT LIMIT 593 retrieves: 0

    PL/SQL procedure successfully completed.

    SQL > spool off

    I love a mystery, so I figured out how your code might look like:

    SQL> create table t
      2  as
      3  select case n1
      4         when 1 then 470553
      5         when 2 then 100991
      6         when 3 then 100981
      7         when 4 then 101001
      8         when 5 then 101033
      9         end pk
     10    from (select level n1 from dual connect by level <= 5)
     11       , (select level n2 from dual connect by level <= 593)
     12   where (  (n1 = 1 and n2 <= 17)
     13         or (n1 = 2 and n2 <= 38)
     14         or (n1 = 3 and n2 <= 183)
     15         or (n1 = 4 and n2 <= 193)
     16         or (n1 = 5 and n2 <= 593)
     17         )
     18  /
    
    Tabel is aangemaakt.
    
    SQL> declare
      2    type ta is table of number;
      3    a_limitsizes ta := ta(78,100,140,183,200,600,593);
      4    a_pks ta := ta(470553,100991,100981,101001,101033);
      5    a ta;
      6    l_actualcount number;
      7    cursor c(b number) is select pk from t where pk = b;
      8  begin
      9    for i in a_limitsizes.first .. a_limitsizes.last
     10    loop
     11      for j in a_pks.first .. a_pks.last
     12      loop
     13        l_actualcount := 0;
     14        open c(a_pks(j));
     15        loop
     16          fetch c bulk collect into a limit a_limitsizes(i);
     17          l_actualcount := l_actualcount + a.count;
     18          exit when a.count != a_limitsizes(i);
     19        end loop;
     20        close c;
     21        dbms_output.put_line('PK ' || a_pks(j) || ' EXPLICIT CURSOR Actual Count = ' || l_actualcount);
     22        dbms_output.put_line('. LOOP BULK COLLECT LIMIT ' || a_limitsizes(i) || ' retrieves : ' || a.count);
     23        dbms_output.new_line;
     24      end loop;
     25      dbms_output.put_line('*************************************************');
     26      dbms_output.new_line;
     27    end loop;
     28  end;
     29  /
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 78 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 78 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 78 retrieves : 27
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 78 retrieves : 37
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 78 retrieves : 47
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 100 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 100 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 100 retrieves : 83
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 100 retrieves : 93
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 100 retrieves : 93
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 140 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 140 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 140 retrieves : 43
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 140 retrieves : 53
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 140 retrieves : 33
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 183 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 183 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 183 retrieves : 0
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 183 retrieves : 10
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 183 retrieves : 44
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 200 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 200 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 200 retrieves : 183
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 200 retrieves : 193
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 200 retrieves : 193
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 600 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 600 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 600 retrieves : 183
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 600 retrieves : 193
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 600 retrieves : 593
    
    *************************************************
    
    PK 470553 EXPLICIT CURSOR Actual Count = 17
    . LOOP BULK COLLECT LIMIT 593 retrieves : 17
    
    PK 100991 EXPLICIT CURSOR Actual Count = 38
    . LOOP BULK COLLECT LIMIT 593 retrieves : 38
    
    PK 100981 EXPLICIT CURSOR Actual Count = 183
    . LOOP BULK COLLECT LIMIT 593 retrieves : 183
    
    PK 101001 EXPLICIT CURSOR Actual Count = 193
    . LOOP BULK COLLECT LIMIT 593 retrieves : 193
    
    PK 101033 EXPLICIT CURSOR Actual Count = 593
    . LOOP BULK COLLECT LIMIT 593 retrieves : 0
    
    *************************************************
    
    PL/SQL-procedure is geslaagd.
    

    Observation of Randolf was right: you are simply watching the last extraction of a series of extractions, which is the modulo / rest.

    Example: If your cursor retrieves a total of 183 ranks with a maximum size of 100, then your loop steps through twice. The first single 100 lines, the second 83. You print only the last extraction and not the sum of all the extractions.

    Kind regards
    Rob.

  • Bulk collect with sequence Nextval

    Hello


    Oracle Database 10 g Enterprise Edition Release 10.2.0.4.0 - 64 bit


    Had a doubt about the collection in bulk with nextval sequence. You need to update a table with a sequence of Nextval.

    where should I place select below in the proc is this before or after the loop


    < font color = "red" > SELECT prop_id_s.nextval INTO v_prop_id FROM dual; < / make >
    CREATE OR REPLACE PROCEDURE  (state IN varchar2)
    AS
       
       CURSOR get_all
       IS
          SELECT                              /*+ parallel (A, 8) */
                A .ROWID
                from Loads A WHERE A.Prop_id IS NULL;
    
       TYPE b_ROWID
       IS
          TABLE OF ROWID
             INDEX BY BINARY_INTEGER;
    
       
       lns_rowid          b_ROWID;
    BEGIN
    
    
       OPEN Get_all;
    
       LOOP
          FETCH get_all BULK COLLECT INTO   lns_rowid LIMIT 10000;
    
          FORALL I IN 1 .. lns_rowid.COUNT
             UPDATE   loads a
                SET   a.prop_id= v_prop_id (I)
              WHERE   A.ROWID = lns_rowid (I) AND a.prop_id IS NULL;
    
          
          COMMIT;
          EXIT WHEN get_all%NOTFOUND;
       END LOOP;
    
       
    
       CLOSE Get_all;
    END;
    /
    Published by: 960736 on January 23, 2013 12:51

    Hello

    It depends on what results you want. All updated rows would take the same value, or should all get unique values?

    Whatever it is, you don't need the sliders and loop. Just a simple UPDATE statement.

    If each line requires a unique value of the sequence, then

    UPDATE  loads
    SET     prop_id     = prod_id_s.NEXTVAL
    WHERE     prop_id     IS NULL
    ;
    

    If all the lines that have a need to the same value null, then:

    SELECT     prod_id_s.nextval
    INTO     v_prop_id
    FROM     dual;
    
    UPDATE  loads
    SET     prop_id     = v_prop_id
    WHERE     prop_id     IS NULL
    ;
    

    Don't forget to declare v_prop_id as a NUMBER.

    I hope that answers your question.
    If not, post a small example of data (instructions CREATE and INSERT, only relevant columns) for all the tables and the involved sequences and also publish outcomes from these data.
    If you ask on a DML statement, such as UPDATE, the sample data will be the content of the or the tables before the DML, and the results will be the State of the or the tables changed when it's all over.
    Explain, using specific examples, how you get these results from these data.
    Always say what version of Oracle you are using (for example, 11.2.0.2.0).
    See the FAQ forum {message identifier: = 9360002}

  • PLS-00201: identifier 'i' must be declared when using BULK COLLECT with FORALL to insert data in 2 tables?

    iHi.

    Declare
       cursor c_1
       is
        select col1,col2,col3,col4
        from table1
    
    
       type t_type is table of c_1%rowtype index by binary_integer;
       v_data t_type;
    BEGIN
       OPEN c_1;
       LOOP
          FETCH c_1 BULK COLLECT INTO v_data LIMIT 200;
          EXIT WHEN v_data.COUNT = 0;
          FORALL i IN v_data.FIRST .. v_data.LAST
             INSERT INTO xxc_table
               (col1,
                col3,
                col4
               )
                SELECT v_data (i).col1,
                       v_data (i).col3,
                       v_data (i).col4
                  FROM DUAL
                 WHERE NOT EXISTS
                              (SELECT 1
                                 FROM xxc_table a
                                WHERE col1=col1
                                      .....
                              );
                         --commit;
             INSERT INTO xxc_table1
               (col1,
               col2,
              col3,
              col4
               )
                SELECT v_data (i).col1,
                       v_data (i).col2,
                       v_data (i).col3,
                       'Y'
                  FROM DUAL
                 WHERE NOT EXISTS
                              (SELECT 1
                                 FROM xxc_table1 a
                                WHERE col1=col1
          .....
         );
    
    
           --exit when c_1%notfound;
       END LOOP;
       CLOSE c_1;
       commit;
    END;
    
    
    
    
    
    
    
    

    I get 40/28-PLS-00201: identifier 'I' must be declared what the problem in the above code please help me and I have lakhs of data

    Thank you

    Post edited by: Rajesh123 I changed IDX

    Post edited by: Rajesh123 changed t_type c_1 in Fetch

    But by using a SET of INSERT to insert into two tables at once in the same query would do the job without any collection of bulk of PL and avoid to query two times too.

    for example, as a single INSERT...

    SQL > create table table1 as
    2. Select 1 as col1, col2 of 1, 1 as col3, 1 as col4 Union double all the
    3 select 2,2,2,2 of all the double union
    4 Select 3,3,3,3 Union double all the
    5 Select 4,4,4,4 of all the double union
    6 select 5,5,5,5 of all the double union
    7 select 6,6,6,6 of all the double union
    8 select 7,7,7,7 of all the double union
    9 select 8,8,8,8 of all the double union
    10. Select 9,9,9,9 to the Union double all the
    11. Select double 10,10,10,10
    12.

    Table created.

    SQL > create table xxc_table like
    2. Select 1 as col1, col3 2, 3 as col4 Union double all the
    3. Select the 3, 4, 5 Union double all the
    4. Select the 5, 6, 7 double
    5.

    Table created.

    SQL > create table xxc_table1 like
    2. Select 3 as col1, col2, col3, 5 4 "n" as col4 Union double all the
    3. Select the 6, 7, 8, double "n"
    4.

    Table created.

    SQL > insert all
    2 when the xt_insert is null then
    3 in xxc_table (col1, col3, col4)
    4 values (col1, col3, col4)
    5 when the xt1_insert is null then
    6 in xxc_table1 (col1, col2, col3, col4)
    7 values (col1, col2, col3, 'Y')
    8. Select t1.col1 t1.col2, t1.col3, t1.col4
    9, xt.col1 as xt_insert
    10, xt1.col1 as xt1_insert
    11 from table1 t1
    12 left join external xxc_table xt (t1.col1 = xt.col1)
    13 left xt1 xxc_table1 outer join (t1.col1 = xt1.col1)
    14.

    15 rows created.

    SQL > select * from xxc_table by 1.
    COL1 COL3 COL4
    ---------- ---------- ----------
    1          2          3
    2          2          2
    3          4          5
    4          4          4
    5          6          7
    6          6          6
    7          7          7
    8          8          8
    9          9          9
    10-10-10

    10 selected lines.

    SQL > select * from xxc_table1 by 1.

    COL1 COL2 COL3 C
    ---------- ---------- ---------- -
    1          1          1 Y
    2          2          2 Y
    3          4          5 N
    4          4          4 Y
    5          5          5 Y
    6          7          8 N
    7          7          7 Y
    8          8          8 Y
    9          9          9 Y
    10-10-10

    10 selected lines.

    SQL >

  • Error using BULK collect with RECORD TYPE

    Hello

    I wrote a simple procedure to declare a record type & then by a variable of type NESTED table.

    I then selects the data using COLLECT in BULK & trying to access it via a LOOP... We get an ERROR.

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    CREATE OR REPLACE PROCEDURE sp_test_bulkcollect
    IS

    TYPE rec_type () IS RENDERING
    emp_id VARCHAR2 (20).
    level_id NUMBER
    );

    TYPE v_rec_type IS TABLE OF THE rec_type;

    BEGIN

    SELECT employe_id, level_id
    LOOSE COLLECTION v_rec_type
    OF portfolio_exec_level_mapping
    WHERE portfolio_execp_id = 2851852;

    FOR indx IN v_rec_type. FIRST... v_rec_type. LAST
    LOOP

    dbms_output.put_line ('Emp-' | v_rec_type.emp_id (indx) |) » '|| v_rec_type.level_id (indx));

    END LOOP;

    END;
    -----------------------------------------------------------------------------------------------------------------------------------

    Here is the ERROR I get...


    -Errors of compilation for the PROCEDURE DOMRATBDTESTUSER. SP_TEST_BULKCOLLECT

    Error: PLS-00321: expression "V_REC_TYPE" is not appropriate for the left side of an assignment statement
    Online: 15
    Text: IN portfolio_exec_level_mapping

    Error: PL/SQL: ORA-00904: invalid identifier
    Online: 16
    Text: WHERE portfolio_execp_id = 2851852;

    Error: PL/SQL: statement ignored
    Line: 14
    Text: COLLECT LOOSE v_rec_type

    Error: PLS-00302: component 'FIRST' must be declared
    Online: 19
    Text: LOOP

    Error: PL/SQL: statement ignored
    Online: 19
    Text: LOOP
    ------------------------------------------------------------------------------------------------

    Help PLZ.

    and with a complete code example:

    SQL> CREATE OR REPLACE PROCEDURE sp_test_bulkcollect
      2  IS
      3  TYPE rec_type IS RECORD (
      4  emp_id VARCHAR2(20),
      5  level_id NUMBER
      6  );
      7  TYPE v_rec_type IS TABLE OF rec_type;
      8  v v_rec_type;
      9  BEGIN
     10     SELECT empno, sal
     11     BULK COLLECT INTO v
     12     FROM emp
     13     WHERE empno = 7876;
     14     FOR indx IN v.FIRST..v.LAST
     15     LOOP
     16        dbms_output.put_line('Emp -- '||v(indx).emp_id||' '||v(indx).level_id);
     17     END LOOP;
     18  END;
     19  /
    
    Procedure created.
    
    SQL>
    SQL> show error
    No errors.
    SQL>
    SQL> begin
      2     sp_test_bulkcollect;
      3  end;
      4  /
    Emp -- 7876 1100
    
    PL/SQL procedure successfully completed.
    
  • Bulk collect fresh limit clause

    Hey,.

    There is little theoretical question about bulk collect.
    Have searched a lot of books but could not get the right solution.
    How do we calculate the value optimized for the fired limit bulk clause?

    -Say we have 10 million records... What should be the optimized value of limit?
    -We have 100 million documents... What should be the optimized value of limit?

    My code woks strangely... I was wondering what would be the limit?

    Value optimized in the Limit clause is equal tohow amount of memory you can afford to consume in the PGA and then adjust the limit to be as close to that amount as possible.
    Use of the below block to check that limit what value would be the most appropriate for your system, since it depends of your allocation of memory and CPU consumption.

    DECLARE
       PROCEDURE fetch_all_rows (limit_in IN PLS_INTEGER)
       IS
          CURSOR source_cur
          IS
             SELECT *
               FROM all_source;
    
          TYPE source_aat IS TABLE OF source_cur%ROWTYPE
             INDEX BY PLS_INTEGER;
    
          l_source   source_aat;
          l_start    PLS_INTEGER;
          l_end      PLS_INTEGER;
       BEGIN
          DBMS_SESSION.free_unused_user_memory;
          show_pga_memory (limit_in || ' - BEFORE');
          l_start := DBMS_UTILITY.get_cpu_time;
    
          OPEN source_cur;
    
          LOOP
             FETCH source_cur
             BULK COLLECT INTO l_source LIMIT limit_in;
    
             EXIT WHEN l_source.COUNT = 0;
          END LOOP;
    
          CLOSE source_cur;
    
          l_end := DBMS_UTILITY.get_cpu_time;
          DBMS_OUTPUT.put_line (   'Elapsed CPU time for limit of '
                                || limit_in
                                || ' = '
                                || TO_CHAR (l_end - l_start)
                               );
          show_pga_memory (limit_in || ' - AFTER');
       END fetch_all_rows;
    BEGIN
       fetch_all_rows (1);
       fetch_all_rows (5);
       fetch_all_rows (25);
       fetch_all_rows (50);
       fetch_all_rows (75);
       fetch_all_rows (100);
       fetch_all_rows (1000);
       fetch_all_rows (10000);
       fetch_all_rows (100000);
    END;
    
  • In BULK COLLECT with loop for?

    Let's say I have a table with a column number and a date column.

    I also have a query using a number and a date as a parameter. I want to run this query for each row in the table (using the column date and number of lines as parameters). If my thinking is looping through the rows and the query parameters for each line. It becomes a large number of queries select. Is it possible to use bulk collect here? All the examples I've seen where he uses a predefined cursor. Also, I don't know how to fix this problem without a cursor.

    Here's the query I want to do for each line:
    select * from reading_values rv, 
        (select * from 
           (select id, datereading
                  from readings,
                  where datereading < p_date and pointid = p_id
                  order by datereading desc)
           where rownum <= 1) t
         where rv.reading_id = t.id

    After reading your initial statement 3 times I simply add a third table to select it. I call this tableX colb and two columns cola (number) (date).

    select rv.*, r.*, row_number() over (partition by r.pointid  order by r.datereading desc) rn
    from reading_values rv
    join readings r on rv.reading_id = r.id
    join tableX x on x.colA = r.pointid and  r.datereading < x.colB
    order by  r.pointid, datereading desc
    

    You can restrict which to return only one row for each data point by using the column rn I already added.

    select * /* probably need sinlge column names here to avoid duplications */
    from (
       select rv.*, r.*, row_number() over (partition by r.pointid  order by r.datereading desc) rn
       from reading_values rv
       join readings r on rv.reading_id = r.id
       join tableX x on x.colA = r.pointid and  r.datereading < x.colB
    )
    where rn = 1
    order by pointid, datereading desc
    

    Published by: Sven w. on June 23, 2010 16:47

  • Using bulk collect into with assistance from the limit to avoid the TEMP tablespace error run out?

    Hi all

    I want to know if using bulk collect into limit will help to avoid the TEMP tablespace error run out.

    We use Oracle 11 g R1.

    I am assigned to a task of creating journal facilitated for all tables in a query of the APEX.

    I create procedures to execute some sql statements to create a DEC (Create table select), and then fires on these tables.

    We have about three tables with more than 26 million records.

    It seems very well running until we reached a table with more than 15 million record, we got an error says that Miss tablespace TEMP.

    I googled on this topic and retrieve the tips:

    Use NO LOG

    Parallel use

    BULK COLLECT INTO limited

    However, the questions for those above usually short-term memory rather than running out of TEMPORARY tablespace.

    I'm just a junior developer and does not have dealed with table more than 10 million documents at a time like this before.

    The database support is outsourced. If we try to keep it as minimal contact with the DBA as possible. My Manager asked me to find a solution without asking the administrator to extend the TEMP tablespace.

    I wrote a few BULK COLLECT INTO to insert about 300,000 like once on the development environment. It seems.

    But the code works only against a 000 4000 table of records. I am trying to add more data into the Test table, but yet again, we lack the tablespace on DEV (this time, it's a step a TEMP data)

    I'll give it a go against the table of 26 million records on the Production of this weekend. I just want to know if it is worth trying.

    Thanks for reading this.

    Ann

    I really need check that you did not have the sizes of huge line (like several K by rank), they are not too bad at all, which is good!

    A good rule of thumb to maximize the amount of limit clause, is to see how much memory you can afford to consume in the PGA (to avoid the number of calls to the extraction and forall section and therefore the context switches) and adjust the limit to be as close to that amount as possible.

    Use the routines below to check at what threshold value would be better suited for your system because it depends on your memory allocation and CPU consumption.  Flexibility, based on your limits of PGA, as lines of length vary, but this method will get a good order of magnitude.

    CREATE OR REPLACE PROCEDURE show_pga_memory (context_in IN VARCHAR2 DEFAULT NULL)

    IS

    l_memory NUMBER;

    BEGIN

    SELECT st. VALUE

    IN l_memory

    SYS.v_$ session se, SYS.v_$ sesstat st, SYS.v_$ statname nm

    WHERE se.audsid = USERENV ('SESSIONID')

    AND st.statistic # nm.statistic = #.

    AND themselves. SID = st. SID

    AND nm.NAME = 'pga session in memory. "

    Dbms_output.put_line (CASE

    WHEN context_in IS NULL

    THEN NULL

    ELSE context_in | ' - '

    END

    || 'Used in the session PGA memory ='

    || To_char (l_memory)

    );

    END show_pga_memory;

    DECLARE

    PROCEDURE fetch_all_rows (limit_in IN PLS_INTEGER)

    IS

    CURSOR source_cur

    IS

    SELECT *.

    FROM YOUR_TABLE;

    TYPE source_aat IS TABLE OF source_cur % ROWTYPE

    INDEX BY PLS_INTEGER;

    l_source source_aat;

    l_start PLS_INTEGER;

    l_end PLS_INTEGER;

    BEGIN

    DBMS_SESSION.free_unused_user_memory;

    show_pga_memory (limit_in |) "- BEFORE"); "."

    l_start: = DBMS_UTILITY.get_cpu_time;

    OPEN source_cur.

    LOOP

    EXTRACTION source_cur

    LOOSE COLLECTION l_source LIMITED limit_in;

    WHEN l_source EXIT. COUNT = 0;

    END LOOP;

    CLOSE Source_cur;

    l_end: = DBMS_UTILITY.get_cpu_time;

    Dbms_output.put_line (' elapsed time CPU for limit of ')

    || limit_in

    || ' = '

    || To_char (l_end - l_start)

    );

    show_pga_memory (limit_in |) "- AFTER");

    END fetch_all_rows;

    BEGIN

    fetch_all_rows (20000);

    fetch_all_rows (40000);

    fetch_all_rows (60000);

    fetch_all_rows (80000);

    fetch_all_rows (100000);

    fetch_all_rows (150000);

    fetch_all_rows (250000);

    -etc.

    END;

  • Bulk collect and type returns nothing

    Hello

    I have the following code:
    declare
         type view_my_type is table of admuser.my_view%rowtype
         index by pls_integer;
         --x admuser.my_view%rowtype;
         my_array view_my_type;
         cursor c1 is
         select *
         from admuser.my_view;
         s long;
         i number := 1;
    begin
         s := 'crate table ';
         open c1;
         loop
              fetch c1 bulk collect into my_array limit 1;
              
         --s := s ||' decode (tf.fin_dates_id, '||my_array(i).fin_dates_id||', sum(tf.act_work_cost), 0) ';
                   s := my_array(i).fin_dates_id;
              exit when c1%notfound;
         end loop;
         close c1;
         dbms_output.put_line(s);
    exception
         when others then
         null;
    end;
    This code returns PL/SQL procedure successfully completed.
    but don't show me is not the variable "s".

    Can you help me with this?

    Thank you

    There a quite a number of things not just here.
    First of all, allow me to reproduce your situation:

    SQL> create table my_view
      2  as
      3  select 'hello' fin_dates_id from dual
      4  /
    
    Table created.
    
    SQL> declare
      2    type view_my_type is table of my_view%rowtype index by pls_integer;
      3    my_array view_my_type;
      4    cursor c1 is
      5    select *
      6    from my_view;
      7    s long;
      8    i number := 1;
      9  begin
     10    s := 'crate table ';
     11    open c1;
     12    loop
     13      fetch c1 bulk collect into my_array limit 1;
     14      s := my_array(i).fin_dates_id;
     15      exit when c1%notfound;
     16    end loop;
     17    close c1;
     18    dbms_output.put_line(s);
     19  exception
     20  when others then
     21    null;
     22  end;
     23  /
    
    PL/SQL procedure successfully completed.
    

    And I SERVEROUTPUT on. Your exception handler is notoriously wrong. It is said: If something goes wrong, we'll pretend it didn't happen. And that's exactly what happened here: something has gone wrong and you have chosen to not know about it.

    We will remove the exception handler to see what went wrong:

    SQL> declare
      2    type view_my_type is table of my_view%rowtype index by pls_integer;
      3    my_array view_my_type;
      4    cursor c1 is
      5    select *
      6    from my_view;
      7    s long;
      8    i number := 1;
      9  begin
     10    s := 'crate table ';
     11    open c1;
     12    loop
     13      fetch c1 bulk collect into my_array limit 1;
     14      s := my_array(i).fin_dates_id;
     15      exit when c1%notfound;
     16    end loop;
     17    close c1;
     18    dbms_output.put_line(s);
     19  end;
     20  /
    declare
    *
    ERROR at line 1:
    ORA-01403: no data found
    ORA-06512: at line 14
    

    A no-data-found, because you are referencing my_array (i), when I is null. Just move the OUTPUT when a line upwards as well as your code runs better:

    SQL> declare
      2    type view_my_type is table of my_view%rowtype index by pls_integer;
      3    my_array view_my_type;
      4    cursor c1 is
      5    select *
      6    from my_view;
      7    s long;
      8    i number := 1;
      9  begin
     10    s := 'crate table ';
     11    open c1;
     12    loop
     13      fetch c1 bulk collect into my_array limit 1;
     14      exit when c1%notfound;
     15      s := my_array(i).fin_dates_id;
     16    end loop;
     17    close c1;
     18    dbms_output.put_line(s);
     19  end;
     20  /
    hello
    
    PL/SQL procedure successfully completed.
    

    Then next to fix things are:
    -do not use the long data type Use a VARCHAR2 or a CLOB.
    -' Cashier' should probably be 'create '.
    -in bulk, treatment with limit 1. Now you have the worst of both sides: line by line, treatment and slightly more complex syntax
    -Variable increment I
    -Easier (and thus better) use a loop FOR

    I hope this helps.

    Kind regards
    Rob.

  • bulk collect into with limit

    Hi all
    I was reading [http://asktom.oracle.com/pls/apex/f?p=100:11:0:P11_QUESTION_ID:5918938803188] of Tom Kyte site on bulk collect within limits. The code uses the % notfound cursor to exit the recovery loop. What I do in this situation is using exists, method of table rather than cursor attribute.
    create or replace procedure p1 is
    type num_list_type is table of number index by pls_integer;
    num_list num_list_type;
    
    cursor c1 is select temp from test;
    
    begin
    open c1;
    loop
      fetch c1 bulk collect into num_list limit 2;
      if num_list.exists(1)=false then
        exit;
      end if;
      for i in num_list.first..num_list.last 
      loop
        dbms_output.put_line(num_list(i));
      END LOOP;
    end loop;
    
    end;
    Since when I do this:
    exit wen c1%notfound  
    It will close when the cursor retrieves only less than the limit, leaving a few rows. If the code works properly.
    Question:
    1. is the Exit statement properly, is there another way (I'm a little skeptical because I'm not using the cursor)?
    2 How to decide on the size limit based on what we have in the hardware settings and oracle? All of the guidelines?
    3 - is the best practice when it comes with the cursor and several lines that still use bulk collect into?

    Best regards
    Val

    Valerie Debonair wrote:
    Hi all
    I was reading [http://asktom.oracle.com/pls/apex/f?p=100:11:0:P11_QUESTION_ID:5918938803188] of Tom Kyte site on bulk collect within limits. The code uses the % notfound cursor to exit the recovery loop. What I do in this situation is using exists, method of table rather than cursor attribute.

    create or replace procedure p1 is
    type num_list_type is table of number index by pls_integer;
    num_list num_list_type;
    
    cursor c1 is select temp from test;
    
    begin
    open c1;
    loop
    fetch c1 bulk collect into num_list limit 2;
    if num_list.exists(1)=false then
    exit;
    end if;
    for i in num_list.first..num_list.last
    loop
    dbms_output.put_line(num_list(i));
    END LOOP;
    end loop;
    
    end;
    

    Since when I do this:

    exit wen c1%notfound  
    

    It will close when the cursor retrieves only less than the limit, leaving a few rows. If the code works properly.
    Question:
    1. is the Exit statement properly, is there another way (I'm a little skeptical because I'm not using the cursor)?
    2 How to decide on the size limit based on what we have in the hardware settings and oracle? All of the guidelines?
    3 - is the best practice when it comes with the cursor and several lines that still use bulk collect into?

    Best regards
    Val

    Hello

    1. Yes, in above code statement EXIT will work correctly. The other way is % NOTFOUND CURSOR attribute usage.
    2. There is no precise way to decide the size limit.
    3 depends on number of records. If you have a lot of records always use LIMIT that improves performance.

    After reading the link that was posted by Blu, I am to edit this post.

    1. do not use CURSOR attribute when you use collections within a cursor. Use methods of collection such as COUNT or EXIST etc.

    @Blu,

    Thanks much for the link.

    Thank you
    Suri

    Published by: Suri on January 26, 2012 20:38

  • How to use Bulk collect in dynamic SQL with the example below:

    My Question is

    Using of dynamic SQL with collection in bulkif we pass the name of the table as "to the parameter' function, I want to display those

    An array of column names without vowels (replace the vowels by spaces or remove vowels and display).

    Please explain for example.

    Thank you!!

    It's just a predefined type

    SQL> desc sys.OdciVarchar2List
     sys.OdciVarchar2List VARRAY(32767) OF VARCHAR2(4000)
    

    You can just as easily declare your own collection type (and you are probably better served declaring your own type of readability if nothing else)

    SQL> ed
    Wrote file afiedt.buf
    
      1  CREATE OR REPLACE
      2     PROCEDURE TBL_COLS_NO_VOWELS(
      3                                  p_owner VARCHAR2,
      4                                  p_tbl   VARCHAR2
      5                                 )
      6  IS
      7     TYPE vc2_tbl IS TABLE OF varchar2(4000);
      8     v_col_list vc2_tbl ;
      9  BEGIN
     10      EXECUTE IMMEDIATE 'SELECT COLUMN_NAME FROM DBA_TAB_COLUMNS WHERE OWNER = :1 AND TABLE_NAME = :2 ORDER BY COLUMN_ID'
     11         BULK COLLECT
     12         INTO v_col_list
     13        USING p_owner,
     14              p_tbl;
     15      FOR v_i IN 1..v_col_list.COUNT LOOP
     16        DBMS_OUTPUT.PUT_LINE(TRANSLATE(v_col_list(v_i),'1AEIOU','1'));
     17      END LOOP;
     18*  END;
    SQL> /
    
    Procedure created.
    
    SQL> exec tbl_cols_no_vowels( 'SCOTT', 'EMP' );
    MPN
    NM
    JB
    MGR
    HRDT
    SL
    CMM
    DPTN
    
    PL/SQL procedure successfully completed.
    

    Justin

  • Bulk collect into a Table nested with Extend

    Hi all
    I want to get all the columns of the table emp and dept. So I use bulk collect into the concept of nested table.

    *) I wrote the function in three different ways. EX: 1 and 2 (DM_NESTTAB_BULKCOLLECT_1 & DM_NESTTAB_BULKCOLLECT_2) does not give the desired result.
    *) It only gives the columns of the EMP table. That means it takes DEPT & columns of the EMP table, but it only gives columns of table EMP.
    ) I think, there is something problem with nested table Extend.
    ) I want to know infested.
    Can we use bulk collect into a table nested with extend?
    If it is yes then fix the below codes (EX: 1 & EX: 2) and can you explain me please?


    Codes are given below *.

    CREATE OR REPLACE TYPE NEST_TAB IS TABLE OF THE VARCHAR2 (1000);

    EX: 1:
    ----
    -Bulk collect into a Table nested with Extend-
    CREATE or replace FUNCTION DM_NESTTAB_BULKCOLLECT_1
    RETURN NEST_TAB
    AS
    l_nesttab NEST_TAB: = NEST_TAB();
    BEGIN
    FOR tab_rec IN (SELECT table_name
    From user_tables
    WHERE table_name IN ('EMP', 'Department')) LOOP
    l_nesttab.extend;

    SELECT column_name
    bulk collect INTO l_nesttab
    Of user_tab_columns
    WHERE table_name = tab_rec.table_name
    ORDER BY column_id;
    END LOOP;

    RETURN l_nesttab;
    EXCEPTION
    WHILE OTHERS THEN
    LIFT;
    END DM_NESTTAB_BULKCOLLECT_1;

    SELECT *.
    TABLE (DM_NESTTAB_BULKCOLLECT_1);

    OUTPUT:
    -------
    EMPNO
    ENAME
    JOB
    MGR
    HIREDATE
    SAL
    COMM
    DEPTNO

    * Only the EMP table columns are there in the nested table.
    -----------------------------------------------------------------------------------------------------

    EX: 2:
    -----
    -Bulk collect in the nested with Extend based on County - Table
    CREATE or replace FUNCTION DM_NESTTAB_BULKCOLLECT_2
    RETURN NEST_TAB
    AS
    l_nesttab NEST_TAB: = NEST_TAB();
    v_col_cnt NUMBER;
    BEGIN
    FOR tab_rec IN (SELECT table_name
    From user_tables
    WHERE table_name IN ('EMP', 'Department')) LOOP
    SELECT MAX (column_id)
    IN v_col_cnt
    Of user_tab_columns
    WHERE table_name = tab_rec.table_name;

    l_nesttab. Extend (v_col_cnt);

    SELECT column_name
    bulk collect INTO l_nesttab
    Of user_tab_columns
    WHERE table_name = tab_rec.table_name
    ORDER BY column_id;
    END LOOP;

    RETURN l_nesttab;
    EXCEPTION
    WHILE OTHERS THEN
    LIFT;
    END DM_NESTTAB_BULKCOLLECT_2;

    SELECT *.
    TABLE (DM_NESTTAB_BULKCOLLECT_2);

    OUTPUT:
    -------
    EMPNO
    ENAME
    JOB
    MGR
    HIREDATE
    SAL
    COMM
    DEPTNO

    * Only the EMP table columns are there in the nested table.
    -------------------------------------------------------------------------------------------

    EX: 3:
    -----

    -Collect in bulk in a nested Table to expand aid for loop.
    CREATE or replace FUNCTION DM_NESTTAB_BULKCOLLECT_3
    RETURN NEST_TAB
    AS
    l_nesttab NEST_TAB: = NEST_TAB();
    TYPE local_nest_tab
    THE VARCHAR2 ARRAY (1000);
    l_localnesttab LOCAL_NEST_TAB: = LOCAL_NEST_TAB();
    NUMBER x: = 1;
    BEGIN
    FOR tab_rec IN (SELECT table_name
    From user_tables
    WHERE table_name IN ('EMP', 'Department')) LOOP
    SELECT column_name
    bulk collect INTO l_localnesttab
    Of user_tab_columns
    WHERE table_name = tab_rec.table_name
    ORDER BY column_id;

    BECAUSE me IN 1.l_localnesttab. COUNTING LOOP
    l_nesttab.extend;

    L_NESTTAB (x): = L_LOCALNESTTAB (i);

    x: = x + 1;
    END LOOP;
    END LOOP;

    RETURN l_nesttab;
    EXCEPTION
    WHILE OTHERS THEN
    LIFT;
    END DM_NESTTAB_BULKCOLLECT_3;

    SELECT *.
    TABLE (DM_NESTTAB_BULKCOLLECT_3);

    OUTPUT:
    ------
    DEPTNO
    DNAME
    LOC
    EMPNO
    ENAME
    JOB
    MGR
    HIREDATE
    SAL
    COMM
    DEPTNO

    * Now, I got the desired result set. DEP. and columns of the Emp Table are in the nested Table.




    Thank you
    Ann

    COLLECTION BULK cannot add values to an existing collection. It can only crush.

  • Problem with bulk collect

    HII All,
    I am facing a problem with in bulk collect unable to identify where my code is wrong. When I try to run the code below its getting hanged and thus leading to the end of the session. Please help me.

    Here I am providing examples of data.

    CREATE TABLE R_DUMMY
       (FA_FAC_OS NUMBER(34,14), 
      FAC_ID VARCHAR2(10) NOT NULL, 
      SYSTEM_ID NUMBER(6,0) NOT NULL, 
      WRKNG_CPY VARCHAR2(1) NOT NULL, 
      CA_ID VARCHAR2(16) NOT NULL, 
      FA_PRNT_FAC_ID VARCHAR2(10)
       );
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (10000.00000000000000, 'FA000001', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (500.00000000000000, 'FA000005', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (-500.00000000000000, 'FA000008', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (600.00000000000000, 'FA000013', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (600.00000000000000, 'FA000018', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (700.00000000000000, 'FA000020', 1, 'C', 'CA2001/11/0002', '');
    
    insert into r_dummy (FA_FAC_OS, FAC_ID, SYSTEM_ID, WRKNG_CPY, CA_ID, FA_PRNT_FAC_ID)
    values (1200.00000000000000, 'FA000022', 1, 'C', 'CA2001/11/0002', '');
    
    CREATE TABLE R_DUMMY_1
       (FA_FAC_OS NUMBER(34,14), 
         FAC_ID VARCHAR2(10) NOT NULL,
         SYSTEM_ID NUMBER(6,0) NOT NULL,
         VER_NUM NUMBER(4,2) NOT NULL
       );
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (10000.00000000000000, 'FA000001', 1, 3.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (10000.00000000000000, 'FA000001', 1, 2.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (10000.00000000000000, 'FA000001', 1, 1.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (500.00000000000000, 'FA000005', 1, 3.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (500.00000000000000, 'FA000005', 1, 2.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (500.00000000000000, 'FA000005', 1, 1.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (-500.00000000000000, 'FA000008', 1, 3.00);
    
    insert into r_dummy_1 (FA_FAC_OS, FAC_ID, SYSTEM_ID, VER_NUM)
    values (-500.00000000000000, 'FA000008', 1, 2.00);
    And my block of pl sql
    Set serveroutput on;
    
    Declare
              vPkgCaId          r_dummy.ca_id%type          := 'CA2001/11/0002';
              vPkgSystemId     r_dummy.system_id%type     := 1;
              vPkgWrkFlg          r_dummy.WRKNG_CPY%type     :=  'C';
    
              
    
              
              type t_type is object
                                       (
                                       v_FA_FAC_OS     r_dummy.FA_FAC_OS%type,
                                       v_FAC_ID     r_dummy.FAC_ID%type,
                                       v_SYSTEM_ID     r_dummy.SYSTEM_ID%type,
                                       v_ver_num     r_dummy_1.ver_num%type
                                       );
    
              type t_col_tbl is table of t_type index by binary_integer;
              
              l_col_tbl     t_col_tbl;
              
              
              
              
              
              --fac_id,system_id,ver_num is composite primary key for CP_CA_FAC_VER
    Begin
              
                        SELECT     fac.FA_FAC_OS,fac.FAC_ID,fac.SYSTEM_ID,ver.ver_num
                        bulk collect into l_col_tbl
                        FROM     r_dummy fac,r_dummy_1 ver
                        WHERE     fac.fac_id = ver.fac_id
                        and fac.system_id = ver.system_id
                        and fac.CA_ID = vPkgCaId
                        AND fac.SYSTEM_ID = vPkgSystemId
                        AND fac.WRKNG_CPY = vPkgWrkFlg
                        START WITH fac.CA_ID = vPkgCaId
                                  AND fac.SYSTEM_ID = vPkgSystemId
                                  AND fac.WRKNG_CPY = vPkgWrkFlg AND fac.FA_PRNT_FAC_ID IS NULL
                        CONNECT BY PRIOR fac.FAC_ID = fac.FA_PRNT_FAC_ID
                                  AND fac.SYSTEM_ID = vPkgSystemId
                                  AND fac.WRKNG_CPY = vPkgWrkFlg;
                        
              
              forall i in 1..l_col_tbl.count
    
                   
                   update     r_dummy_1 ver
                   set          ver.FA_FAC_OS           = l_col_tbl(i).v_FA_FAC_OS
                   where     fac_id                    = l_col_tbl(i).v_FAC_ID
                             and system_id          = l_col_tbl(i).v_system_id
                             and ver_num               = l_col_tbl(i).v_ver_num
                             ;
              
    
              Commit;
    
    End;
    /
    Please help me. I was able to do to help collect cursor instead in bulk, but think that bulk collect will result in better performance. Please suggest if my code needs no changes.


    Concerning
    Rambeau

    I'd rather do it right SQL which is much faster that COLLECT in BULK

     UPDATE r_dummy_1 ver
        SET ver.FA_FAC_OS =
            (
              SELECT fa_fac_os
                FROM (
                        SELECT fac.FA_FAC_OS,fac.FAC_ID,fac.SYSTEM_ID,ver.ver_num
                          FROM r_dummy fac,r_dummy_1 ver
                         WHERE fac.fac_id = ver.fac_id
                           and fac.system_id = ver.system_id
                           and fac.CA_ID = vPkgCaId
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                         START WITH fac.CA_ID = vPkgCaId
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                           AND fac.FA_PRNT_FAC_ID IS NULL
                       CONNECT BY PRIOR fac.FAC_ID = fac.FA_PRNT_FAC_ID
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                     ) t
               WHERE t.fac_id = ver.fac_id
                 AND t.system_id = ver.system_id
                 AND t.ver_num = ver.ver_num
            )
      WHERE EXISTS
            (
              SELECT fa_fac_os
                FROM (
                        SELECT fac.FA_FAC_OS,fac.FAC_ID,fac.SYSTEM_ID,ver.ver_num
                          FROM r_dummy fac,r_dummy_1 ver
                         WHERE fac.fac_id = ver.fac_id
                           and fac.system_id = ver.system_id
                           and fac.CA_ID = vPkgCaId
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                         START WITH fac.CA_ID = vPkgCaId
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                           AND fac.FA_PRNT_FAC_ID IS NULL
                       CONNECT BY PRIOR fac.FAC_ID = fac.FA_PRNT_FAC_ID
                           AND fac.SYSTEM_ID = vPkgSystemId
                           AND fac.WRKNG_CPY = vPkgWrkFlg
                     ) t
               WHERE t.fac_id = ver.fac_id
                 AND t.system_id = ver.system_id
                 AND t.ver_num = ver.ver_num
            )      
    
  • Bulk collect treats all lines not containing the LIMIT clause.

    Hi all

    I was referring the Oracle Site for COLLECTION in BULK.

    http://www.Oracle.com/technology/oramag/Oracle/08-Mar/o28plsql.html

    In the following code, I found and I ran the same.

    I just want to know why motor Pl - SQL is not processing or recital 27 last lines when I use % NOTFOUND cursot attribute.


    PROCEDURE process_all_rows_foi_test (p_limit PLS_INTEGER DEFAULT 100)
    IS
       CURSOR c1
       IS
          SELECT *
            FROM all_objects
           WHERE ROWNUM <= 227;
    
       TYPE foi_rec IS TABLE OF c1%ROWTYPE
          INDEX BY PLS_INTEGER;
    
       v_foi_rec   foi_rec;
       v_number    NUMBER  := 1;
    BEGIN
       OPEN c1;
    
       LOOP
          FETCH c1
          BULK COLLECT INTO v_foi_rec LIMIT p_limit;
    
          EXIT WHEN v_foi_rec.COUNT = 0;--------EXIT WHEN c1%NOTFOUND;--->Here is the issue
          DBMS_OUTPUT.put_line (v_number);
          v_number := v_number + 1;
       END LOOP;
    
       CLOSE c1;
    END;
    Please guide me on this.

    Thank you
    Arun

    % NOTFOUND will have the value TRUE when it gets below the limit

    (it is documented)

    But your workaround works fine

    SQL> declare
      2     CURSOR c1
      3     IS
      4        SELECT *
      5          FROM all_objects
      6         WHERE ROWNUM <= 227;
      7
      8     TYPE foi_rec IS TABLE OF c1%ROWTYPE
      9        INDEX BY PLS_INTEGER;
     10
     11     v_foi_rec   foi_rec;
     12     v_number    NUMBER  := 1;
     13  BEGIN
     14     OPEN c1;
     15
     16     LOOP
     17        FETCH c1
     18        BULK COLLECT INTO v_foi_rec LIMIT 100; --p_limit;
     19
     20        EXIT WHEN v_foi_rec.COUNT = 0;--------EXIT WHEN c1%NOTFOUND;--->Here is the issue
     21        DBMS_OUTPUT.put_line (v_foi_rec.count);
     22        v_number := v_number + 1;
     23     END LOOP;
     24
     25     CLOSE c1;
     26  END;
     27  /
    100
    100
    27
    
    PL/SQL procedure successfully completed.
    
    SQL> 
    

    Another option would be to place the EXIT right before your END LOOP;

Maybe you are looking for

  • Pixeled video when you watch videos on the internet... worked fine a week ago

    When I watch videos on the internet, they are really pixeled... they were very clear a week ago.  I have Vista Home Basic and a dell Inspiron 1545.not sure why the change in quality.  It seems to be good quality for a micro second then worsen the go

  • Downgraded to Windows 7 WIndows 8 - USB drivers needed

    I bought an a HP Pavilion g6 - 2288ca.  Uninstalled Windows 8 and installed Windows 7 Ultimate 64 bit. My left USB ports do not work.  I'm assuming USB3.  They have an exclamation mark next to them in Device Manager. USB host controller I read a lot

  • 3850 catalyst, MAB and RADIUS

    Hello This a 3850 catalyst drivers to speak (C3750 MAB auth works like a charm) and the strange thing is that I don't see RAIUS client sending packets button anywhere: Statistics of RADIUS #showAuth.      ACCT.       BothLength maximum inQ: NA NA 0Le

  • How can I download my flash drive on my windows computer documents 8

    I just got my computer with windows 8, and I don't know how to download my flash drive on the new computer.  Any help would be greatly appreciated. Anthony

  • Captivate 8, YouTube and Firefox: why it won't work?

    I'm having a problem with Captivate 8 the YouTube Widget, Firefox. Videos hosted on YouTube and accessible via the YouTube Widget in a Captivate project 8 no longer works. All I get is a white screen. If I use the test button in the widget, I can acc