一個比較複雜的多次拆分字串的儲存過程

mchdba發表於2014-04-10
自己寫的特殊拆分函式如下: 
create or replace function FN_SPLIT_STR_2(var_str   in varchar2)return varchar2
/* 
有一張表 t1,裡面有個欄位叫c3,存的是所有店鋪的點位資訊。
現在需要一個儲存過程,將所有的記錄的c3欄位的座標值都縮小3倍,寫入c欄位


內容舉例為  220.25 257,220.25 269.75,229.25 269.75,229.25 257
每個逗號分開的是一個個的座標點,每個座標點用空格區分x座標和y座標


儲存函式名稱:FN_SPLIT_STR_2
用途:把bis_store座標v_coords3縮小三倍更新coords,比如
author:huangshan
*/
as
  var_tmp     varchar2(4000);
  var_element varchar2(4000);
  var_result varchar2(4000);
  var_instr_first number;
  var_instr_second number;
  var_length number;


begin
  var_tmp := var_str;
  var_instr_first :=0;
  var_instr_second :=0;
  var_result :='';
  var_length:=0;
  
  /* 替換掉傳過來的特殊字元
chr(9) 製表符 
chr(10)回車
chr(13)換行
  */
  var_tmp:= replace(var_tmp,chr(10),'');
  var_tmp:= replace(var_tmp,chr(13),'');
  var_tmp:= replace(var_tmp,chr(9),'');
  
  while instr(var_tmp, ' ') > 0 
    or instr(var_tmp, ',')>0 
    or(var_length>0) loop
    var_instr_first :=instr(var_tmp, ' ');
    var_instr_second :=instr(var_tmp, ',');
   -- dbms_output.put_line('var_instr_kg:'||var_instr_first||'  ');
   -- dbms_output.put_line('var_instr_dh:'||var_instr_second||'  ');
         var_length:=length(var_tmp);
   --  dbms_output.put_line('var_length  :'||var_length||'  ');
     
/* 1 如果是先有空格,比如 12 32,12 32這類 **/
    if var_instr_first          var_element := round(to_number(substr(var_tmp, 1, var_instr_first-1))/3,2);
         var_result := var_result|| var_element|| ' ';
         var_tmp := substr(var_tmp,var_instr_first+1, length(var_tmp));


      --   dbms_output.put_line('var_result kg:'||var_result);
      --   dbms_output.put_line('var_tmp kg:'||var_tmp||'  ');
      --   dbms_output.put_line('var_element kg:'||var_element||'  ');
 
      /* 2 如果是已經擷取完空格,逗號在前面比如 32,12 32這類 **/    
    elsif var_instr_first>var_instr_second and  var_instr_second>0 then
           var_element := round(to_number(substr(var_tmp, 1, var_instr_second-1))/3,2);
           var_result := var_result || var_element || ',' ;
           var_tmp := substr(var_tmp,var_instr_second+1, length(var_tmp));
         --  dbms_output.put_line('var_result dh:'||var_result);
        --   dbms_output.put_line('var_tmp dh:'||var_tmp||'  ');
        --   dbms_output.put_line('var_element dh:'||var_element||'  ');

/* 3 如果是已經擷取完逗號,已經只剩下最後一個座標x y,比如12 32這類 **/  
    elsif var_instr_first>var_instr_second and  var_instr_second=0 then
         var_element := round(to_number(substr(var_tmp, 1, var_instr_first-1))/3,2);
         var_result := var_result|| var_element|| ' ';
         var_tmp := substr(var_tmp,+1, length(var_tmp));


       --  dbms_output.put_line('var_result kg:'||var_result);
       --  dbms_output.put_line('var_tmpvar_instr_first kg:'||var_tmp||'  ');
        -- dbms_output.put_line('var_element kg:'||var_element||'  '); 
        
/* 4 如果是已經擷取到最後一個座標,比如32這類 **/ 
     elsif var_instr_first=0 and var_instr_second=0 and var_length>0 then
      --  dbms_output.put_line('var_tmp the last one:'||var_tmp||'  ');
       var_element := round(to_number(var_tmp)/3,2);
       var_result := var_result  || var_element;
       var_tmp:='';
       --  dbms_output.put_line('var_result 0:'||var_result);
       --  dbms_output.put_line('var_tmp 0:'||var_tmp||'  ');
       --  dbms_output.put_line('var_element 0:'||var_element||'  ');
         
 
/* 5 如果其他的東西,設定成''退出while迴圈為止 **/ 
     else 
       var_tmp:='';
     end if;


    -- dbms_output.put_line('     ');
     
  end loop;
  return var_result;


end FN_SPLIT_STR_2;


-- google其他人的拆分function如下:
-- 拆分函式
create or replace function split_str(var_str   in varchar2, 
                                       var_split in varchar2) 
/**************************************************** 
  注意 先執行下面語句 建立型別 
  create or replace type t_ret_table is table of varchar2(100) 
  ** 函式名稱:split_str 
  ** 參    數:【名稱】         【型別 】      【說明】 
  **           var_str          varchar2       要拆分的字串 
  **           var_split        varchar2       字串分隔符 
  ** 返 回 值:Result           t_ret_table    拆分後陣列集合 
  ** 摘    要:拆分字串 
  呼叫 舉例: 
  select * from table(split_str('2008-10-21','-')) 
  ****************************************************/ 
  return t_ret_table is 
  var_out     t_ret_table; 
  var_tmp     varchar2(4000); 
  var_element varchar2(4000); 


begin 
  var_tmp := var_str; 
  var_out := t_ret_table(); 
  --如果存在匹配的分割符 
  while instr(var_tmp, var_split) > 0 loop 
    var_element := substr(var_tmp, 1, instr(var_tmp, var_split) - 1); 
    var_tmp     := substr(var_tmp, 
                          instr(var_tmp, var_split) + length(var_split), 
                          length(var_tmp)); 
    --var_out.extend(1); 
    var_out.extend; 
    var_out(var_out.count) := var_element; 
  end loop; 


  --var_out.extend(1); 
  var_out.extend; 
  var_out(var_out.count) := var_tmp; 


  return var_out; 
end split_str; 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26230597/viewspace-1139367/,如需轉載,請註明出處,否則將追究法律責任。

相關文章