![](/img/trans.png)
[英]Adding an attribute to all nodes matching an XPATH expression using Oracle XML DB
[英]Concatenate XML nodes using XPath and XQuery in Oracle
我有一個 XML 數據存儲在 CLOB 列中,如下所示:
<row id='123456' xml:space='preserve'>
<name>Martin H</name>
<phone>1111</phone>
<phone m='2'>2222</phone>
<phone m='3'></phone>
<sms m='2'>1212</sms>
<sms m='3'>2323</sms>
<email>abc@gmail.com</email>
<email m='3'>xyz@outlook.com</email></row>
如何在 Oracle DB 中使用 Xpath 和 XQuery 以僅在一行中獲得以下預期輸出:
姓名 | 電話 | 短信 | 電子郵件 |
---|---|---|---|
馬丁 H | 1111#2222# | #1212#2323 | abc@gmail.com##xyz@outlook.com |
基本上,'#' 用於分隔值,並且上述 XML 中任何組的任何缺失標記都將作為空值返回。
任何幫助都感激不盡。 謝謝!
使用XMLTABLE
將您的 XML 解析為列,然后您可以在定義路徑時使用string-join
運算符來執行與LISTAGG
類似的功能。
WITH
example_table (xml_clob)
AS
(SELECT EMPTY_CLOB () || '<row id=''123456'' xml:space=''preserve''>
<name>Martin H</name>
<phone>1111</phone>
<phone m=''2''>2222</phone>
<phone m=''3''></phone>
<sms m=''2''>1212</sms>
<sms m=''3''>2323</sms>
<email>abc@gmail.com</email>
<email m=''3''>xyz@outlook.com</email>
</row>' FROM DUAL)
SELECT xt.*
FROM example_table et
CROSS JOIN
XMLTABLE (
'row'
PASSING xmltype (et.xml_clob)
COLUMNS name VARCHAR2 (100)
PATH 'name',
phone VARCHAR2 (100)
PATH 'string-join(phone,"#")',
sms VARCHAR2 (100)
PATH 'string-join(sms,"#")',
email VARCHAR2 (100)
PATH 'string-join(email,"#")') xt;
NAME PHONE SMS EMAIL
___________ _____________ ____________ ________________________________
Martin H 1111#2222# 1212#2323 abc@gmail.com#xyz@outlook.com
在閱讀 kfinity 的評論並更清楚地理解問題后,仍然可以使用XMLTABLE
解決問題,然后使用CASE
語句將值連接在一起以獲得所需的結果。
WITH
example_table (xml_clob)
AS
(SELECT EMPTY_CLOB () || '<row id=''123456'' xml:space=''preserve''>
<name>Martin H</name>
<phone>1111</phone>
<phone m=''2''>2222</phone>
<phone m=''3''></phone>
<sms m=''2''>1212</sms>
<sms m=''3''>2323</sms>
<email>abc@gmail.com</email>
<email m=''3''>xyz@outlook.com</email>
</row>' FROM DUAL)
SELECT xt.name,
CASE
WHEN phone1_mtag IS NULL AND phone1 IS NOT NULL THEN phone1
WHEN phone2_mtag IS NULL AND phone2 IS NOT NULL THEN phone2
WHEN phone3_mtag IS NULL AND phone3 IS NOT NULL THEN phone3
END
|| '#'
|| CASE
WHEN phone1_mtag = '2' AND phone1 IS NOT NULL THEN phone1
WHEN phone2_mtag = '2' AND phone2 IS NOT NULL THEN phone2
WHEN phone3_mtag = '2' AND phone3 IS NOT NULL THEN phone3
END
|| '#'
|| CASE
WHEN phone1_mtag = '3' AND phone1 IS NOT NULL THEN phone1
WHEN phone2_mtag = '3' AND phone2 IS NOT NULL THEN phone2
WHEN phone3_mtag = '3' AND phone3 IS NOT NULL THEN phone3
END AS phone,
CASE
WHEN sms1_mtag IS NULL AND sms1 IS NOT NULL THEN sms1
WHEN sms2_mtag IS NULL AND sms2 IS NOT NULL THEN sms2
WHEN sms3_mtag IS NULL AND sms3 IS NOT NULL THEN sms3
END
|| '#'
|| CASE
WHEN sms1_mtag = '2' AND sms1 IS NOT NULL THEN sms1
WHEN sms2_mtag = '2' AND sms2 IS NOT NULL THEN sms2
WHEN sms3_mtag = '2' AND sms3 IS NOT NULL THEN sms3
END
|| '#'
|| CASE
WHEN sms1_mtag = '3' AND sms1 IS NOT NULL THEN sms1
WHEN sms2_mtag = '3' AND sms2 IS NOT NULL THEN sms2
WHEN sms3_mtag = '3' AND sms3 IS NOT NULL THEN sms3
END AS sms,
CASE
WHEN email1_mtag IS NULL AND email1 IS NOT NULL THEN email1
WHEN email2_mtag IS NULL AND email2 IS NOT NULL THEN email2
WHEN email3_mtag IS NULL AND email3 IS NOT NULL THEN email3
END
|| '#'
|| CASE
WHEN email1_mtag = '2' AND email1 IS NOT NULL THEN email1
WHEN email2_mtag = '2' AND email2 IS NOT NULL THEN email2
WHEN email3_mtag = '2' AND email3 IS NOT NULL THEN email3
END
|| '#'
|| CASE
WHEN email1_mtag = '3' AND email1 IS NOT NULL THEN email1
WHEN email2_mtag = '3' AND email2 IS NOT NULL THEN email2
WHEN email3_mtag = '3' AND email3 IS NOT NULL THEN email3
END AS email
FROM example_table et
CROSS JOIN XMLTABLE ('row'
PASSING xmltype (et.xml_clob)
COLUMNS name VARCHAR2 (100) PATH 'name',
phone1 VARCHAR2 (100) PATH 'phone[1]',
phone1_mtag VARCHAR2 (100) PATH 'phone[1]/@m',
phone2 VARCHAR2 (100) PATH 'phone[2]',
phone2_mtag VARCHAR2 (100) PATH 'phone[2]/@m',
phone3 VARCHAR2 (100) PATH 'phone[3]',
phone3_mtag VARCHAR2 (100) PATH 'phone[3]/@m',
sms1 VARCHAR2 (100) PATH 'sms[1]',
sms1_mtag VARCHAR2 (100) PATH 'sms[1]/@m',
sms2 VARCHAR2 (100) PATH 'sms[2]',
sms2_mtag VARCHAR2 (100) PATH 'sms[2]/@m',
sms3 VARCHAR2 (100) PATH 'sms[3]',
sms3_mtag VARCHAR2 (100) PATH 'sms[3]/@m',
email1 VARCHAR2 (100) PATH 'email[1]',
email1_mtag VARCHAR2 (100) PATH 'email[1]/@m',
email2 VARCHAR2 (100) PATH 'email[2]',
email2_mtag VARCHAR2 (100) PATH 'email[2]/@m',
email3 VARCHAR2 (100) PATH 'email[3]',
email3_mtag VARCHAR2 (100) PATH 'email[3]/@m') xt;
NAME PHONE SMS EMAIL
___________ _____________ _____________ _________________________________
Martin H 1111#2222# #1212#2323 abc@gmail.com##xyz@outlook.com
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.