1

我有以下复杂的 XML

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

我将凭证详细信息保存在一张表中,将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 @VID=@@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)
            )

所有值都存储在数据库中,但表中的列VoucherID对于SalesLedger所有行都是相同的(它不应该......),因为我使用@@IDENTITY它只返回最后一个标识值。

请有人帮助我如何在 sqlvoucherIDSalesLedger使用表存储相关...openxml()

4

1 回答 1

0

我可能会使用 SQL Server 的本机 XQuery 功能来执行此操作。首先,抓住SalesVoucher桌子所需的物品并插入它们。

当您插入详细信息时,您的“父”信息已经存储在SalesVoucher表中 - 所以从那里获取必要的信息。

您的代码将是这样的(假设您的 XML 数据位于名为@inputtype的 SQL 变量中XML):

-- 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父级的引用 - 使用该信息,您可以检索AbsIDfromSalesVoucher并将适当的值插入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 位在小数点之后。

于 2012-04-17T13:44:30.327 回答