如何使用动态PL / SQL将值字符串与IN子句放在一起?

时间:2014-02-12 21:04:32

标签: sql oracle plsql

使用Oracle PL / SQL,我如何使用bind variable :b3的多个值填充IN clause? (此代码仅用于演示目的 - 它可能无法编译,但它确实澄清了问题是否需要)

 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;
/

4 个答案:

答案 0 :(得分:1)

当你循环遍历这些值时,请继续使用'和,根据需要附加字符串来构成in的一部分。然后你可以使用该字符串作为sql语句的一部分。

实施例

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

希望它有所帮助!

答案 1 :(得分:1)

您需要使用另一个变量准备循环内的in列表,然后使用它之外的语句。这样的事情可能有所帮助:

 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;

答案 2 :(得分:1)

你可以使用plsql集合作为绑定变量,这对我来说似乎是更好的解决方案:

    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;
    /

答案 3 :(得分:0)

更好的解决方案(至少在我的问题上) - 不要使用绑定变量,而是连接值的字符串(仅显示代码段):

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;
...

你明白了。感谢您的所有意见。