2009-12-11 2 views
1

У меня есть простая структура XML:В TSQL, каков наилучший способ итерации через 1 .. * дочерние узлы данных XML и извлечения значений?

<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> 
. 
. 
. 

Я посылаю сериализированный поток в моем sproc, где я могу захватить отдельные значения того, что мне нужно, как идентификаторы и т.д. Однако я хочу, чтобы перебрать все ReceiptItems , захват значений и сохранение их в таблице ReceiptItems.

Есть ли простой способ создания цикла while для этого?

+0

Какой версию SQL Server? Существует тип данных xml, и вы можете использовать value() для измельчения xml, чтобы поместить его в таблицу temp. –

+0

SQL Server 2005. Посмотрите на это ... – ElHaix

ответ

1

OMG Ponies - большой свинец, которые привели меня к решению ... спасибо:

Использование общих табличных выражений, я был в состоянии перебирать дочерние узлы мне нужно для следующих данных:

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

Не забывайте, что вы можете отметить свой собственный ответ в качестве принятого ответа. –

Смежные вопросы