我有以下复杂的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>
我将凭证详细信息保存在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 @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)
)
所有值都存储在DB中,但VoucherID
表中的SalesLedger
列对于所有行都是相同的(它不应该......),因为我使用了@@IDENTITY
它返回了最后一个标识只有价值。
请有人帮助我如何在voucherID
表中使用SalesLedger
在sql中存储相关的openxml()
...
答案 0 :(得分:0)
我可能会使用SQL Server的本机XQuery功能来执行此操作。首先,抓住SalesVoucher
表所需的项目并插入它们。
当您来插入详细信息时,您的“父”信息已存储在SalesVoucher
表中 - 因此请从那里获取必要的信息。
您的代码将是这样的(假设您的XML数据位于@input
类型为XML
的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
- 使用该信息,您可以从AbsID
检索SalesVoucher
并插入适当的值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位小数点后。