在TSQL中获取动态字符串的特定部分

时间:2016-01-15 09:12:14

标签: sql sql-server sql-server-2008 tsql

样品

我的字符串如下:

AA=Item01,ZZ=Item111,ZZ=Item2,ZZ=Item3333,ZZ=Item4,ZZ=Item55

说明

AA=ZZ=是静态的,AA=的总计为1,ZZ=的计数为5。

所有Item*都是动态的,它们的长度是动态的。

我需要什么

我需要从该字符串中选择Item2。我怎样才能实现它?

我做了什么

我尝试使用RIGHTLEFTLENCHARINDEX来检测=,但无法实现它很远(语法不正确)......

注意:我知道逗号分隔的字符串是一种可怕的做法,但我无法避免它,客户提供这样的字符串。

3 个答案:

答案 0 :(得分:1)

假设您的商品值不能包含ZZ,ZZ模式(因此可以将其视为真正的分隔符),您可以使用charindex和{{ 1}}:

substring

说明:

  1. 在字符串中找到第一个declare @src nvarchar(max), @Start_Position int, @End_Position int select @src = 'AA=Item0,ZZ=Item1,ZZ=Item2,ZZ=Item3,ZZ=Item4,ZZ=Item5' select @Start_Position = charindex('ZZ', @src, charindex('ZZ', @src) + 1) + 3 select @End_Position = charindex(',ZZ', @src, @Start_Position) select substring(@src, @Start_Position, @End_Position - @Start_Position) 的出现位置:ZZ
  2. 从第一个charindex('ZZ', @src)的位置开始查找下一个ZZ的出现并添加三个字符 - 它将是ZZ开始的位置。
  3. 从上一步确定的位置开始查找Item2个字符的出现 - 它将是,ZZ结束的位置。
  4. 做子串。

答案 1 :(得分:1)

declare @src nvarchar(max)
set @src = 'AA=Item0,ZZ=Item1,ZZ=Item2,ZZ=Item3,ZZ=Item4,ZZ=Item5'
select item from [dbo].[SplitString](@src,',') where item like '%item2%'

用户定义的功能

enter image description here

GO
/****** Object:  UserDefinedFunction [dbo].[SplitString]    Script Date: 15-01-2016 18:13:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[SplitString]
(   
    @Input NVARCHAR(MAX),
    @Character CHAR(1)
)
RETURNS @Output TABLE (
    Item NVARCHAR(1000)
)
AS
BEGIN
    DECLARE @StartIndex INT, @EndIndex INT

    SET @StartIndex = 1
    IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
    BEGIN
        SET @Input = @Input + @Character
    END

    WHILE CHARINDEX(@Character, @Input) > 0
    BEGIN
        SET @EndIndex = CHARINDEX(@Character, @Input)

        INSERT INTO @Output(Item)
        SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

        SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
    END

    RETURN
END

答案 2 :(得分:1)

此功能允许您搜索不同位置的元素。 请注意,语法中只有最少的慢速字符串操作:

CREATE function [dbo].[f_find_element]
(
  @elementno int,
  @var varchar(max),
  @searchtxt varchar(20)
) RETURNS varchar(max)
as
BEGIN
SELECT @searchtxt += '=', @var = ',=' + @var + ',' +@searchtxt + '='
DECLARE @pos int = 0
;WITH N(N)AS 
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f)
SELECT top (@elementno) 
 @pos = CHARINDEX(@searchtxt, @var, @pos + 2)
FROM tally

RETURN
  STUFF(SUBSTRING(@var, @pos, 
  NULLIF(CHARINDEX(',', @var, @pos + 2), 0) - @pos), 1, LEN(@searchtxt), '')
END

以下是其使用的一些示例。

DECLARE @var varchar(max)
  ='AA=Item01,ZZ=Item111,ZZ=Item2,ZZ=Item3333,ZZ=Item4,ZZ=Item55,ZZZ=4'

SELECT element, searchtxt, [dbo].[f_find_element](element, @var, searchtxt) foundvalue
FROM 
  (values(1, 'ZZZ'),(2, 'ZZZ'),
  (2, 'ZZ'),(1, 'AA'),(2, 'AA')) x(element, searchtxt)

结果(当该元素在该位置上不存在时,为foundvalue返回NULL):

element searchtxt  foundvalue
1       ZZZ        4
2       ZZZ        NULL
2       ZZ         Item2
1       AA         Item01
2       AA         NULL