第一种 用10G开始支持的正则表达式
SELECT REGEXP_SUBSTR('我,爱,玩', '[^,]+', 1,ROWNUM) FROM DUAL
CONNECT BY ROWNUM <=
LENGTH('我,爱,玩') - LENGTH(REPLACE('我,爱,玩', ',', '')) + 1;
REGEXP_SUBSTR 函数
第一个参数:被搜索的字符串, 第二个参数:字符截取正则表达式, 第三个参数:起始位置,从第几个字符开始正则表达式匹配(默认为1), 第四个参数:取第几组(默认为1)
rownum伪列序号,connect 循环 ,循环次数为串总长度-去除分隔符后=几个分隔符 +1
第二种,使用存储函数
--首先创建一个返回类型
create or replace type myTableType is table of varchar2(32676);
/**
p_list:待分割的字符串
p_sep:分隔符 默认逗号分隔,也可以指定字符或字符串。
Example:SELECT * FROM users WHERE u_id IN (SELECT COLUMN_VALUE FROM table (split ('1,2')))
返回u_id为1和2的两行数据。
*/
create or replace function my_spilt(
p_list CLOB, --待分割的字符串
p_sep VARCHAR2 := ',' --分隔符 默认逗号分隔
)
RETURN tabletype
IS
l_idx PLS_INTEGER;--这个整数类型运算快
v_list VARCHAR2 (32676) := 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;
END my_spilt;
另外一个切割函数
--定义的是变长数组类型(VARRAY)
create type type_splitstr is varray(1024) of varchar2(128);
/**
var_str:待分割的字符串
var_split:分隔符 默认逗号分隔,也可以指定字符或字符串。
Example:select * from user u where u.u_id in(select * from table(func_splitstr('1,2',',')))
返回u_id为1和2的两行数据
*/
create or replace function func_splitstr
(var_str in varchar2,--要拆分的字符串
var_split in varchar2--分隔符
)
return type_splitstr
is
var_out type_splitstr;
var_tmp varchar2(4000);
var_element varchar2(128);
begin
var_tmp := var_str;
var_out:=type_splitstr();
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;
var_out(var_out.count) := var_element; --向数组的末尾添加一个元素
end loop;
var_out.extend;
var_out(var_out.count) := var_tmp;
return var_out;
end func_splitstr;