寻找功能拆分字符串Oracle

时间:2017-08-18 17:02:11

标签: oracle function plsql

我正在寻找像这样的Oracle中的函数

例如

select xxx('orange,apple,banana,strawberry,Blueberry,tomato', ',' 3) from dual;

然后显示

orange,apple,banana,

重要的是','到3

select xxx('orange,apple,banana,strawberry,Blueberry,tomato', ',' ,2,3) from dual;

显示

banana,strawberry,Blueberry,

我希望这是有道理的

比你这么多

1 个答案:

答案 0 :(得分:2)

没有一个内置功能可以做到这一点。你可以接近正则表达式。但您也可以根据逗号创建自己的函数来识别所需细分的起始位置和结束位置:

create function foo(p_str varchar2, p_delimiter varchar2,
  p_occurrences number, p_position number default 0)
return varchar2 is
  l_start pls_integer;
  l_end pls_integer;
  l_length pls_integer;
  l_result varchar2(4000);
begin
  l_start := case when p_position = 0 then 1
    else instr(p_str, p_delimiter, 1, p_position) + 1 end;
  l_end := instr(p_str, p_delimiter, l_start, p_occurrences);
  l_length := case when l_end = 0 then length(p_str) - l_start + 1
  else l_end - l_start end;

  l_result := substr(p_str, l_start, l_length);

  return l_result;
end;
/

然后,当您提供两个参数时,交换示例中的参数(只是为了允许position的默认值像这样工作):

select foo('orange,apple,banana,strawberry,Blueberry,tomato', ',', 1) from dual;

orange

select foo('orange,apple,banana,strawberry,Blueberry,tomato', ',', 3) from dual;

orange,apple,banana

select foo('orange,apple,banana,strawberry,Blueberry,tomato', ',', 3, 2) from dual;

banana,strawberry,Blueberry

select foo('orange,apple,banana,strawberry,Blueberry,tomato', ',', 3, 5) from dual;

tomato

如果你要求的次数多于那么多,那么它只返回存在的数量(即最后一次调用只是'番茄',尽管要求3个元素)。如果您的起始位置高于逗号数,则返回原始字符串,但如果您愿意,可以将其修改为返回null。

您可以使用直接substrinstr调用在纯SQL中执行此操作,但它会有点混乱。

另一种方法是标记原始字符串(allowing for null elements),选择要保留的标记,然后将它们粘在一起:

select listagg(token, ',') within group (order by position) as result
from (
  select level as position,
    regexp_substr('orange,apple,banana,strawberry,Blueberry,tomato',
      '(.*?)(,|$)', 1, level, null, 1) as token
  from dual
  connect by level <
    regexp_count('orange,apple,banana,strawberry,Blueberry,tomato', '(.*?)(,|$)')
)
where position between 3 and 5;

banana,strawberry,Blueberry