1. 程式人生 > >oracle動態SQL繫結集合變數

oracle動態SQL繫結集合變數

有如下需求,在儲存過程中,傳遞的引數是字串,字串格式是‘1,2,3 ’, 由數字組成,中間用','號分割;然後在SQL語句如下使用:

create or replace procedure moveToRight  (v_ids varchar2, v_workid int )
as
i_sql varchar2(1000);
begin
	 /*
	  -- v_ids 的格式 '1,2,3'轉換成1,2,3的集合
	  */ 
   -- oracle 動態SQL列名不能使用替代形式,只能拼湊
    i_sql:=' insert into profworktype (workid,worktypeid) select  '|| v_workid ||' ,id from  worktype where  id  in (:1)  and id not in ( select worktypeid  from  profworktype where workid = :2 ) ';
      execute immediate i_sql  using  v_ids, v_workid;
   end;

 注意上面紅色標記的引數傳遞,是顯然不對的,因為使用in後面必須是集合,集合要麼來自於select語句,要麼自己封裝,具體參考:http://space.itpub.net/756652/viewspace-242174 ;做法主要是將字串轉換成數字集合,然後通過select語句即可;程式碼如下:

1、首先建立一個型別,用於儲存資料

create or replace type numTableType as table of number ;

 2、建立一個函式負責完成字串到集合的轉換

-- 程式碼來源於 http://space.itpub.net/756652/viewspace-242174
create or replace function str2numlist (v_ids varchar2)
 return  numTableType 
 as 
  v_str long default v_ids || ','; 
  v_n number; 
  v_data  numTableType := numTableType (); 

begin
    loop 
  v_n := to_number(instr( v_str, ',' )); 
          exit when (nvl(v_n,0) = 0); 
 v_data.extend; 
v_data( v_data.count ) := ltrim(rtrim(substr(v_str,1,v_n-1))); 
 v_str := substr( v_str, v_n+1 ); 
end loop; 
 return v_data; 
 end; 

 3、在儲存過程中呼叫該函式即可;

create or replace procedure moveToRight  (v_ids varchar2, v_workid int )
as
i_sql varchar2(1000);
begin
	 /*
	  -- v_ids 的格式 '1,2,3'轉換成1,2,3的集合
	  */ 
   -- oracle 動態SQL列名不能使用替代形式,只能拼湊
    i_sql:=' insert into profworktype (workid,worktypeid) select  '|| v_workid ||' ,id from  worktype where  id  in (select * from the(select cast (str2numlist( :1) as numtableType ) from dual) )  and id not in ( select worktypeid  from  profworktype where workid = :2 ) ';
      execute immediate i_sql  using  v_ids, v_workid;
   end;

 注意select * from the(表函式返回的結果集集合)的用法,查找了半天沒有找到官方說明,歡迎指出。但是下面是等價的:

select * from the(select cast (str2numlist( :1) as numtableType ) from dual) 

-- 等價於

select * from table (  cast (str2numlist( '1,2') as numtableType )   )