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