使用Transact-SQL查找特定的子字符串

时间:2009-06-17 18:34:42

标签: sql sql-server

我需要从表单的字符串中提取特定的子字符串:

foo=abc;bar=def;baz=ghi

例如,我如何从该字符串中获取“bar”的值?

6 个答案:

答案 0 :(得分:1)

您可以使用charindexsubstring。例如,要搜索“baz”的值:

declare @str varchar(128)
set @str = 'foo=abc;bar=def;baz=ghi'

-- Make sure @str starts and ends with a ;
set @str = ';' + @str + ';'

select substring(@str, 
    charindex(';baz=',@str) + len(';baz='),
    charindex('=',@str,charindex(';baz=',@str)) - charindex(';baz=',@str) - 1)

或者在字符串开头的“foo”值:

select substring(@str, 
    charindex(';foo=',@str) + len(';foo='),
    charindex('=',@str,charindex(';foo=',@str)) - charindex(';foo=',@str) - 1)

这是一个完成此任务的UDF(受BlackTigerX答案启发的更具可读性的版本):

create function dbo.FindValueInString(
    @search varchar(256),
    @name varchar(30))
returns varchar(30)
as
begin
    declare @name_start int
    declare @name_length int
    declare @value_start int
    declare @value_end int

    set @search = ';' + @search

    set @name_start = charindex(';' + @name + '=',@search)
    if @name_start = 0
        return NULL

    set @name_length = len(';' + @name + '=')
    set @value_start = @name_start + @name_length
    set @value_end = charindex(';', @search, @value_start)

    return substring(@search, @value_start, @value_end - @value_start)
end

正如您所看到的,这在Sql Server中并不容易:)更好地在客户端语言中执行此操作,或者对数据库进行规范化,以使子字符串位于各自的列中。

答案 1 :(得分:1)

我有一个适用于此问题的通用解决方案:

CREATE FUNCTION [dbo].[fn_StringBetween]
(
    @BaseString varchar(max),
    @StringDelim1 varchar(max),
    @StringDelim2 varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
    DECLARE @at1 int
    DECLARE @at2 int
    DECLARE @rtrn varchar(max)

    SET @at1 = CHARINDEX(@StringDelim1, @BaseString)
    IF @at1 > 0
    BEGIN
        SET @rtrn = SUBSTRING(@BaseString, @at1
         + LEN(@StringDelim1), LEN(@BaseString) - @at1)
        SET @at2 = CHARINDEX(@StringDelim2, @rtrn)
        IF @at2 > 0
            SET @rtrn = LEFT(@rtrn, @at2 - 1)
    END

    RETURN @rtrn
END

所以,如果你运行(只是用开头和结尾的';'包装原始字符串):

PRINT dbo.fn_StringBetween(';foo=abc;bar=def;baz=ghi;', ';bar=', ';')

你会得到'def'返回。

答案 2 :(得分:0)

查看PATINDEX函数。它有通配符匹配,可以帮助你..

答案 3 :(得分:0)

你可以使用这个功能

alter function FindValue(@txt varchar(200), @find varchar(200)) 
returns varchar(200)
as
begin
declare 
    @firstPos int,
    @lastPos int

select @firstPos = charindex(@find, @txt), @lastPos = charindex(';', @txt, @firstPos+5)

select @lastPos = len(@txt)+1 where @lastPos = 0

return substring(@txt, @firstPos+len(@find)+1, @lastPos-@firstPos-len(@find)-1)
end


select dbo.FindValue('foo=abc;bar=def;baz=ghi', 'bar')

更新:没有使用@find的长度

答案 4 :(得分:0)

这假设字符串将具有相同的字符串格式,只需替换'foo = abc; bar = def; baz = ghi'

的列名称
select substring('foo=abc;bar=def;baz=ghi',patindex('%bar=%','foo=abc;bar=def;baz=ghi')+4, len('foo=abc;bar=def;baz=ghi')-patindex('%;baz=%','foo=abc;bar=def;baz=ghi')-4)

答案 5 :(得分:-1)

这可以通过简单的方式实现

DECLARE  @str VARCHAR(30)

DECLARE  @start INT

SET @str='foo=abc;bar=def;baz=ghi'

SET @start=CHARINDEX('bar',@str)

PRINT SUBSTRING(@str,@start,3)