我有这个查询:
SELECT ROWNUM AS num_row,
REGEXP_SUBSTR(REPLACE('param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;',
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value
FROM dual
CONNECT BY REGEXP_SUBSTR(REPLACE('param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;',
';;',
'; ;'),
'[^;]+',
1,
level) IS NOT NULL
带输出:
1 param1
2 param2
3 param3
4
5 param5
6
7 param7
8
9 param10
10 param11
11 param12
12 param13
13 param14
14 param15
正如您已经看过(或不是),在参数7和10之间应该有两个NULL参数,但是这个查询只返回一个。
如果我在'param10'之前再添加一个分号或将';; param10'改为'; ; param10' - > param10在第10行,但这是我不能做的事情。
似乎更长的';'序列oracle总是喜欢有分号-1。
有没有人知道如何修复它?
答案 0 :(得分:4)
如果我是你,我会通过在connect by子句中使用regexp_count来简化事情(看起来你的参数总是以分号结尾,所以不管有多少个冒号,你想循环遍历字符串很多次。)
此外,[^<characters>]
方法不处理空值,因此您需要切换到(.*?)(;|$)
的模式 - 即。零个或多个字符后跟一个分号,然后只选择第一次进行(`。*?)。
这意味着你可以这样做:
WITH sample_data AS (SELECT 'param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;' str FROM dual)
SELECT LEVEL AS num_row,
REGEXP_SUBSTR(REPLACE(str,
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value,
REGEXP_SUBSTR(str, '(.*?)(;)', 1, LEVEL, NULL, 1) new_str
FROM sample_data
CONNECT BY LEVEL <= regexp_count(str, ';');
NUM_ROW PAR_VAL NEW_STR
---------- ------- -------
1 param1 param1
2 param2 param2
3 param3 param3
4
5 param5 param5
6
7 param7 param7
8
9 param10
10 param11 param10
11 param12 param11
12 param13 param12
13 param14 param13
14 param15 param14
15 param15
注意,如果尾部分号实际上意味着它后面有一个空参数,那么你需要切换到(.*?)(;|$)
的模式(即零个或多个字符后跟一个分号或者字符串的结尾),加上你需要在regexp_count结果中添加一个:
WITH sample_data AS (SELECT 'param1;param2;param3;;param5;;param7;;;param10;param11;param12;param13;param14;param15;' str FROM dual)
SELECT LEVEL AS num_row,
REGEXP_SUBSTR(REPLACE(str,
';;',
'; ;'),
'[^;]+',
1,
level) AS par_value,
REGEXP_SUBSTR(str, '(.*?)(;|$)', 1, LEVEL, NULL, 1) new_str
FROM sample_data
CONNECT BY LEVEL <= regexp_count(str, ';') + 1;
NUM_ROW PAR_VAL NEW_STR
---------- ------- -------
1 param1 param1
2 param2 param2
3 param3 param3
4
5 param5 param5
6
7 param7 param7
8
9 param10
10 param11 param10
11 param12 param11
12 param13 param12
13 param14 param13
14 param15 param14
15 param15
16