0

Using Oracle PL/SQL, how can I populate the bind variable :b3 with more than one value for the IN clause? (This code is for demo purposes only -- it may not compile but it does clarify the question if any is needed)

 declare
      type work_rec is record ( 
        work_status varchar2(50),
        work_cd     varchar2(50));

  type work_tab is table of work_rec index by pls_integer;   

  t_work_tab work_tab; 
  sql_stmt varchar2(400); 

begin
  select case    
     when status_desc like '%Employed%' then 'Employed'
     else 'Unknown'
   end as work_status
  ,case 
     when status_cd between '1' and '9' then '1,2,3,4' 
     else '0'
   end as work_cd
  bulk collect into t_work_tab
  from employee_table;

  for i in t_work_tab.first..t_work_tab.last 
  loop
    sql_stmt := 'insert into employee_hist 
                 select name,
                        employer
                 from tax_table
                 where employment_cd in (:b3)';    --< how to populate this with '1','2','3','4'

    execute immediate sql_stmt using t_work_tab(i).work_cd;
    commit;

  end loop;

end;
/
2

4 Answers 4

1

When you loop through the values, keep appending the string with ' and , as required to make up the part of in. Then you can use that string as part of your sql statement.

Example

temp = "'"
Loop through values a,b,c,d as str
    temp = temp + str + "'",
End Loop
temp = substr(temp,0,length(temp))  // this is to trim the last , character

Hope it helps!

Sign up to request clarification or add additional context in comments.

Comments

1

You need to prepare the in list inside the loop using another variable and then the statement outside it. Something like this may help:

 declare
      type work_rec is record ( 
        work_status varchar2(50),
        work_cd     varchar2(50));

  type work_tab is table of work_rec index by pls_integer;   

  t_work_tab work_tab; 
  sql_stmt VARCHAR2(400); 
  v_in_str varchar2(100);_

begin
  select case    
     when status_desc like '%Employed%' then 'Employed'
     else 'Unknown'
   end as work_status
  ,case 
     when status_cd between '1' and '9' then '1,2,3,4' 
     else '0'
   end as work_cd
  bulk collect into t_work_tab
  from employee_table;

  for i in t_work_tab.first..t_work_tab.last 
  loop
    v_in_str := v_in_str || t_work_tab(i).work_cd || ',';

  END loop;
  v_in_str :=rtrim(v_in_str, ',');
  sql_stmt := 'insert into employee_hist 
               select name,
                      employer
               from tax_table
               where employment_cd in ('||v_in_str||')';

  execute immediate sql_stmt;
  commit;

end;

Comments

1

you could use a plsql collection as bind variable, this seems the nicer solution to me:

    declare
        type t_nbr_tbl is table of number;

        type work_rec is record ( 
          work_status varchar2(50),
          work_cd     t_nbr_tbl;

        type work_tab is table of work_rec index by pls_integer;   

        t_work_tab work_tab; 
        sql_stmt varchar2(400); 

    begin
        select case    
           when status_desc like '%Employed%' then 'Employed'
           else 'Unknown'
         end as work_status
        ,case 
           when status_cd between '1' and '9' then t_nbr_tbl(1,2,3,4)
           else t_nbr_tbl(0)
         end as work_cd
        bulk collect into t_work_tab
        from employee_table;

        for i in t_work_tab.first..t_work_tab.last 
        loop
          sql_stmt := 'insert into employee_hist 
                       select name,
                              employer
                       from tax_table
                       where employment_cd in (select column_value from table(:b3))';    --< how to populate this with '1','2','3','4'

          execute immediate sql_stmt using t_work_tab(i).work_cd;
          commit;

        end loop;

    end;
    /

Comments

0

Better solution (at least to my issue) - don't use a bind variable but instead concatenate the string of values (code segment shown only):

for i in t_work_tab.first..t_work_tab.last 
  loop
    sql_stmt := 'insert into employee_hist 
             select name,
                    employer
             from tax_table
             where employment_cd in (' || t_work_tab(i).work_cd || ')';

   execute immediate sql_stmt;
...

You get the idea. Thanks for all your input.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.