检索两个分隔符之间多次出现的字符串 SQL 服务器

Retrieve String Between Two Delimiters for Multiple Occurences SQL Server

如何从下方获取结果集 TESTING1、TESTING2

DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'

基本上我需要获取 $I10~ 和 $

之间的所有子字符串

查看内联评论以了解正在发生的事情的概述:

DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
select 
--take part of
substring( 
    --the input string
    @MyString     
    --starting from the first pre-delimiter (but add on the length of the delimeter so we exclude the delimeter itself)
    ,charindex(@pre,@MyString) + len(@pre) 
    --and ending at the first post-delimiter to appear after the first pre-delimeter
    , charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre)) - (charindex(@pre,@MyString) + len(@pre))
) 
,
--for the second result do the same as above
substring(
    @MyString
    --only now we're looking for the second pre-delimiter (aka the first after the first)
    ,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)
    --and the second post-delimiter
    ,charindex(@post,@MyString,charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre)) - (charindex(@pre,@MyString,charindex(@pre,@MyString) + len(@pre)) + len(@pre))
) 

注意:这假设前置分隔符没有出现在前置分隔符和 post 分隔符之间;如果这样做可能会造成混淆/我们需要确定所需的行为。

substring(@stringToBreakApart, @indexOfFirstCharacterInSubstring, @lengthOfResultingString) - return是原始字符串的一段。

charindex(@stringToFind, @stringToSearch, @indexOfFirstCharacterToLookAt) - returns 给定字符串中给定子字符串的第一个字符的索引。

len(@stringToAnalyze) - returns 给定字符串的字符数(长度)。

更新

根据评论,这里是如何 return 一个单独的列,它在分隔符上拆分字符串(忽略任何不在前和 post 之间的内容),然后连接结果以形成逗号分隔场.

DECLARE @MyString varchar(256) = '$I10~TESTING1$XYZ$I10~TESTING2$~$I10~TESTING3$...'
, @pre char(5) = '$I10~' --this appears before the string we want
, @post char(1) = '$' --this appears after it
, @newDelim char(1) = ','
;with cte(indx, firstCharIndex, lastCharIndex) as 
(
    select 0 
    , charindex(@pre,@MyString) + len(@pre) 
    , charindex(@post,@MyString,charindex(@pre,@MyString) + len(@pre)) 

    union all

    select indx + 1
    , charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre) 
    , charindex(@post,@MyString,charindex(@pre,@MyString, lastCharIndex + len(@post)) + len(@pre)) 
    from cte
    where charindex(@pre,@MyString, lastCharIndex + len(@post)) > 0
)
, cte2 (substr, indx ) as 
(
    select cast(substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) as nvarchar(max)) 
    , indx
    from cte 
    where indx = (select max(indx) from cte)

    union all

    select substring(@MyString, firstCharIndex, lastCharIndex - firstCharIndex) + @newDelim + cte2.substr
    , cte.indx
    from cte
    inner join cte2 on cte2.indx = cte.indx + 1 

)
select * from cte2 where indx = 0