抽空写段代码,简单测试成功,
请大侠们帮看看, 有没有更简练的方法,本菜鸟想学习,谢谢!
-- ------------------------------------------------------------------
-- Name            : split_pac.sql
-- Author          : 追寻
-- Created         : 2010-12-29
-- purpose         : 实现类似于Java语言中String的split方法
-- Srl No       Date        Name             Description
-- ------ -------------- -----------      ------------------
--   1      29/Dec/2010    追寻           Original Version    
-- ------------------------------------------------------------------
CREATE OR REPLACE PACKAGE split_pac AS    TYPE ArrayList IS TABLE OF VARCHAR2(500)  INDEX BY BINARY_INTEGER;
        PROCEDURE split_pro( inpString IN    VARCHAR2, 
                         splitChar IN    CHAR, 
                         outArr    OUT   ArrayList);                         END split_pac;
/
CREATE OR REPLACE PACKAGE BODY split_pac AS    PROCEDURE split_pro( inpString IN    VARCHAR2, 
                         splitChar IN    CHAR, 
                         outArr    OUT   ArrayList) IS
                                                                                
        v_tempString VARCHAR2(2000):= NULL;
        -- 分割符
        v_splitChar CHAR:= NULL;                                                
        v_outArr ArrayList;
        
        v_splitCharCount NUMBER(4,0):= 0;        v_Count NUMBER(4,0):= 0;
                                              
    BEGIN
    
        v_tempString := inpString;
        v_splitChar := splitChar;
    
        LOOP
        --{
            v_Count := v_Count +1;
            
            -- INSTR(x, find_string [,start] [,occourrence])
            -- 在 x 中查找字符串find_string,然后返回find_string的位置
            -- start      指定该函数从该位置查找 (小于0时 ?)
            -- occurrence 指定第几次出现的位置
            IF (instr(v_tempString,v_splitChar) = 0) OR (v_tempString IS NULL)  THEN
            --{
               v_outArr(v_Count) := v_tempString;
               EXIT;
            --}
            END IF;
            
            IF instr(v_tempString,v_splitChar) = 1 THEN
            --{
            
            -- SUBSTR(x, start [,length])
            -- 返回x中的一个子字符串,
            -- start   指定开始位置,当 start < 0 时,倒着数start个开始从左向右截取
            -- length  指定子字符串的长度
               v_tempString := substr(v_tempString,(length(v_splitChar)+1));
               v_tempString := ltrim(v_tempString,v_splitChar);
            --}
            ELSE 
            --{
               v_outArr(v_Count) := substr(v_tempString,1,(instr(v_tempString,v_splitChar)-1));
               v_tempString := substr(v_tempString,(instr(v_tempString,v_splitChar)+length(v_splitChar)));
            --}
            END IF;
            
        --}
        END LOOP;
         
    outArr := v_outArr;
    
    EXCEPTION 
    WHEN OTHERS THEN
         dbms_output.put_line(' exists errs ');
    END split_pro;END split_pac;
