使用Cross apply为XML Column返回多行

时间:2015-10-07 09:19:05

标签: xml sql-server-2008

我有一个表tblTransI,其中包含一个名为TransI_xmlDetails的XML类型列中的以下数据:

<DeliveryDetails>
  <Sender>
    <Name>Test Data</Name>
  </Sender>
  <Receivers>
    <Receiver id="1">
      <GiftVouchers>
        <Voucher>ABCD</Voucher>
        <Voucher>2345</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="2">
      <GiftVouchers>
        <Voucher>1234</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="3">
      <GiftVouchers>
        <Voucher>6789</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="4">
      <GiftVouchers>
        <Voucher>WXYZ</Voucher>
      </GiftVouchers>
    </Receiver>
  </Receivers>
</DeliveryDetails>

我想创建一个返回多行的查询 - 每个凭证一个,我尝试了以下查询:

SELECT c.query('data(Voucher)') AS Id
FROM tblTransI
        CROSS APPLY TransI_xmlDetails.nodes('/DeliveryDetails/Receivers/Receiver/GiftVouchers') x(c)
WHERE TransI_xmlDetails.exist('/DeliveryDetails/Receivers/Receiver/GiftVouchers/Voucher') = 1

并返回以下输出: -

ABCD 2345
1234
6789
WXYZ

但我希望输出为: -

ABCD 
2345
1234
6789
WXYZ

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:1)

尝试这样:将其粘贴到一个空的查询窗口中,并将想法转移到您的代码中:

DECLARE @xml XML=
'<DeliveryDetails>
  <Sender>
    <Name>Test Data</Name>
  </Sender>
  <Receivers>
    <Receiver id="1">
      <GiftVouchers>
        <Voucher>ABCD</Voucher>
        <Voucher>2345</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="2">
      <GiftVouchers>
        <Voucher>1234</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="3">
      <GiftVouchers>
        <Voucher>6789</Voucher>
      </GiftVouchers>
    </Receiver>
    <Receiver id="4">
      <GiftVouchers>
        <Voucher>WXYZ</Voucher>
      </GiftVouchers>
    </Receiver>
  </Receivers>
</DeliveryDetails>';
SELECT c.value('.','varchar(max)') AS Id
FROM @xml.nodes('/DeliveryDetails/Receivers/Receiver/GiftVouchers/Voucher') x(c)

编辑:

它足以让你的节点更深一层()并将SELECT更改为value()而不是query():

在没有WHERE的情况下尝试,CROSS APPLY应该隐式执行此操作。

SELECT c.value('.','varchar(max)') AS Id
FROM tblTransI
        CROSS APPLY TransI_xmlDetails.nodes('/DeliveryDetails/Receivers/Receiver/GiftVouchers/Voucher') x(c)
WHERE TransI_xmlDetails.exist('/DeliveryDetails/Receivers/Receiver/GiftVouchers/Voucher') = 1