简体   繁体   中英

Use Input Parameter of procedure to declare %Rowtype record

I am trying to insert the data into a table using Bulk Collect. Here is the code:

create or replace procedure insert_via_bulk_collect authid current_user
as 
    lc_status number;
    cursor lc_old_tb_data is select * from old_table_name;

    type lc_old_tb_type is table of old_table_name%rowtype;
    lc_old_tb_row lc_old_tb_type;
begin

    open lc_old_tb_data;
    loop 
        fetch lc_old_tb_data bulk collect into lc_old_tb_row;

        forall i in 1..lc_old_tb_row.count
            insert into new_table_name values lc_old_tb_row(i);

        commit;

        exit when lc_old_tb_data%notfound;
    end loop;
    close lc_old_tb_data;  

end insert_via_bulk_collect;

It's working for me. But I want to pass the table name dynamically. like

insert_via_bulk_collect(new_tb_nm varchar2(30), old_tb_name varchar2(30))

But I am not able to use those variables in cursor and declaring the record of OLD_TABLE%rowtype . Is there a way to do this?

As mentioned in comments, it is better to use direct insert ... select ... . In your case, you can combine this way with execute immediate :

create or replace procedure insert_via_bulk_collect(new_tb_nm varchar2, old_tb_name varchar2) is
begin
  execute immediate 'insert into ' || new_tb_nm || 
      '(<columns list>) select <columns list> from ' || old_tb_nm; 
end;

Try below code

    CREATE OR REPLACE PROCEDURE INSERT_VIA_BULK_COLLECT 
(NEW_TABLE_NAME  varchar2, OLD_TABLE_NAME  varchar2)
    as 
         l_str varchar2(4000);
    begin
         l_str := 'declare
         CURSOR lc_old_tb_data IS SELECT * FROM ' || OLD_TABLE_NAME || ';
         TYPE lc_old_tb_type IS TABLE OF '|| OLD_TABLE_NAME || '%rowtype;
         lc_old_tb_row lc_old_tb_type;     
         begin
              Open lc_old_tb_data;
              loop 
                   fetch lc_old_tb_data bulk collect into lc_old_tb_row;

                   FORALL i IN 1..lc_old_tb_row.count
                   INSERT INTO ' || NEW_TABLE_NAME || ' VALUES lc_old_tb_row(i);

                   COMMIT;

                   exit when lc_old_tb_data%notfound;
              end loop;
              close lc_old_tb_data; 
              end; ';

         dbms_output.put_line (l_str);
         EXECUTE IMMEDIATE l_str; 

    end insert_via_bulk_collect;

You can add Exception handing. Also it is recommended to add limit for fetching of data as below fetch lc_old_tb_data bulk collect into lc_old_tb_row l_size; you can put l_size value as per your requirement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM