2009-12-11 24 views
1

我有一个简单的XML结构:在TSQL中,什么是迭代XML数据的1 .. *子节点并检索值的最佳方法?

<Receipt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ReceiptID="0" UserID="0" UserCardID="0" PaymentMethodID="1" MerchantID="0" MerchantTaxID="MERCHANT_TAX_ID" MerchantReceiptID="MERCHANT_RECEIPT_ID" MerchantReceiptReferenceID="MERCHANT_RECEIPT_REF_ID" ReceiptTypeID="0" TransactionTypeID="2" MerchantReceiptDate="2009-12-10T18:01:14.2101141-07:00" Tax1PerCent="0" Tax2PerCent="0" Tax3PerCent="0" Tax1Total="0" Tax2Total="0" Tax3Total="0" TotalTax="5" Subtotal="100" ReceiptTotal="105" DateAdded="2009-12-10T18:01:14.2101141-07:00" MerchantStore="MERCHANT_STORE_NAME" StoreAddress1="228127 Long Street" StoreAddress2="" StoreCity="Los Angeles" StoreState="California" StoreZip="90212" StoreCountry="USA" StorePhone1="310-444-3333" StorePhone2="" StoreFax="310-333-2222" ReceiptHeader1="Test Receipt Header 1" ReceiptHeader2="Header 2" ReceiptHeader3="Header 3" ReceiptFooter1="Test Receipt Footer 1" ReceiptFooter2="Footer 2" ReceiptFooter3="Footer 3" ReceiptCreditCost="6" UserPaidForReceipt="false"> 
    <Errors /> 
    <ReceiptItem LineItemID="0" UserID="0" ReceiptID="0" MerchantItemID="111xxxTEST_ITEM_1" LineItemTypeID="1" ItemDesc1="Item 1 - Desc1: This is a test item purchased on a test receipt, line 1" ItemDesc2="Item 1 - Desc2: Item description, line 2" ItemDesc3="Item 1 - Desc3: Item description, line 3" Quantity="1" PricePerItem="50" LineItemTotal="50" DateAdded="2009-12-10T18:01:14.2101141-07:00"> 
    <Errors /> 
    <LineItemType LineItemTypeID="1" LineItemType="Purchase"> 
     <Errors /> 
    </LineItemType> 
    </ReceiptItem> 
    <ReceiptItem LineItemID="0" UserID="0" ReceiptID="0" MerchantItemID="111xxxTEST_ITEM_2" LineItemTypeID="1" ItemDesc1="Item 2 - Desc1: This is a test item purchased on a test receipt, line 1" ItemDesc2="Item 2 - Desc2: Item description, line 2" ItemDesc3="Item 2 - Desc3: Item description, line 3" Quantity="1" PricePerItem="25" LineItemTotal="25" DateAdded="2009-12-10T18:01:14.2101141-07:00"> 
    <Errors /> 
    <LineItemType LineItemTypeID="1" LineItemType="Purchase"> 
     <Errors /> 
    </LineItemType> 
    </ReceiptItem> 
. 
. 
. 

我送的序列化流到我的存储过程,我可以抓住的东西,我需要单独的值,比如身份证,等等。但是我想通过所有ReceiptItems迭代,抓取值并将它们保存到ReceiptItems表中。

有没有简单的方法来创建一个while循环来完成这个?

+0

什么版本的SQL Server?有一个xml数据类型,您可以使用value()来分解xml以将其放入临时表中。 – 2009-12-11 02:18:52

+0

SQL Server 2005.将研究此... – ElHaix 2009-12-11 05:24:37

回答

1

OMG小马 - 巨大的领先优势,这给我带来了解决方案...谢谢:

使用公共表表达式,我能够通过我需要以下数据的子节点遍历:

SET @TestData = 
'<Receipt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ReceiptID="0" UserID="0" UserCardID="0" PaymentMethodID="1" MerchantID="0" MerchantTaxID="MERCHANT_TAX_ID" MerchantReceiptID="MERCHANT_RECEIPT_ID" MerchantReceiptReferenceID="MERCHANT_RECEIPT_REF_ID" ReceiptTypeID="0" TransactionTypeID="2" MerchantReceiptDate="2009-12-10T18:01:14.2101141-07:00" Tax1PerCent="0" Tax2PerCent="0" Tax3PerCent="0" Tax1Total="0" Tax2Total="0" Tax3Total="0" TotalTax="5" Subtotal="100" ReceiptTotal="105" DateAdded="2009-12-10T18:01:14.2101141-07:00" MerchantStore="MERCHANT_STORE_NAME" StoreAddress1="228127 Long Street" StoreAddress2="" StoreCity="Los Angeles" StoreState="California" StoreZip="90212" StoreCountry="USA" StorePhone1="310-444-3333" StorePhone2="" StoreFax="310-333-2222" ReceiptHeader1="Test Receipt Header 1" ReceiptHeader2="Header 2" ReceiptHeader3="Header 3" ReceiptFooter1="Test Receipt Footer 1" ReceiptFooter2="Footer 2" ReceiptFooter3="Footer 3" ReceiptCreditCost="1" UserPaidForReceipt="false"> 
    <Errors /> 
    <ReceiptItem LineItemID="0" UserID="0" ReceiptID="0" MerchantItemID="111xxxTEST_ITEM_1" LineItemTypeID="1" ItemDesc1="Item 1 - Desc1: This is a test item purchased on a test receipt, line 1" ItemDesc2="Item 1 - Desc2: Item description, line 2" ItemDesc3="Item 1 - Desc3: Item description, line 3" Quantity="1" PricePerItem="50" LineItemTotal="50" DateAdded="2009-12-10T18:01:14.2101141-07:00"> 
    <Errors /> 
    <LineItemType LineItemTypeID="1" LineItemType="Purchase"> 
     <Errors /> 
    </LineItemType> 
    </ReceiptItem> 
    <ReceiptItem LineItemID="0" UserID="0" ReceiptID="0" MerchantItemID="111xxxTEST_ITEM_2" LineItemTypeID="1" ItemDesc1="Item 2 - Desc1: This is a test item purchased on a test receipt, line 1" ItemDesc2="Item 2 - Desc2: Item description, line 2" ItemDesc3="Item 2 - Desc3: Item description, line 3" Quantity="1" PricePerItem="25" LineItemTotal="25" DateAdded="2009-12-10T18:01:14.2101141-07:00"> 
    <Errors /> 
    <LineItemType LineItemTypeID="1" LineItemType="Purchase"> 
     <Errors /> 
    </LineItemType> 
    </ReceiptItem> 
. 
. 
. 

鉴于这些数据,我写了下面的代码来获取我所需要的所有值,没有真正具有明确的节点遍历:

-- now iterate through the receipt items and with a CTE add them to to tbl_ReceiptLineItems 
;WITH CTE_ITEMS (Receipt, MerchantItemID, LineItemTypeID, 
       ItemDesc1, ItemDesc2, ItemDec3, ItemNumber, Quantity, 
       PricePerItem, LineItemTotal, DateAdded) 
AS 
(
    -- we're only interested in the receipt line items 
    -- AS we've already retrieved the receipt top-level items 
    SELECT 
     VIRT.node.query('./*') AS Receipt, 
     [email protected] AS UserID, 
     [email protected] AS REceipt, 
     VIRT.node.value('@MerchantItemID', 'varchar(50)') AS MerchantItemID, 
     VIRT.node.value('@LineItemTypeID', 'int') AS LineItemTypeID, 
     VIRT.node.value('@ItemDesc1', 'varchar(128)') AS ItemDesc1, 
     VIRT.node.value('@ItemDesc2', 'varchar(128)') AS ItemDesc2, 
     VIRT.node.value('@ItemDesc3', 'varchar(128)') AS ItemDesc3, 
     VIRT.node.value('@ItemNumber', 'varchar(128)') AS ItemNumber, 
     VIRT.node.value('@Quantity', 'int') AS Quantity, 
     VIRT.node.value('@PricePerItem', 'decimal(18,2)') AS PricePerItem, 
     VIRT.node.value('@LineItemTotal', 'decimal(18,2)') AS LineItemTotal, 
     VIRT.node.value('@DateAdded', 'datetime') AS DateAded 
    FROM @TestData.nodes('/Receipt/ReceiptItem') AS VIRT(node) 

    UNION ALL 

    SELECT 
     VIRT.node.query('./*') AS Receipt, 
     [email protected] AS UserID, 
     [email protected] AS REceipt, 
     VIRT.node.value('@MerchantItemID', 'varchar(50)') AS MerchantItemID, 
     VIRT.node.value('@LineItemTypeID', 'int') AS LineItemTypeID, 
     VIRT.node.value('@ItemDesc1', 'varchar(128)') AS ItemDesc1, 
     VIRT.node.value('@ItemDesc2', 'varchar(128)') AS ItemDesc2, 
     VIRT.node.value('@ItemDesc3', 'varchar(128)') AS ItemDesc3, 
     VIRT.node.value('@ItemNumber', 'varchar(128)') AS ItemNumber, 
     VIRT.node.value('@Quantity', 'int') AS Quantity, 
     VIRT.node.value('@PricePerItem', 'decimal(18,2)') AS PricePerItem, 
     VIRT.node.value('@LineItemTotal', 'decimal(18,2)') AS LineItemTotal, 
     VIRT.node.value('@DateAdded', 'datetime') AS DateAded 
    FROM CTE_ITEMS CROSS APPLY Receipt.nodes('./ReceiptItem') AS VIRT(node) 
) 


SELECT @UserID AS UserID, @ReceiptID AS ReceiptID, -- Receipt, 
     MerchantItemID, LineItemTypeID, 
     ItemDesc1, ItemDesc2, ItemDec3, ItemNumber, Quantity, 
     PricePerItem, LineItemTotal, DateAdded 

FROM CTE_ITEMS 
+0

不要忘记,你可以将自己的答案标记为接受的答案。 – 2009-12-13 02:09:22

相关问题