2015-12-15 42 views
0

不规则的字符串我有数据,并有类似的问题这个问题:Parsing pipe delimited string into columns?解析管道分隔,在Oracle

但是我的数据可以包含没有数据,或者说是不完整的串子串。请注意5个值是最大值。除非字符串有5个值,否则上述问题的解决方案将失败。请看下图:

KEY   VALUE        
----  ------------------- 
00   val1||||val5         
01   val2|val2|val3|       
02   val1|val2||val4 
+0

什么是你想要的输出?一行五列?在0行和5行之间有两列?还有别的吗?我不确定你在尝试什么,可能是'regexp_substr'和什么“失败”。 –

+0

我需要将分隔符上的值列拆分为5列。 '根据标准,'dual'选择regexp_substr('val1 | val2 ||| val5','[^ |] +',1,3)将产生'val5',因为它是第三个值。我的目标是将这些数据转移到一个有目的的表格中。 –

+0

如果你将它编辑到你的问题中(这是你正在使用的代码和你想要输入数据的输出),这将会很有帮助。 –

回答

1

设置

CREATE TABLE TABLE_NAME (KEY, VALUE) AS 
SELECT '00',   'val1||||val5' FROM DUAL UNION ALL 
SELECT '01',   'val2|val2|val3|' FROM DUAL UNION ALL 
SELECT '02',   'val1|val2||val4' FROM DUAL; 

查询1

SELECT Key, 
     REGEXP_SUBSTR(value, '([^|]*)(\||$)', 1, 1, NULL, 1) AS val1, 
     REGEXP_SUBSTR(value, '([^|]*)(\||$)', 1, 2, NULL, 1) AS val2, 
     REGEXP_SUBSTR(value, '([^|]*)(\||$)', 1, 3, NULL, 1) AS val3, 
     REGEXP_SUBSTR(value, '([^|]*)(\||$)', 1, 4, NULL, 1) AS val4, 
     REGEXP_SUBSTR(value, '([^|]*)(\||$)', 1, 5, NULL, 1) AS val5 
FROM table_name 

结果

KEY VAL1   VAL2   VAL3   VAL4   VAL5   
--- --------------- --------------- --------------- --------------- --------------- 
00 val1               val5    
01 val2   val2   val3            
02 val1   val2       val4        
+0

谢谢,这似乎工作。你能帮我理解你对比赛和次表达参数以及第二个捕获组的使用吗?为什么没有一个'以|结束|'以同样的方式工作? –

+1

要匹配'||'之间的空字符串,您需要从'[^ |] +'更改为零宽度匹配'[^ |] *'。然而,当你有'| val |' - 与'val'匹配,然后在分隔符之前出现不需要的零宽度匹配时,这会产生两个匹配的副作用;为了解决这个问题,你需要确保你在匹配'[^ |] * \ |'中包含分隔符,但是它不会匹配最后一个值,所以你需要匹配分隔符或者字符串末尾'[[^|] *(\ $ ||)'。它给你你想要的,但包括分隔符,所以你可以使用捕获组来提取所需的值'([^ |] *)(\ || $)''。 – MT0

1

如果使用PL/SQL和循环是OK,你可以使用apex_util.string_to_table:

declare 
    l_tab apex_application_global.vc_arr2; 
begin 
    for r in (select key, value from mytable) loop 
     l_tab := apex_util.string_to_table (r.value, '|'); 
     dbms_output.put_line ('key='||r.key); 
     for i in 1..l_tab.count loop 
     dbms_output.put_line ('value ' || i || '='||l_tab(i)); 
     end loop; 
    end loop; 
end;