从clob中提取多个字段

时间:2017-01-30 14:52:59

标签: oracle substr clob

我有一个带有clob字段的oracle数据库。字段中的数据看起来像这样(这是clob中1行的数据);

outputLocale;runOptionEnum;runOptionLanguageArray;123;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:string[1]">{CR}{LF}
{>>}<item xsi:type="xsd:string">en-us</item>{CR}{LF}
</value>{CR}{LF}
ccAddress;deliveryOptionEnum;deliveryOptionAddressSMTPArray;207;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:addressSMTP[2]">{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">bccesa@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">blah@blah.nl</item>{CR}{LF}
</value>{CR}{LF}
toAddress;deliveryOptionEnum;deliveryOptionAddressSMTPArray;271;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:addressSMTP[3]">{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa2017@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa2018@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa9@blah.nl</item>{CR}{LF}
</value>{CR}{LF}

我需要将电子邮件地址作为一行提取,因此首选输出为bccesa@blah.nl,blah@blah.nl,esa2017@blah.nl,esa2018@blah.nl,esa9@blah.nl等等。有些行有1个电子邮件地址,有些行有10个。

我试图首先使用substr和instr函数定位字段,但我认为有一种更简单的方法可以做到这一点。数据可能看起来像XML,但最终它不是..所以xml oracle选项似乎不起作用。

1 个答案:

答案 0 :(得分:1)

将文本换行到XML元素中,然后将其解析为XML:

Oracle安装程序

CREATE TABLE table_name ( id INT, clob_field CLOB );

INSERT INTO table_name (
  id, clob_field
) VALUES (
  1, 'outputLocale;runOptionEnum;runOptionLanguageArray;123;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:string[1]">{CR}{LF}
{>>}<item xsi:type="xsd:string">en-us</item>{CR}{LF}
</value>{CR}{LF}
ccAddress;deliveryOptionEnum;deliveryOptionAddressSMTPArray;207;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:addressSMTP[2]">{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">bccesa@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">blah@blah.nl</item>{CR}{LF}
</value>{CR}{LF}
toAddress;deliveryOptionEnum;deliveryOptionAddressSMTPArray;271;<value xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="bus:addressSMTP[3]">{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa2017@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa2018@blah.nl</item>{CR}{LF}
{>>}<item xsi:type="bus:addressSMTP">esa9@blah.nl</item>{CR}{LF}
</value>{CR}{LF}'
);

<强>查询

SELECT t.id,
       LISTAGG( x.address, ',' ) WITHIN GROUP ( ORDER BY ROWNUM ) AS addresses
FROM   table_name t
       CROSS JOIN
       XMLTABLE(
         '/SOAP-ENC/value/item[@xsi:type="bus:addressSMTP"]'
         PASSING XMLType(
           '<?xml version="1.0" encoding="utf-8"?>
            <SOAP-ENC xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xmlns:xsd="http://www.w3.org/2001/XMLSchema">'
           || t.clob_field
           || '</SOAP-ENC>'
         )
         COLUMNS address VARCHAR2(200) PATH 'text()'
       ) x
GROUP BY t.id;

<强>输出

ID ADDRESSES
-- ------------------------------------------------------------------------
 1 bccesa@blah.nl,blah@blah.nl,esa2017@blah.nl,esa2018@blah.nl,esa9@blah.nl