例子:

     一个字符串"11,15,13,17,12",以逗号分割,现在要排序成"11,12,13,15,17"。

写了一个实现方法,记录下来以备后用:

--------------------------------------------------------
-- Export file for user BEN                           --
-- Created by Administrator on 2015/8/5 星期三, 10:24:20 --
--------------------------------------------------------

set define off
spool get_bubble.log

prompt
prompt Creating function GET_BUBBLE
prompt ============================
prompt
create or replace function Get_BUBBLE
(
  av_str varchar2,  --要分割的字符串
  av_split varchar2  --分隔符号

)
return varchar2
is
  lv_str varchar2(1024); 
  str  varchar2(1024); 
  str1 varchar2(1024); --进行交换的第一个子串
  str2 varchar2(1024); --进行交换的第二个子串
  temp varchar2(1024); --临时交换中间空间
  new_str varchar2(1024); --内层循环每次交换的最大值
  all_str varchar2(1024); --保存每次循环后生成的新串
  end_str varchar2(1024); --最终值,返回值
  lv_length number; --分割后的子串个数
  jflag char(1); --每次外循环后首次内循环的标识
  i number := 0; --外循环控制
  j NUMBER := 0; --内循环控制
  x number;  --首次内循环第一个子串截取位置
  k number;  --首次内循环第二个子串截取位置
  y number;  
  z number;  --非首次内循环子串截取的位置
begin
  lv_str    := ltrim(rtrim(av_str)); --去前后空格
  str       := lv_str;
  lv_length := 0;
  ----分割串【得到子串个数】
  while instr(str,av_split)<>0 loop
     lv_length:=lv_length+1;
     str:=substr(str,instr(str,av_split)+length(av_split),length(str));
  end loop;
  lv_length:=lv_length+1; 
  if lv_length <= 1 then
    return '分割后只有一个子串';
  end if;
------------------------------------------------  
  end_str := '';
  <<loop1>>
  loop --外循环
    if i < lv_length then
      j := i+1; 
      jflag := 0;
      new_str := '';
      all_str := '';
      <<loop2>>
      loop --内循环
        if j < lv_length then
          if jflag = 0 then -- 首次内循环(方便处理子串的拼接问题)
            select instr(lv_str, av_split, 1) into x from dual;
            str1 := substr(lv_str, 1, x-1);
            --decode处理最后一个子串截取位置为0的问题
            select decode(instr(lv_str, av_split, x+length(av_split)),0,length(lv_str)+1,instr(lv_str, av_split, x+length(av_split))) into k from dual;
            str2 := substr(lv_str, x+length(av_split), k-x-length(av_split));
            select count(*) into y from dual where str1 > str2;
            if y > 0 then
              new_str := str1;
              temp := str1;
              str1 := str2;
              str2 := temp;      
            else
              new_str := str2;
            end if;
            all_str := str1; 
            jflag := 1;
          else --非首次
            str1 := new_str; --上次比较后的最大值作为这次比较的前一个值
            select decode(instr(lv_str, av_split, k+length(av_split)),0,length(lv_str)+1,instr(lv_str, av_split, k+length(av_split))) into z from dual;
            str2 := substr(lv_str, k+length(av_split), z-k-length(av_split)); --第二个
            k := z; -- z赋给k,方便下一次截取str2
            select count(*) into y from dual where str1 > str2;
            if y > 0 then
              new_str := str1;
              temp := str1;
              str1 := str2;
              str2 := temp;      
            else 
              new_str := str2;
            end if;
            all_str := all_str||av_split||str1; 
          end if;
        end if;
        j := j+1;
        exit loop2 when j >= lv_length;
        
      end loop loop2;
      lv_str := all_str||av_split||new_str; --上一轮内循环生成的新串
      
      if end_str is null then --最终的子串处理
        end_str := new_str;
      else
        end_str := new_str||av_split||end_str;
      end if;
           
   end if;
    i := i+1;
    exit when i >= lv_length-1;
  end loop loop1;
  end_str := str1||av_split||end_str; --返回前拼接上最后一个值

  return  end_str;
end Get_BUBBLE;
/


spool off

 

posted on 2015-08-05 11:28  笨笨多  阅读(788)  评论(0编辑  收藏  举报