3

我在 Oracle pl/sql 中使用以下代码(版本:Oracle Database 11g Release 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代码吗?我怎样才能让它正常工作?

4

5 回答 5

4

您可以结合INSTRundSUBSTR来获得所需的结果:

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
;
于 2013-02-12T11:46:31.870 回答
2

您可以NULLS FIRSTORDER BY子句中使用

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 文档

如果未指定 null 排序,则 null 值的处理是:

NULLS LAST if the sort is ASC

NULLS FIRST if the sort is DESC

如果既没有指定升序也没有指定降序,并且也没有指定空排序,则使用两个默认值,因此顺序将使用 NULLS LAST 升序。

于 2013-02-12T10:22:00.473 回答
2

因为我在我的问题中使用了单个字符作为示例,但实际上我在我的项目中使用了长字符串,例如'How~do~I~do~this'

感谢 chris227,我从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;

这甚至适用于单个字符。

希望这将有助于其他寻找类似解决方案的人。

于 2013-02-12T18:28:35.597 回答
0

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

select REPLACE(regexp_substr('A~~C','[^~]*(~)?',1,level),'~') output, level
from dual
connect by level <= length(regexp_replace('A~~C','[^~]+')) + 1
ORDER BY level;
于 2015-07-23T18:00:04.233 回答
0

由于这个问题对我来说是新鲜的,并且我碰巧看到了这篇文章,因此我恭敬地提交了我的建议,该建议基于 user3767503 的回答。它减少了所需的函数调用次数。它使用了一些 11g 更新regexp_substr()并利用了regexp_count()我相信在 11g 中也引入的这些更新。它假设字段的数量是分隔符的数量加一。

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;

有关阅读正则表达式模式的更多信息和详细信息,请参阅此帖子:Split comma separated values to columns

底线是常用的正则表达式模式,'[^<delimiter>]+'当列表中有空值时解析字符串失败,应该避免,恕我直言。

于 2015-07-23T19:32:11.747 回答