从批量#xml将数据插入SQL SERVER表

时间:2014-12-01 07:02:50

标签: sql-server xml xpath sql-server-2008-r2 xquery

我正在尝试使用存储过程从外部xml插入数据 虽然我的SP正在运行,但它没有插入所有记录。

这是我的表

CREATE TABLE MFR
(
    MESSAGEID varchar(16) NOT NULL,
    REPORTINGTYPE varchar(max) NULL,
    SENTBY varchar(max) NULL,
    SENTTO varchar(20) NULL,
    CREATIONTIMESTAMP varchar(30) NULL,
    TRADEID VARCHAR(52) COLLATE SQL_Latin1_General_CP1_CS_AS NULL,
    PARTYIDTYPE varchar(3) NULL,
    PARTYID varchar(50) NULL,
    COUNTERPARTYIDTYPE varchar(3) NULL,
    COUNTERPARTYID varchar(50) NULL,
    FIELDNAME varchar(50) NULL,
    PARTYVALUE varchar(100) NULL,
    COUNTERPARTYVALUE varchar(100) NULL
)

我的存储过程

IF EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID('SP_ADDREC_MFR'))
    DROP PROCEDURE SP_ADDREC_MFR
GO

CREATE PROCEDURE SP_ADDREC_MFR
(
    @BR CHAR(2),@xmlString XML
)

