tonyf
tonyf

Reputation: 35557

Take Oracle Type Array and insert contents into an Oracle table

I have a variable l_rec of type wwv_flow_global.vc_arr2 within my package procedure, where:

type vc_arr2 is table of varchar2(32767) index by binary_integer;

Within l_rec, I have populated a number of records.

Within my debug statement, I can access the records using the following query:

   FOR i IN 1..l_rec.COUNT
    LOOP
      insert into msg_log(msg) 
      values
        ('Record info: Index: ' || i || ' - Value: ' || l_rec(i));
    END LOOP;

FYI, I actually also have an outer loop that repeats the below info but with different data, i.e. a loop within a loop.

Sample dataset looks like:

Record info: Index: 1 - Value: AA
Record info: Index: 2 - Value: BB
Record info: Index: 3 - Value: CC
Record info: Index: 4 - Value: DD
Record info: Index: 5 - Value: EE
Record info: Index: 1 - Value: AAA
Record info: Index: 2 - Value: BBB
Record info: Index: 3 - Value: CCC
Record info: Index: 4 - Value: DDD
Record info: Index: 5 - Value: EEE

etc....

Based on the above, I have created a table called message_log that has the following columns:

SEQ_ID  NUMBER,
C001    VARCHAR2(4000),
C002    VARCHAR2(4000),
C003    VARCHAR2(4000),
C004    VARCHAR2(4000),
C005    VARCHAR2(4000)

My question is, how can I take my l_rec array of type wwv_flow_global.vc_arr2 and insert the whole contents into my message_log Oracle table?

Please note that SEQ_ID here will be a counter of my outer loop so I would expect to see message log table data as follows:

1,AA,BB,CC,DD,EE
2,AAA,BBB,CCC,DDD,EEE

Upvotes: 0

Views: 2801

Answers (2)

Arkadiusz Łukasiewicz
Arkadiusz Łukasiewicz

Reputation: 6346

You have a few options.But direct insert is not possible.

create table msg_log( 
        seq_id number,
        col1 varchar2(4000),
        col2 varchar2(4000),
        col3 varchar2(4000),
        col4 varchar2(4000),
        col5 varchar2(4000),
        col6 varchar2(4000),
        col7 varchar2(4000),
        col8 varchar2(4000));

Preparing test table.

In static approach each value from your record is assigned to rowtype record.
In dynamic approach whole insert is generated.

declare 
    type vc_arr2 is table of varchar2(32767) index by binary_integer;
    rec vc_arr2;
    row_msg_log msg_log%rowtype ;
    function populate(how_many number) return vc_arr2  is
        tmp vc_arr2; 
        begin 
        for i in 1 .. how_many loop
        tmp(i) := 'VALUE'||i;
        end loop;
        return tmp;
    end; 

    function static_approach(id number , rec vc_arr2) return msg_log%rowtype 
    is 
     tmp msg_log%rowtype;
    begin 
         tmp.seq_id := id;
         if rec.exists(1) then 
            tmp.col1 := rec(1);
         end if; 
         if rec.exists(2) then 
            tmp.col2 := rec(2);
         end if; 
         if rec.exists(3) then 
            tmp.col3 := rec(3);
         end if; 
         --etc.

         return tmp;
    end; 

    procedure dynamic_insert(id number , rec vc_arr2)  is 
      v_sql varchar2(4000);

      function generate_stament return varchar2 is
       idx number; 
       column_list varchar2(4000);
       value_list  varchar2(4000);
      begin 
        column_list := '(seq_id';
        value_list := '('||id;
        idx := rec.first;
        while (idx is not null)
           loop
               column_list := column_list||' ,col'||idx;
               value_list := value_list||' ,'''||rec(idx)||'''';
               idx := rec.next(idx);
           end loop; 
          column_list := column_list||') ';
          value_list := value_list||') ';
        return 'insert into msg_log'||column_list||'values'||value_list;
       end;
    begin 
     v_sql := generate_stament;       
     execute immediate  v_sql;      
    end;

begin



row_msg_log := static_approach(1,populate(3));
insert into msg_log values row_msg_log;
row_msg_log := static_approach(2,populate(4));
insert into msg_log values row_msg_log;

dynamic_insert(3,populate(8));
dynamic_insert(4,populate(1));

-- with a not dens array

rec := populate(1);
rec(5) := 'blblb';
rec(8) := 'fofofo';
dynamic_insert(4,rec);
end;

Upvotes: 0

Scott
Scott

Reputation: 5035

If you work with apex_t_varchar2, you can

select * from table(apex_string.split('1,2,3',','));

or

declare
  l_table apex_t_varchar2;
begin
    apex_string.push(l_table, 'a');
    apex_string.push(l_table, 'b');
    sys.dbms_output.put_line(apex_string.join(l_table, ','));
end;
/

Which I think would cover a few of your needs.

Upvotes: 1

Related Questions