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!

Dynamic Insert Statement

User_1M3BRMay 19 2021 — edited May 19 2021

Hi,
 There is a requirement to dynamically pick the filter condition from table and then insert the data in another table. I have written the below procedure and it works fine in terms of the result and for small data set. But for large data set , it is taking very long time. How can we optimize it. 
 Total no of records in temp_tab is approx 52 lakhs
 Total no of records in temp_tab_1 is approx 30K
Note that the dynamic insert which is getting created does not take much time to execute. I think issue is with context switching ie. looping the record one by one.
Test data is given below for reference.

CREATE TABLE TEMP_TAB
   (	"LOCATION_ID" VARCHAR2(1020 BYTE), 
	"STORE_NAME" VARCHAR2(1020 BYTE), 
	"STREET_NAME" VARCHAR2(1020 BYTE)
   );
   
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4346448','АНЮТА','КУРЧАТОВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7692143','РОСЬ','СТЕКЛОВСКОГО');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7691976','СУПЕРМАРКЕТ СТАРТ','НЕЧАЕВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37916687','ВИННЫЙ ПОГРЕБОК','ТИМИРЯЗЕВА  ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37926097','АССОРТИ ПРОДУКТЫ','ПОГРАНИЧНАЯ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7710783','ПРОДУКТЫ','ПОКРЫШКИНА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4310789','АПТЕКА ДЕЖУРНАЯ _ ООО АПТЕКА ДЕЖУРНАЯ','МИРА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7706784','ПРОДУКТЫ','БОЛЬШАЯ САДОВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4358145','Б/В','ОЛИМПИЙСКИЙ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37926810','ПРОДУКТЫ','ОРЕХОВЫЙ');


   
    CREATE TABLE TEMP_TAB_1
   (	"ID" VARCHAR2(30 CHAR), 
	"STORE_ID" NUMBER, 
	"FILTER_COND" CLOB
   ) ;
   


Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',100,' AND (location_id = ''4346448'' or store_name = ''СУПЕРМАРКЕТ СТАРТ''   )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',200,' AND (location_id = ''37916687''  )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',300,' AND (street_name = ''ПОГРАНИЧНАЯ''   )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',400,' AND (street_name = ''ПОКРЫШКИНА'' or location_id = ''37926810''  )');
  
   
     CREATE TABLE TEST_TABLE
   (	"LOCATION_ID" VARCHAR2(1020 BYTE),
        "ID" VARCHAR2(30 CHAR), 
	"STORE_ID" VARCHAR2(100 CHAR)
   );
   
   
     CREATE TABLE TEST_error
   (	"ID" VARCHAR2(30 CHAR), 
	"STORE_ID" VARCHAR2(100 CHAR),
	error varchar2(1000)
   );  

create or replace PROCEDURE p_test (p_id          IN VARCHAR2,
                                   p_temp_tab  IN VARCHAR2,
                                   p_temp_tab_1   IN VARCHAR2)
   IS


        v_sql               CLOB;
        v_sql_err           CLOB;
        v_sql_err_cnt       VARCHAR2(100 CHAR);
        v_upd               CLOB;
        id                   VARCHAR2(30 CHAR);
        store_id           VARCHAR2 (100 CHAR);
        filter_cond         CLOB; 
        TYPE c1 IS REF CURSOR;
        cur      c1;
        p_audit_key         NUMBER;
        v_temp_err_tab      VARCHAR2(50 CHAR):='test_error';
        v_err_cnt           NUMBER;

    BEGIN       
       
        OPEN cur FOR
           'SELECT ID, STORE_ID, filter_cond FROM ' || p_temp_tab_1;
        LOOP
            FETCH cur INTO id, store_id, filter_cond;

            EXIT WHEN cur%NOTFOUND;

            v_sql :=
             ' INSERT INTO test_table '
            || ' ( location_id,ID, STORE_ID )'
            || ' select location_id,' 
            || '''' || p_id   || '''' || ','
            || '''' || store_id      || '''' 
            || ' from ' || p_temp_tab 
            || ' where 1 = 1 '
            || filter_cond;
	
			dbms_output.put_line(v_sql);

            BEGIN
             EXECUTE IMMEDIATE v_sql;

            EXCEPTION
                WHEN OTHERS  THEN
                 v_upd := 'insert into ' || v_temp_err_tab
                || ' select ' || '''' || p_id || '''' || ','
                || '''' || store_id || ''''  || ','
                || '''' || 'ERROR' || ''''
                || ' FROM DUAL';


                 EXECUTE IMMEDIATE v_upd;


           END;
        END LOOP; 


        COMMIT;


        CLOSE cur;


END p_test;


Procedure call


begin
 p_test ('1','temp_tab','temp_tab_1');
end;
/	

Any suggestions would be really appreciated.
Thanks.

Comments
Post Details
Added on May 19 2021
13 comments
379 views