AS
BEGIN
    SET NOCOUNT ON;
    SET CONCAT_NULL_YIELDS_NULL ON;

    DECLARE @xmlTag varchar(100)
    IF  CHARINDEX('</mismatchedFields>', CAST(@xmlString as varchar(MAX))) > 0 
        SET @xmlTag = 'mismatchedFields' 

    IF  CHARINDEX('</InterMismatchedFields>', CAST(@xmlString as varchar(MAX))) > 0 
        SET @xmlTag = 'InterMismatchedFields' 


    INSERT INTO MFR (MESSAGEID,REPORTINGTYPE,SENTBY, SENTTO, CREATIONTIMESTAMP
    , TRADEID, PARTYIDTYPE,PARTYID, COUNTERPARTYIDTYPE,COUNTERPARTYID,FIELDNAME,PARTYVALUE,COUNTERPARTYVALUE
)
    (
        SELECT   
            RTRIM(LTRIM(header.c.value('(messageId/text())[1]', 'VARCHAR(MAX)')))   AS MESSAGEID,
            RTRIM(LTRIM(header.c.value('(reportingType/text())[1]', 'VARCHAR(MAX)')))   AS REPORTINGTYPE,
            RTRIM(LTRIM(header.c.value('(sentBy/text())[1]', 'VARCHAR(MAX)')))  AS SENTBY,
            RTRIM(LTRIM(header.c.value('(sentTo/text())[1]', 'VARCHAR(MAX)')))  AS SENTTO,
            RTRIM(LTRIM(header.c.value('(creationTimestamp/text())[1]', 'DATETIME')))   AS CREATIONTIMESTAMP,
            RTRIM(LTRIM(mismatchedTrade.c.value('(trade/tradeId/text())[1]', 'VARCHAR(MAX)')))  AS TRADEID,
            RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/partyDetails/partyIdType/text())[1]', 'VARCHAR(MAX)')))    AS PARTYIDTYPE,
            RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/partyDetails/partyId/text())[1]', 'VARCHAR(MAX)')))    AS PARTYID,
            RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/counterpartyDetails/counterpartyIdType/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYIDTYPE,
            RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/counterpartyDetails/counterpartyId/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYID,
            RTRIM(LTRIM(mismatchedTrade.c.value('(mismatchedField/fieldName/text())[1]', 'VARCHAR(MAX)')))  AS FIELDNAME,
            RTRIM(LTRIM(mismatchedTrade.c.value('(mismatchedField/partyValue/text())[1]', 'VARCHAR(MAX)'))) AS PARTYVALUE,
            RTRIM(LTRIM(mismatchedTrade.c.value('(mismatchedField/counterpartyValue/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYVALUE


            FROM @xmlString.nodes('*[local-name(.)=sql:variable("@xmlTag")]/header')  header(c)
                CROSS APPLY @xmlString.nodes('*[local-name(.)=sql:variable("@xmlTag")]/mismatchedTrade') mismatchedTrade(c)

    )
    SET CONCAT_NULL_YIELDS_NULL OFF;

DECLARE @ERRNO INTEGER
DECLARE @ERRORMSG CHAR(250)

SELECT @ERRNO = @@ERROR 
IF @ERRNO <> 0 
BEGIN 
    SELECT @ERRORMSG = OBJECT_NAME(@@PROCID) + ' ' + CONVERT(VARCHAR(250), @ERRNO) 
    EXEC SP_RAISERROR 99999, @ERRORMSG 
    RETURN @ERRNO 
END
END

运行sp你可以使用以下脚本

DECLARE @return_value int

EXEC    @return_value = [dbo].SP_ADDREC_MFR
        @BR = '01',
@xmlString ='<mismatchedFields><header><messageId>D433140109000015</messageId><reportingType>MismatchedFields</reportingType><sentBy>RGTRESMMXXX</sentBy><sentTo>IN672735513</sentTo><creationTimestamp>2014-01-09T20:14:42+01:00</creationTimestamp></header><mismatchedTrade><trade><tradeId>OPTIONTESTRECON</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBRA1XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBR99XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>price</fieldName><partyValue>-32.00000</partyValue><counterpartyValue>32.00000</counterpartyValue></mismatchedField><mismatchedField><fieldName>price</fieldName><partyValue>32.00000</partyValue><counterpartyValue>-32.00000</counterpartyValue></mismatchedField></mismatchedTrade><mismatchedTrade><trade><tradeId>RECTESTOPTION</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBR99XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBRA1XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>price</fieldName><partyValue>25.00000</partyValue><counterpartyValue>-25.00000</counterpartyValue></mismatchedField><mismatchedField><fieldName>price</fieldName><partyValue>-25.00000</partyValue><counterpartyValue>25.00000</counterpartyValue></mismatchedField></mismatchedTrade><mismatchedTrade><trade><tradeId>UTIRECTEST</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBR99XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBRA1XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>currency1</fieldName><partyValue>USD</partyValue><counterpartyValue>GBP</counterpartyValue></mismatchedField><mismatchedField><fieldName>currency1</fieldName><partyValue>GBP</partyValue><counterpartyValue>USD</counterpartyValue></mismatchedField><mismatchedField><fieldName>currency2</fieldName><partyValue>USD</partyValue><counterpartyValue>GBP</counterpartyValue></mismatchedField><mismatchedField><fieldName>currency2</fieldName><partyValue>GBP</partyValue><counterpartyValue>USD</counterpartyValue></mismatchedField></mismatchedTrade><mismatchedTrade><trade><tradeId>UTIRECTEST2</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBRA1XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBR99XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField></mismatchedTrade><mismatchedTrade><trade><tradeId>UTITEST6</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBRP9XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBRM9XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField></mismatchedTrade><mismatchedTrade><trade><tradeId>UTITEST9</tradeId><counterpartyData><partyDetails><partyIdType>LEI</partyIdType><partyId>LEIBRP9XXXXXXXXXXXXX</partyId></partyDetails><counterpartyDetails><counterpartyIdType>LEI</counterpartyIdType><counterpartyId>LEIBRM9XXXXXXXXXXXXX</counterpartyId></counterpartyDetails></counterpartyData></trade><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField><mismatchedField><fieldName>counterpartySide</fieldName><partyValue>B</partyValue><counterpartyValue>B</counterpartyValue></mismatchedField></mismatchedTrade></mismatchedFields>'
SELECT  'Return Value' = @return_value

GO

上面的脚本只插入12条记录,但在xml中有18条记录。

1 个答案:

答案 0 :(得分:0)

你正在粉碎mismatchedTrade并且只有6个元素。在mismatchedField上为shred添加额外的交叉应用,并使用该派生表作为属于mismatchedField的节点值的源。

SELECT   
  RTRIM(LTRIM(header.c.value('(messageId/text())[1]', 'VARCHAR(MAX)')))   AS MESSAGEID,
  RTRIM(LTRIM(header.c.value('(reportingType/text())[1]', 'VARCHAR(MAX)')))   AS REPORTINGTYPE,
  RTRIM(LTRIM(header.c.value('(sentBy/text())[1]', 'VARCHAR(MAX)')))  AS SENTBY,
  RTRIM(LTRIM(header.c.value('(sentTo/text())[1]', 'VARCHAR(MAX)')))  AS SENTTO,
  RTRIM(LTRIM(header.c.value('(creationTimestamp/text())[1]', 'DATETIME')))   AS CREATIONTIMESTAMP,
  RTRIM(LTRIM(mismatchedTrade.c.value('(trade/tradeId/text())[1]', 'VARCHAR(MAX)')))  AS TRADEID,
  RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/partyDetails/partyIdType/text())[1]', 'VARCHAR(MAX)')))    AS PARTYIDTYPE,
  RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/partyDetails/partyId/text())[1]', 'VARCHAR(MAX)')))    AS PARTYID,
  RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/counterpartyDetails/counterpartyIdType/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYIDTYPE,
  RTRIM(LTRIM(mismatchedTrade.c.value('(trade/counterpartyData/counterpartyDetails/counterpartyId/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYID,
  RTRIM(LTRIM(mismatchedField.c.value('(fieldName/text())[1]', 'VARCHAR(MAX)')))  AS FIELDNAME,
  RTRIM(LTRIM(mismatchedField.c.value('(partyValue/text())[1]', 'VARCHAR(MAX)'))) AS PARTYVALUE,
  RTRIM(LTRIM(mismatchedField.c.value('(counterpartyValue/text())[1]', 'VARCHAR(MAX)')))  AS COUNTERPARTYVALUE
FROM @xmlString.nodes('*[local-name(.)=sql:variable("@xmlTag")]/header')  header(c)
    CROSS APPLY @xmlString.nodes('*[local-name(.)=sql:variable("@xmlTag")]/mismatchedTrade') mismatchedTrade(c)
    CROSS APPLY mismatchedTrade.c.nodes('mismatchedField') mismatchedField(c)