寻找函数拆分字符串Oracle

Posted

技术标签:

【中文标题】寻找函数拆分字符串Oracle【英文标题】:looking for function Split string Oracle 【发布时间】:2017-08-18 17:02:10 【问题描述】:

我正在寻找这样的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,

我希望这是有道理的

比你好多了

【问题讨论】:

第二个例子中的“2”代表什么?该调用是否应该从第二个分隔值开始并获取三个值?还是从第三个开始得到两个?结果也不匹配。 听起来很有趣。到目前为止你尝试过什么? @AlexPoole so orange '1',apple '2',banana '3',strawberry '4',Blueberry '5',tomato from "2," 2+3 = 5, to " 5,"因此,"香蕉、草莓、蓝莓,"我希望这对你有意义。 So.. from after 第二个逗号;在第一个查询中,隐含在“第零个”逗号之后? 是的,但这只是我编造的,我可以这样说。select xxx('orange,apple,banana,strawberry,Blueberry,tomato', ',' ,2,5) 显示香蕉、草莓、蓝莓 【参考方案1】:

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

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。

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

另一种方法是对原始字符串 (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

【讨论】:

为不使用危险的'[^,]+' 正则表达式鼓掌,当分隔列表中存在空值时,它不会返回正确的值! @Gary_W - 我试图决定是否可以将指向您帖子的链接挤进去,就像我在使用您的方法时尝试做的那样(as here;告诉您我会收藏它! );我现在也添加到这里了。 谢谢先生!当我想到那里返回的不良数据而开发人员不知道它正在发生时,我感到畏缩。 @AlexPoole 非常感谢!!!从昨天开始你就一直在帮助我

以上是关于寻找函数拆分字符串Oracle的主要内容,如果未能解决你的问题,请参考以下文章

oracle之字符串拆分

oracle 如何将一个字段里的值拆分为多个值显示出来

oracle根据某个字符拆分字符串

ORACLE 怎么拆分字符串

关于Oracle中实现单列拆分成多列的技术应用

oracle sql 字符串拆分的查询的问题,急!!!