【问题标题】:SQL Server Substring with CharIndex used on nested XML tags用于嵌套 XML 标记的带有 CharIndex 的 SQL Server 子字符串
【发布时间】:2012-05-09 13:47:07
【问题描述】:

这是我用来从 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 工作正常。当有两个嵌套的&lt;GLJournal&gt; 标签时,问题就出现了。 xml 然后看起来像:

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

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

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

【问题讨论】:

    标签: sql-server xml stored-procedures substring


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      这是一个你可以适应的 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        • 2013-11-19
        相关资源
        最近更新 更多