带有CharIndex的SQL Server Substring用于嵌套的XML标记

时间:2012-05-09 13:47:08

标签: sql-server xml stored-procedures substring

这是我用来从xml中获取5位数的存储过程:

    CREATE PROCEDURE [dbo].[SP_KINGPRICE_InsertJournalFromPost]
    (
        @ResponseID bigint,
        @TransactionDetailID bigint
    )
    AS
    BEGIN
    DECLARE @info as varchar(max) = '', @Reference as varchar(max) = ''
    SET @info = (SELECT SUBSTRING(Response, CHARINDEX('<GlJournal>',Response) + 11,5) 
                 FROM SysproIntegration..ifmTransactionDetailResponse 
                 WHERE TransactionDetailResponseID = @ResponseID)
    SET @Reference = (SELECT DISTINCT Reference 
                      FROM GenJournalDetail 
                      WHERE Journal = CAST(@info as DECIMAL(5,0)))
    INSERT INTO ZJournalRecords
    (JournalNumber,Reference)

    VALUES (@info,@Reference)
    END

XML有这样的标记:

    <GLJournal>12345</GLJournal>

如果XML文档只有这些标签中的一个,我不用担心。 SP工作正常。当有两个嵌套的<GLJournal>标记时会出现此问题。然后xml看起来像:

    <GLJournal>
        <SomeTag/>
        <SomeTag2/>
        <GLJournal>12345</GLJournal>
    </GLJournal>

如何获取嵌套标记的5位数值? (它总是5位数) 我曾想过使用try catch,但这似乎不是一个优雅的解决方案。

编辑:
此外,部分问题是,我不知道什么时候会有一个GlJournal个标签,或者两个。

2 个答案:

答案 0 :(得分:1)

我决定计算标签的出现次数,并根据该次数确定某个位置的子串。

DECLARE @info as varchar(max) = '', @Reference as varchar(max) = '', @inputString as varchar(max), @searchString as varchar(max), @numberOfTags as int

SET @searchString = '<GlJournal>'
SET @inputString = (SELECT Response FROM SysproIntegration..ifmTransactionDetailResponse WHERE TransactionDetailResponseID = @ResponseID)
SET @numberOfTags = (LEN(@inputString) - 
                 LEN(REPLACE(@inputString, @searchString, ''))) /
                 LEN(@searchString)

IF @numberOfTags = 1 
BEGIN
SET @info = (SELECT SUBSTRING(Response, CHARINDEX('<GlJournal>',Response) + 11,5) FROM SysproIntegration..ifmTransactionDetailResponse WHERE TransactionDetailResponseID = @ResponseID)
SET @Reference = (SELECT DISTINCT Reference FROM GenJournalDetail WHERE Journal = CAST(@info as DECIMAL(5,0)))
END
ELSE
BEGIN
SET @info = (SELECT SUBSTRING(Response, CHARINDEX('<GlJournal>',Response) + 69,5) FROM SysproIntegration..ifmTransactionDetailResponse WHERE TransactionDetailResponseID = @ResponseID)
SET @Reference = (SELECT DISTINCT Reference FROM GenJournalDetail WHERE Journal = CAST(@info as DECIMAL(5,0)))
END

答案 1 :(得分:0)

这是一个你可能适应的int测试:



declare @xml xml, @tags smallint

SET @tags = 1

-- Load @xml...
--SELECT @xml = Response 
--FROM SysproIntegration..ifmTransactionDetailResponse 
--WHERE TransactionDetailResponseID = @ResponseID

-- ... or for test...
IF @tags = 1 BEGIN
    -- Test 1 GLJournal tag
    SET @xml = '12346'
END ELSE IF @tags = 2 BEGIN
    -- Test 2 GLJournal tags
    SET @xml = '
        
        
        12345
    '
END ELSE BEGIN
    -- Test no GLJournal tags 
    SET @xml = ''
END    

DECLARE @i int; SET @i = -1

-- Try one tag    
SELECT @i = ParamValues.ID.query('GLJournal').value('.','int')
FROM @xml.nodes('/') as ParamValues(ID)

IF @i = 0   
    -- Try two tags 
    SELECT @i = ParamValues.ID.query('GLJournal').value('.','int')
    FROM @xml.nodes('/GLJournal') as ParamValues(ID)     

SELECT @i    

-- INSERT INTO ZJournalRecords... other stuff