/下面是测试代码:DECLARE
       
     arrList dbscust.split_pac.ArrayList;
     i NUMBER:=0;BEGIN
     split_pac.split_pro('D:\work\2010-12-20','\',arrList);
     LOOP
         i:=i+1;         IF arrList(i) IS NULL THEN
             EXIT;
         ELSE
             dbms_output.put_line(arrList(i));
         END IF;
     END LOOP;END;再次表示感谢!

解决方案 »

  1.   

    代码不够简练,导致太长了,sorry,希望能看到精彩的回复~~
      

  2.   

    好像直接由split这个库函数
    再不然自己写一个function啊,也没这么复杂吧
      

  3.   

    if not object_id('Tab') is null
        drop table Tab
    Go
    Create table Tab([Col1] int,[COl2] nvarchar(5))
    Insert Tab
    select 1,N'a,b,c' union all
    select 2,N'd,e' union all
    select 3,N'f'
    Go--SQL2000用辅助表:
    if object_id('Tempdb..#Num') is not null
        drop table #Num
    go
    select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
    Select 
        a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID) 
    from 
        Tab a,#Num b
    where
        charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
    --2000不使用辅助表
    Select
        a.Col1,COl2=substring(a.Col2,b.number,charindex(',',a.Col2+',',b.number)-b.number) 
    from 
        Tab a join master..spt_values  b 
        ON B.type='p' AND B.number BETWEEN 1 AND LEN(A.col2)
    where
         substring(','+a.COl2,b.number,1)=','ms sql  里的处理方法 。我按照这个思路改的,
    不过好像报错,呵呵。declare 
     str:='D:\work\2010-12-20'
    begin
    select substr(str,n,instr(str+'\','\',n)-n)
    from (select rownum as n from tab)t
    where substr(str,n,1)='\';
    end
    str:='D:\work\2010-12-20'
        *第 2 行出现错误: 
    ORA-06550: 第 2 行, 第 5 列: 
    PLS-00103: 出现符号 "="在需要下列之一时: constant 
    exception 
    <an identifier> <a double-quoted delimited-identifier> table 
    LONG_ double ref char time timestamp interval date binary 
    national character nchar 
      

  4.   

    select substr(str,n,instr(str||'\','\',n)-n) col
    from 
    (select 'D:\work\2010-12-20' as str from dual) a,
    (select rownum as n from tab)t
    where substr('\'||str,n,1)='\';COL  
    -------
    D:  
    work  
    2010-12-20  这个可以
      

  5.   

    select regexp_substr('D:\work\2010-12-20','[^\\]+',1,rownum) from dual
    connect by rownum<=length('D:\work\2010-12-20')-length(replace('D:\work\2010-12-20','\\',''))+1
      

  6.   


    -------不要使用双斜杠
    SQL> 
    SQL> select regexp_substr('D:\work\2010-12-20', '[^\]+', 1, rownum)
      2    from dual
      3  connect by rownum <= length('D:\work\2010-12-20') -
      4             length(replace('D:\work\2010-12-20', '\', '')) + 1
      5  ;REGEXP_SUBSTR('D:\WORK\2010-12
    ------------------------------------------------------------------------
    D:
    work
    2010-12-20SQL> 
      

  7.   

    你不就当表使用啊,难道使用数据比表方便吗?
    谁说忽略了,只是他显示在最后一行而已。你如果要去掉为空的嵌套一下,在where里加上is not null
    呵呵。。
    testSQL> 
    SQL> select nvl(regexp_substr('D:\work\\2010-12-20', '[^\]+', 1, rownum),'this row is null')
      2    from dual
      3  connect by rownum <= length('D:\work\\2010-12-20') -
      4             length(replace('D:\work\\2010-12-20', '\', '')) + 1
      5  ;NVL(REGEXP_SUBSTR('D:\WORK\\20
    ----------------------------------------------------------------------------
    D:
    work
    2010-12-20
    this row is nullSQL> 
      

  8.   


    --固定的格式的
    scott@ORCL> create or replace package pack_arr
      2  as
      3  type arr_type is table of  varchar2(100);
      4  function fun_arr(c_str varchar2,c_sepstr varchar2) return arr_type pipelined;
      5  end;
      6  /程序包已创建。scott@ORCL> ed
    已写入 file afiedt.buf  1  create or replace package body pack_arr
      2  as
      3  function fun_arr(c_str varchar2,c_sepstr varchar2) return arr_type pipelined
      4  as
      5  arr pack_arr.arr_type:=pack_arr.arr_type();
      6  str varchar2(1000);
      7  cnt number;
      8  begin
      9  cnt:=length(c_str)-length(replace(c_str,c_sepstr,''))+1;
     10  str:=c_sepstr||c_str||c_sepstr;
     11  for i in 1..cnt loop
     12  arr.extend;
     13  select
     14  substr(str,instr(str,c_sepstr,1,i)+1,abs(instr(str,c_sepstr,1,i+1)-instr(str,c_sepstr,1,i)-1))
     15  into arr(i) from dual;
     16  pipe row(arr(i));
     17  end loop;
     18  return;
     19  end fun_arr;
     20* end;
    scott@ORCL> /程序包体已创建。scott@ORCL> select * from table(pack_arr.fun_arr('D:\work\2010-12-20','\'))
      2  /COLUMN_VALUE
    --------------------------------------------------------------------------------
    D:
    work
    2010-12-20
      

  9.   

    我们系统中正在使用的一个函数
    create or replace function split(p_list varchar2,p_sep varchar2 := ',') return type_split pipelined
    IS
     l_idx pls_integer;
     v_list varchar2(4000) := p_list; begin
          loop
               l_idx := instr(v_list,p_sep);
               if l_idx > 0 then
                   pipe row(substr(v_list,1,l_idx-1));
                   v_list := substr(v_list,l_idx+length(p_sep));
               else
                    pipe row(v_list);
                    exit;
               end if;      end loop;
          return;
     end split;
      

  10.   

    CREATE OR REPLACE TYPE "TYPE_SPLIT"                                                                    IS TABLE OF VARCHAR2 (4000)
      

  11.   

    新年好,再请教一下:
    regexp_substr() 里 1的位置是start 即指定开始位置,rownum 是指第几次匹配的位置,
    问题如下:SELECT nvl(regexp_substr('D:\work\2010-12-20\', '[^\]+',1, 3),'null')
    FROM dual
    -- 结果是: 2010-12-20 而不是: D:\work\2010-12-20
    -- 说明: 3 是指第三次匹配到'[^\]+'的末尾的位置,而1是指指第三次匹配到'[^\]+'的开头的位置的位置-- 按上面的推断下面的结果是D后面的冒号
    SELECT nvl(regexp_substr('D:\work\2010-12-20\', '[^\]+',2, 1),'null')
    FROM dual
    --对的,结果是D后面的冒号
    -- 如果上面的推断没错的话, 将start 位置改为2,结果应该是: 010-12-20
    SELECT nvl(regexp_substr('D:\work\2010-12-20\', '[^\]+',2, 3),'null')
    FROM dual
    -- 但结果也是:2010-12-20
    -- 如果将start 位置改为3的话,结果却变成了: null为什么会这样?:[ ] Bracket expression for specifying a matching list that should match any
    one of the expressions represented in the list. A nonmatching list
    expression begins with a circumflex (^) and specifies a list that matches
    any character except for the expressions represented in the list.