【问题标题】:Extract multiple fields from clob从clob中提取多个字段
【发布时间】:2017-06-15 18:48:12
【问题描述】:

我有一个带有 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 选项似乎不起作用。

【问题讨论】:

  • 在&lt;value&gt; 元素之前去掉{CR}{LF} 和; 分隔的字符串。然后看起来你应该能够将它作为 XML 处理。
  • 也许吧,但是去掉这些字段并不像听起来那么容易。因为 outputLocale;runOptionEnum;runOptionLanguageArray;123 部分在 clob 中的长度是可变的。
  • SELECT REGEXP_REPLACE( clob_field, '(^|&lt;/value&gt;).*?($|&lt;value)|\{cr\}\{lf\}', '\1\2' ) FROM table_name; 应该去掉它。
  • 感谢您的回复.. 但您的代码似乎没有对输出进行任何更改。有没有办法搜索并只显示 esa2017@blah.nl 之间的字段?

标签: oracle substr clob


【解决方案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

【讨论】:

  • 优秀.. 开箱即用!从此我可以继续!
猜你喜欢
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 2023-03-09
  • 2014-01-24
  • 2011-08-02
  • 2022-10-04
  • 2021-08-01
  • 1970-01-01
相关资源
最近更新 更多