请告诉我如何更改以下代码:
with temp as
(
select 108 Name, 'test' Project, 'string-1 , string-2 ; string-3' Error from dual
union all
select 109, 'test2', 'single string' from dual
)
select distinct
t.name, t.project,
trim(regexp_substr(t.error, '[^,;]+', 1, levels.column_value)) as error
from
temp t,
table(cast(multiset(select level from dual connect by level <= length (regexp_replace(t.error, '[^,;]+')) + 1) as sys.OdciNumberList)) levels
order by name;
进入一个通用函数,该函数接受一个字符串作为参数(例如:)'string--1, string-2 ; string-3 , string-4'和一个指定搜索行分隔符的正则表达式(例如:)'\s*[,;]\s*':
FUNCTION csvstr2tab(
p_str IN VARCHAR2,
p_sep_re IN VARCHAR2 DEFAULT '\s*[,;]\s*'
)
...
作为我自己的尝试,这是一个使用固定行分隔符 ( ',') 完成给定任务的函数:
create or replace type admin.strtable as table of varchar2(1000);
/
create or replace
function admin.str2tbl ( p_str in varchar2 ) return strtable
as
l_str long default p_str || ',';
l_n number;
l_data strtable := strtable();
begin
loop
l_n := instr( l_str, ',' );
exit when (nvl(l_n,0) = 0);
l_data.extend;
l_data( l_data.count ) := ltrim(rtrim(substr(l_str,1,l_n-1)));
l_str := substr( l_str, l_n+1 );
end loop;
return l_data;
end;
/
P.S. sql<>小提琴
更新:我使用缩写 CSV 只是为了表明我正在处理包含分隔符分隔的子字符串的字符串。事实上,输入字符串根本不一定是“有效”的 CSV。
试试下面的可重现示例(在版本 12.2.0.1.0 上测试)。
架构准备:
函数本身:
请求和结果: