Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Convert PLSQL code to BULK COLLECT INTO collection

KalpataruSep 25 2025 — edited Sep 25 2025

Hi All,

I have written the following code and it's working fine but talking around approx. 40 minutes for 112000 records.

declare
  lv_website varchar2(100);
  
  cursor c1 is
      select *
        from tb_main_table
        where status = 'C' and active = 'Y'
              and ext_id in (select webid from temp_website_table);
Begin

	For Rec in c1 Loop
      --the following query will always return one record
	  begin
		 select weburl
		   into lv_website
		   from temp_website_table 
		  where webid = Rec.ext_id;
	  exception
		 when others then
			  lv_website := null;
	  end;
	  
	  Rec.seq_id    := tb_main_seq.nextval;
	  Rec.link_text := lv_website;
	  
	  begin
	    Insert into tb_main_table values Rec;
		dbms_output.put.line('Data successfully inserted--:'||Rec.ext_id||'-'||Rec.seq_id);
	  exception
        when others then
             dbms_output.put.line('Error while insert--:'||Rec.ext_id||'-'||Rec.seq_id||'-:'||sqlerrm);
      end;	
	  
	End loop;

exception
  when others then
       dbms_output.put.line('Error--:'||sqlerrm);
end;

I want to convert this normal pl sql to collection bulk collect into and using for all.

I have also tried the below code but getting the below errors

PLS-00642: local collection types not allowed in SQL statements

PL/SQL: ORA-22905: cannot access rows from a non-nested table item

DECLARE
    cursor c1 is
        select *
         from tb_main_table
        where status = 'C' and active = 'Y'
              and ext_id in (select webid from temp_website_table);

    lv_website varchar2(100);
    
    TYPE type_main_collection IS TABLE OF tb_main_table%ROWTYPE;
    lv_cr_data type_main_collection;
    
    TYPE type_website_collection IS TABLE OF VARCHAR2(100);
    lv_websites type_website_collection;

BEGIN
    OPEN c1;
    LOOP
        -- Fetch data in bulk into the collection
        FETCH c1 BULK COLLECT INTO lv_cr_data;
        EXIT WHEN lv_cr_data.COUNT = 0;

        -- Collect websites for the fetched data
        --This select always fetch only one record for one web id 
        --(Getting error from the below select)
        SELECT weburl
        BULK COLLECT INTO lv_websites
        FROM temp_website_table 
        WHERE webid IN (SELECT ext_id FROM TABLE(lv_cr_data));

        -- Assign website and sequence values to lv_cr_data collection
        FOR i IN 1 .. lv_cr_data.COUNT LOOP
            lv_cr_data(i).seq_id    := tb_main_seq.nextval;
            lv_cr_data(i).link_text := lv_websites(i);
        END LOOP;

        -- Bulk insert into the target table using FORALL
        FORALL i IN 1 .. lv_cr_data.COUNT
            INSERT INTO tb_main_table VALUES lv_cr_data(i);

        -- Optionally commit after each batch of records
        COMMIT;

    END LOOP;
    CLOSE c1;
END;
/

Please suggest the best or any other way to do this.

This post has been answered by Gerrit van der Linden on Sep 25 2025
Jump to Answer
Comments
Post Details
Added on Sep 25 2025
13 comments
390 views