2012-04-17 70 views
1

我有以下複雜的XML如何在SQL Server中使用的OpenXML()複雜個XML 2005

<Collection> 
<VOUCHER> 
     <DATE TYPE="Date">20110401</DATE> 
     <NARRATION TYPE="String">MUNNA CONVENT ROAD</NARRATION> 
     <VOUCHERTYPENAME>RETAIL</VOUCHERTYPENAME> 
     <VOUCHERNUMBER>R-2-I2-9-6-27751</VOUCHERNUMBER> 
     <ALLLEDGERENTRIES.LIST>    
      <LEDGERNAME>U.S.T. CANTEEN</LEDGERNAME> 
      <AMOUNT>-2678.9985</AMOUNT> 
     </ALLLEDGERENTRIES.LIST> 
     <ALLLEDGERENTRIES.LIST>    
      <LEDGERNAME>U.S.T. CANTEEN</LEDGERNAME> 
      <AMOUNT>-2678.9985</AMOUNT> 
     </ALLLEDGERENTRIES.LIST> 
</VOUCHER> 
<VOUCHER> 
     <DATE TYPE="Date">20110401</DATE> 
     <NARRATION TYPE="String">MUNNA CONVENT ROAD</NARRATION> 
     <VOUCHERTYPENAME>RETAIL</VOUCHERTYPENAME> 
     <VOUCHERNUMBER>R-2-I2-9-6-27751</VOUCHERNUMBER> 
     <ALLLEDGERENTRIES.LIST>    
      <LEDGERNAME>U.S.T. CANTEEN</LEDGERNAME> 
      <AMOUNT>-2678.9985</AMOUNT> 
     </ALLLEDGERENTRIES.LIST> 
     <ALLLEDGERENTRIES.LIST>    
      <LEDGERNAME>U.S.T. CANTEEN</LEDGERNAME> 
      <AMOUNT>-2678.9985</AMOUNT> 
     </ALLLEDGERENTRIES.LIST> 
</VOUCHER> 
</Collection> 

我節省憑證細節1個表,另一個表ALLLEDGERENTRIES.LIST細節。

這兩張表在VoucherID之間有聯繫。對於特定的VoucherID,應該存儲相關的x3值。在我的存儲過程中,我使用的是openxml()

件我SP的:

INSERT INTO SalesVoucher(AbsID,VoucherNumber,VoucherTypeName,Narration,VoucherDate) 
    SELECT @AID,VOUCHERNUMBER,VOUCHERTYPENAME,NARRATION,CAST(DATE AS DATETIME) 
     FROM OPENXML(@XMLHandle,'ENVELOPE/BODY/DATA/COLLECTION/VOUCHER',3) 
     WITH ( 
      VOUCHERNUMBER nVarchar(200),VOUCHERTYPENAME varchar(100),NARRATION varchar(500),DATE DATETIME 
      ) 
    SELECT @[email protected]@IDENTITY 

INSERT INTO SalesLedger(VoucherID,LedgerName,Amount) 
    SELECT @VID,LEDGERNAME,AMOUNT 
     FROM OPENXML(@XMLHandle,'ENVELOPE/BODY/DATA/COLLECTION/VOUCHER/ALLLEDGERENTRIES.LIST',3) 
     WITH(
      LEDGERNAME varchar(200),AMOUNT decimal(18,0) 
      ) 

所有值都在數據庫存儲,但SalesLedgerVoucherID列是相同的所有行(它不應該..)爲我所用@@IDENTITY它返回最後身份價值只。

請人幫助我如何存儲與voucherID使用openxml()在SQL SalesLedger表...

+0

這是否正確,兩個''子節點** **相同​​* ??如果你再次遇到完全相同的節點,你會怎麼做?你插入數據兩次? – 2012-04-17 13:26:11

回答

0

我可能會使用的SQL Server自帶XQuery能力做到這一點。首先,抓取你需要的物品,並插入這些物品。

當您來插入詳細信息時,您的「父」信息已存儲在SalesVoucher表中 - 因此請從該處獲取必要的信息。

您的代碼將是這樣的(假設你的XML數據是在一個名爲XML@input SQL變量):

-- Insert the "parent" info into SalesVoucher 
INSERT INTO dbo.SalesVoucher(VoucherNumber, VoucherTypeName, Narration, VoucherDate) 
    SELECT 
     v.value('(VOUCHERNUMBER)[1]', 'NVARCHAR(200)'), 
     v.value('(VOUCHERTYPENAME)[1]', 'VARCHAR(100)'), 
     v.value('(NARRATION)[1]', 'VARCHAR(500)'), 
     v.value('(DATE)[1]', 'DATETIME') 
    FROM 
     @input.nodes('/Collection/VOUCHER') AS Coll(V) 

這將插入您的SalesVoucher表的基本信息。

當要分析的細節,你需要做一個參考回父的VoucherNumber - 用這些信息,你可以從SalesVoucherAbsID並插入適當的值到SalesLedger

INSERT INTO @SalesLedger (VoucherID, LedgerName, Amount) 
    SELECT 
     sv.AbsID, 
     AL.LS.value('(LEDGERNAME)[1]', 'VARCHAR(200)'), 
     AL.LS.value('(AMOUNT)[1]', 'DECIMAL(18,4)') 
    FROM 
     @input.nodes('/Collection/VOUCHER') AS Coll(V) 
    INNER JOIN 
     dbo.SalesVoucher sv 
      ON sv.VoucherNumber = v.value('(VOUCHERNUMBER)[1]', 'NVARCHAR(200)') 
    CROSS APPLY 
     Coll.V.nodes('.//ALLLEDGERENTRIES.LIST') AS AL(LS) 

CROSS APPLY獲取該特定節點的詳細信息,從而將細節「連接」到上述XML中VoucherNumber的「父」信息。

作爲PS:DECIMAL(18,0)的數據類型是而不是適用於像-2678.9985這樣的值。 DECIMAL(18,0)將存儲最多18位數字,但其中0其中小數點後 - 因此該值將被存儲爲-2679。我已將其更改爲更有用的DECIMAL(18,4)數據類型 - 最多18位數字,其中4位數字在小數點後面。