oracle 使用连接级别对空值使用PL/SQL拆分字符串

x4shl7ld  于 2023-06-29  发布在  Oracle
关注(0)|答案(6)|浏览(123)

我在Oracle pl/sql中使用了以下代码(版本:Oracle数据库11 g版本11.2.0.1.0)

select regexp_substr('A~B~C','[^~]+',1,level) output
from dual
connect by level <= length(regexp_replace('A~B~C','[^~]+')) + 1

其给出以下结果

row1: A
row2: B
row3: C

这是完美的,但是我应该给予一个空值,即:

select regexp_substr('~B~C','[^~]+',1,level) output
from dual
connect by level <= length(regexp_replace('~B~C','[^~]+')) + 1

我期待并想要以下内容:

row1: <null>
row2: B
row3: C

但是得到了这个输出:

row1: B
row2: C
row3: null

我的pl/sql代码做错了吗?我怎样才能让它正常工作?

mnowg1ta

mnowg1ta1#

你可以合并INSTRSUBSTR来实现你想要的结果:

select  
  str, 
  replace(substr(str, 
                 case level 
                 when 1 then 0 
                 else instr( str, '~',1, level-1) 
                 end 
                  +1,
                 1
                ), '~')
from ( select 'A~B~C~D~E' as str from dual)
connect by level <= length(regexp_replace(str,'[^~]+')) + 1
;
wtlkbnrh

wtlkbnrh2#

可以在ORDER BY子句中使用NULLS FIRST

select regexp_substr('~B~C','[^~]+',1,level) output
from dual
connect by level <= length(regexp_replace('~B~C','[^~]+')) + 1
ORDER BY regexp_substr('~B~C','[^~]+',1,level) NULLS FIRST;

从Oracle文档中引用
如果未指定空值顺序,则对空值的处理为:
NULLS LAST if the sort is ASC
NULLS FIRST if the sort is DESC
如果既未指定升序也未指定降序,并且也未指定空顺序,则使用两个默认值,因此顺序将以NULLS LAST递增。

ulydmbyx

ulydmbyx3#

因为我在问题中使用了单个字符作为示例,但实际上我在项目中使用了长字符串,例如'How~do~I~do~this'
感谢chris 227,我从OTN Oracle.com中找到了这个解决方案。

SELECT CAST(REGEXP_SUBSTR (str, '(.*?)(~|$)', 1, level, null, 1) AS CHAR(12))  output
FROM (select 'How~do~I~do~this' as str from dual)
CONNECT BY level <= regexp_count(str, '~') + 1;

这将工作,甚至与单一的字符。
希望这将有助于其他人寻找类似的解决方案。

368yc8dk

368yc8dk4#

我知道现在已经很晚了,但我认为你(和我)需要的是:

select REPLACE(regexp_substr('A~~C','[^~]*(~)?',1,level),'~') output, level
from dual
connect by level <= length(regexp_replace('A~~C','[^~]+')) + 1
ORDER BY level;
vojdkbi0

vojdkbi05#

由于这个问题在我的脑海中是新鲜的,我碰巧看到这个帖子,我恭敬地提交我的建议,建立在user3767503的答案。它减少了所需的函数调用次数。它使用了一些11g对regexp_substr()的更新,并利用了regexp_count(),我相信这也是在11g中引入的。它假设字段的数量是分隔符的数量加1。

select regexp_substr('AAA~X~C~~DD~~~E', '([^~]*)(~|$)', 1, level, null, 1) output, level
from dual
connect by level <= regexp_count('AAA~X~C~~DD~~~E','~') + 1 
ORDER BY level;

阅读这篇文章,了解更多关于阅读正则表达式模式的信息和细节:将逗号分隔的值拆分到列中。
底线是'[^<delimiter>]+'的常用正则表达式模式,当列表中有null时,解析字符串失败,应该避免,IMHO。

r7xajy2e

r7xajy2e6#

Select regexp_substr('~ B~ C','[^~]+',1,rownum)output From dual Connect by regexp_substr('~ B~ C','[^~]+',1,level)is not null

相关问题