使用标题和项目表从ms sql生成xml

时间:2019-03-11 10:08:05

标签: sql-server xml

我想用这样的结构从MS SQL生成xml(发票标题信息,然后是发票项目信息):

<?xml version="1.0" encoding="ISO8859-2"?>
<Data HD="1" View="InvoiceGen">
    <Row Table="InvoiceHead">
        <InvoiceNumber>630506</InvoiceNumber>
        <CustomerId>1432</CustomerId>
    </Row>
    <Row Table="InvoiceItem">
        <ItemNumber>B52</ItemNumber>
        <Price>320</Price>
        <Tax>30</Tax>
    </Row>
    <Row>
        <ItemNumber>B53</ItemNumber>
        <Price>330</Price>
        <Tax>32</Tax>
    </Row>
    <Row Table="InvoiceHead">
        <InvoiceNumber>630626</InvoiceNumber>
        <CustomerId>1556</CustomerId>
    </Row>
    <Row Table="InvoiceItem">
        <ItemNumber>B5</ItemNumber>
        <Price>500</Price>
        <Tax>55</Tax>
    </Row>
    <Row>
        <ItemNumber>B5</ItemNumber>
        <Price>200</Price>
        <Tax>20</Tax>
    </Row>
    <Row>
        <ItemNumber>B18</ItemNumber>
        <Price>180</Price>
        <Tax>16</Tax>
    </Row>
</Data>

我有一个发票总表和一个发票项目表(InvoiceNumer建立了两者之间的联系):

InvoiceHead(InvoiceNumber,CustomerId)

InvoiceItem(InvoiceNumber,ItemNumber,Price,Tax)

我已经用合并的数据创建了一个表,其结构与所需的xml中的结构相同:

InvoiceGen(InvoiceNumber,CustomerId,ItemNumber,Price,Tax)

在此表中,在标题行之后,所有行都带有与发票标题相关的项目信息。 (就像在xml中一样)

此InvoiceGen表的竞争条件是:

InvoiceNumber   CustomerId  ItemNumber  Price   Tax
630506          1432        null        null    null
630506          1432        B52         320     30
630506          1432        B53         330     32
630626          1556        null        null    null
630626          1556        B5          500     55
630626          1556        B6          200     20
630626          1556        B18         180     16

我不确定这张桌子是否能帮上忙,但这似乎是个好主意。

任何人都可以帮助我创建如上所述的xml吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

这基本上可以使您达到所需。但是请注意,'B18'之前 'B5''B6'排序,因为您的值是varchar。使用varchar时,值'1'的值比'5'低,因此'18'的值比'5'的“低”:

WITH VTE AS(
    SELECT *
    FROM (VALUES (630506,1432,NULL,NULL,NULL),
                 (630506,1432,'B52',320,30),
                 (630506,1432,'B53',330,32),
                 (630626,1556,NULL,NULL,NULL),
                 (630626,1556,'B5',500 ,55),
                 (630626,1556,'B6',200,20),
                 (630626,1556,'B18',180,16)) V(InvoiceNumber,CustomerID,ItemNumber,Price,Tax))
SELECT 1 aS [@HD],
       'InvoiceGen' AS [@View],
       (SELECT CASE WHEN ItemNumber IS NULL THEN 'InvoiceHead' ELSE 'InvoiceItem' END AS [@Table],
               CASE WHEN ItemNumber IS NULL THEN InvoiceNumber END AS InvoiceNumber,
               CASE WHEN ItemNumber IS NULL THEN CustomerID END AS CustomerID,
               ItemNumber,
               Price,
               Tax
        FROM VTE V
        ORDER BY V.InvoiceNumber,
                 V.CustomerID,
                 CASE WHEN V.ItemNumber IS NULL THEN 0 ELSE 1 END,
                 V.ItemNumber
        FOR XML PATH('Row'),TYPE)
FOR XML PATH('Data');