分割字符串,并取到相应的分割字符串

写一个函数或方法实现:传入“一个字符串,分割符,第几段”能够得到相应的字符串。 
如传入字符串 "abc|123|def|456",按"|" 分割,
第1段,那就应该返回“abc“;
第2段,那就应该返回“123”;
第3段,那就应该返回“def”;
第4段,那就应该返回“456”;
找不到则返回null;

 

第一种:适用简单的获取
 fun_get_substr(instring varchar2, num  number,vsplit   varchar2)
--instring 传入的字符串,待分割   
 --num 分割后取第几段字符
--vsplit 分割符  
-------------------------------------------------------------------------------
SQL> select fun_get_substr('ab,c|de,f|g',2,'|') from dual;
 
FUN_GET_SUBSTR('AB,C|DE,F|G',2
--------------------------------------------------------------------------------
de,f
 

函数代码:

create or replace function split_str(i_str varchar2,i_split varchar2,i_num number)
return varchar2 is
  v_split_str varchar2(1000);
  v_first     number;
  v_last      number;
begin
  if i_str is null then
    v_split_str := 'The input string is null';
    return v_split_str;
  end if;
 
  if i_num < 1 then
    v_split_str := 'you must input the position of the split '||'"'||i_split||'"';
    return v_split_str;
  end if;

  if i_num =1 then
    v_first := 1;
    v_last  := instr(i_str,i_split,1,i_num);
  else
    v_first := instr(i_str,i_split,1,i_num-1)+1;
    if v_first =1 then
       v_split_str := 'There are not enough split'||
                      '"'||i_split||'"'||' in '||i_str||
                      ' Or you input the error split!';
       return v_split_str;
    end if; 
    v_last  := instr(i_str,i_split,1,i_num);
  end if; 
 
  if v_last = 0 then
    v_last := length(i_str) + 1;
  end if;
 
  v_split_str := substr(i_str,v_first,v_last-v_first);
 
  return v_split_str;
end split_str;

 

 

第二种:适用字符串分割后,每段的内容被反复的取出,多次使用。
(定义一个数组 过程包加载时就初始化 将分割好的每段存入数组中,待取用)
SQL> select PKG_test_substring.get_subString(2) from dual;
 
PKG_TEST_SUBSTRING.GET_SUBSTRI
--------------------------------------------------------------------------------
de,f

 

create or replace package pkg_test_substring is

  type arr_sub is table of varchar2(100) index by binary_integer;
  sub_data  arr_sub;
 
  function get_subString(v_idx in varchar2) return varchar2;
 
  procedure init_data(v_string in varchar2,
                      vsplit   in varchar2,
                      v_sub    out arr_sub);
                     
end pkg_test_substring;

 

create or replace package body PKG_test_substring is

 -- sub_data  pkg_test_substring.arr_sub;
  --sub_data array_sub;

  --初始化字符串 以传入的分割符,分割字符串为数组,然后返回分割后的数组
  procedure init_data(v_string in varchar2,
                      vsplit   in varchar2,
                      v_sub    out arr_sub) is
    last_str varchar2(32767) := v_string;
    i        number := 1;
  begin
    if v_string is null or instr(v_string, vsplit) = 0 then
      v_sub.delete;
      goto mask_error;
    end if;
    --循环分割,把分割结果存入数组
    while instr(last_str, vsplit) > 0 loop
      v_sub(i) := substr(last_str, 1, instr(last_str, vsplit) - 1);
      last_str := substr(last_str, instr(last_str, vsplit) + 1);
      i := i + 1;
    end loop;
    v_sub(i) := last_str;

    <<mask_error>>
    null;
  end init_data;

  --取初始化好后的数组内的数据
  --v_idx :第几个字符串
  function get_subString(v_idx in varchar2) return varchar2 is
  begin
    if not sub_data.exists(v_idx) then
      return null;
    else
      return sub_data(v_idx);
    end if;
  end get_subString;

  begin
  init_data('ab,c|de,f|g', '|', sub_data);
 
end PKG_test_substring;

 

 OR--------------------------------------------------------

CREATE OR REPLACE TYPE ty_str_split IS TABLE OF VARCHAR2 (4000);

create or replace function fn_split
(
  p_str       in varchar2,
  p_delimiter in varchar2
) return ty_str_split is
  j         int := 0;
  i         int := 1;
  len       int := 0;
  len1      int := 0;
  str       varchar2(4000);
  str_split ty_str_split := ty_str_split();
begin
  len  := length(p_str);
  len1 := length(p_delimiter);

  while j < len
  loop
    j := instr(p_str, p_delimiter, i);
 
    if j = 0
    then
      j   := len;
      str := substr(p_str, i);
      str_split.extend;
      str_split(str_split.count) := str;
   
      if i >= len
      then
        exit;
      end if;
    else
      str := substr(p_str, i, j - i);
      i   := j + len1;
      str_split.extend;
      str_split(str_split.count) := str;
    end if;
  end loop;

  return str_split;
end fn_split;

测试:

DECLARE
  CURSOR c
IS
  SELECT * FROM TABLE (CAST (fn_split ('1;;12;;123;;1234;;12345', ';;') AS ty_str_split));
  r c%ROWTYPE;
BEGIN
  OPEN c;
  LOOP
    FETCH c INTO r;
    EXIT WHEN c%NOTFOUND;
      DBMS_OUTPUT.put_line (r.column_value);
  END LOOP;
  CLOSE c;
END;
/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值