简体   繁体   English

将 xml 值转换为 SQL Server 中的行,如 oracle XAMLTABLE

[英]Converting xml values to rows in SQL Server like oracle XAMLTABLE

I have a table with XML values in this format我有一个包含这种格式的 XML 值的表

id| xml_record 
--+------------
1 | xmlvalue
2 | xmlvalue

The xml value is in this format xml 值是这种格式

<record>
    <c2>date1</c2>
    <c2 m="2">date2</c2>
    <c2 m="3">date3</c2>
    <c3>number1</c3>
    <c3 m="2">number2</c3>
    <c3 m="3">number3</c3>
</record>

I need a query to generate this:我需要一个查询来生成这个:

id | pmt_pos | pmt_date | pmt_number
---+---------+----------+-----------
1  |  1      | date1    | number1
1  |  2      | date2    | number2
1  |  3      | date3    | number3

In Oracle I use the following query successfully to generate two virtual tables with the id's, dates and number and join them on the id and the position of every row:在 Oracle 中,我成功地使用以下查询生成两个带有 id、日期和数字的虚拟表,并将它们连接到 id 和每一行的位置:

SELECT t1.id
    ,t1.pmt_pos
    ,t1.pmt_date
    ,t2.pmt_number
FROM (
    SELECT t.id
        ,xt.pmt_date
        ,nvl(xt.pmt_pos, 1) pmt_pos
    FROM myTable t
        ,XMLTABLE('/row/c2' passing t.xml_record columns pmt_date VARCHAR(8) path '/', pmt_pos VARCHAR(3) path '@m') xt
    ) t1
JOIN (
    SELECT t.id
        ,xt.pmt_number
        ,nvl(xt.pmt_pos, 1) pmt_pos
    FROM myTable t
        ,XMLTABLE('/row/c34' passing t.xml_record columns pmt_number VARCHAR(50) path '/', pmt_pos VARCHAR(3) path '@m') xt
    ) t2 ON t1.id = t2.id
    AND t1.pmt_pos = t2.pmt_pos
ORDER BY t1.id

Is there an equivalent function to Oracle xmltable in SQL or another way to achieve the same results?是否有与 SQL 中的 Oracle xmltable 等效的功能或其他方式来实现相同的结果?

While there is no XMLTABLE exact equivalent, the nodes method on xml data types can achieve similar results like.虽然没有完全等效的 XMLTABLE,但 xml 数据类型的节点方法可以实现类似的结果。 For the above example it would work like this:对于上面的例子,它会像这样工作:

DECLARE @XML AS XML = '
<record>
    <c2>date1</c2>
    <c2 m="2">date2</c2>
    <c2 m="3">date3</c2>
    <c3>number1</c3>
    <c3 m="2">number2</c3>
    <c3 m="3">number3</c3>
</record>'

DECLARE @t TABLE  (ID int, XMLRECORD XML)

INSERT INTO @t values (1,@xml)

 SELECT 
 
ID
,isnull(t1.value('(@m)[1]','nvarchar(200)'),1) AS pmt_pos
,t1.query('.').value('/','nvarchar(30)') pymt_date
,t2.query('.').value('/','nvarchar(30)') pmt_number


FROM @t x
cross APPLY x.XMLRECORD.nodes('/record/c2') AS T1(t1)   
cross APPLY x.XMLRECORD.nodes('/record/c3') AS T2(t2)  

where isnull(t1.value('(@m)[1]','nvarchar(200)'),1)  = isnull(t2.value('(@m)[1]','nvarchar(200)'),1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM