【问题标题】:How to programmatically escape wildcards in SQL LIKE?如何以编程方式在 SQL LIKE 中转义通配符?
【发布时间】:2020-02-07 06:05:59
【问题描述】:

我正在创建一个接受用于搜索表的字符串参数的存储过程。以下是与我正在做的类似的示例。

select * from Logs where IDString like @Prefix+ '[-]%'

问题是@Prefix 参数可能包含通配符,例如 % 或 _ 所以我需要转义这些。

除了使用Replace() 自己逃避它们之外,在 SQL Server 2016 中是否有标准方法可以做到这一点?

【问题讨论】:

标签: sql sql-server sql-server-2016


【解决方案1】:

需要在每个特殊字符上插入一个转义字符。正如你所说,你可以堆叠一堆REPLACE函数:

DECLARE @Prefix VARCHAR(100) = 'My%Prefix_'

DECLARE @Replaced VARCHAR(100) = REPLACE(REPLACE(REPLACE(REPLACE(@Prefix, '%', '\%'), '^', '\^'), '_', '\_'), '[', '\[')

SELECT 
    Original = @Prefix,
    Translated = @Replaced

结果:

Original    Translated
My%Prefix_  My\%Prefix\_

然后使用 LIKE 的ESCAPE 子句告诉引擎你的角色是转义指示符:

SELECT * 
FROM Logs 
WHERE IDString LIKE @Replaced + '[-]%' 
ESCAPE '\'

您还可以使用替换创建标量函数:

CREATE FUNCTION dbo.ufnEscapeLikeSpecialCharacters(@Input VARCHAR(100), @EscapeCharacter CHAR)
RETURNS VARCHAR(100)
AS
BEGIN
    RETURN REPLACE(REPLACE(REPLACE(REPLACE(@Input, '%', @EscapeCharacter + '%'), '^', @EscapeCharacter + '^'), '_', @EscapeCharacter + '_'), '[', @EscapeCharacter + '[')
END

然后像这样使用它:

DECLARE @Prefix VARCHAR(100) = 'My%Prefix_'

SELECT * 
FROM Logs 
WHERE IDString LIKE dbo.ufnEscapeLikeSpecialCharacters(@Prefix, '\') + '[-]%' 
ESCAPE '\'

【讨论】:

    【解决方案2】:

    如果你使用的是.Net,你可以通过Regex实现它

    public static string MakeSqlLikeSearchParam(string input) =>
      string.IsNullOrWhiteSpace(input) ? string.Empty : "%" + EscapeSqlWildcard(input) + "%";
    
    private static string EscapeSqlWildcard(string input) => 
      new Regex("(\\\\|%|\\[|\\]|_)").Replace(input, "\\$1");
    

    在 SQL Server 中,您可以阅读下面的链接以更好地了解

    SQL LIKE query: escape wildcards

    【讨论】:

      【解决方案3】:

      您可以在所有通配符前加上'\'

      set @Prefix = replace( 
                      replace( 
                      replace( 
                      replace( @Prefix
                      ,    '\', '\\' )
                      ,    '%', '\%' )
                      ,    '_', '\_' )
      

      然后使用以下内容来转义所有使用

      的通配符

      逃跑

      select * from Logs where IDString like @Prefix ESCAPE '\'
      

      【讨论】:

        【解决方案4】:

        据我所知,您希望获得IDstring@Prefix + @strParam 开头的值。为此,您不需要正则表达式,只需检查子字符串的索引:

        select * from Logs 
        where charindex(@Prefix + '[-]%', IDString) = 1
        

        这里是转义字符的一般方法(代码中的cmets):

        declare @str varchar(100) = 'some%string%with_special[chars',
                @escapeChar varchar(50) = '\'
        -- escape every character in string
        ;with cte as (
            select len(@str) [idx], @escapeChar + substring(@str, len(@str), 1) escapedChar
            union all
            select [idx] - 1, @escapeChar + substring(@str, [idx] - 1, 1) from cte
            where [idx] > 1
        )
        -- concatenate all escaped characters
        SELECT @str = CAST((
            SELECT [text()] = '' + escapedChar
            FROM cte
            ORDER BY idx
            FOR XML PATH(''), TYPE) AS
        VARCHAR(1000))
        -- test the string
        select 1
        where 'some%string%with_special[chars' like @str escape @escapeChar
        

        【讨论】:

        • 谢谢,但问题中的代码是一个示例,而不是我正在处理的真实代码,我的问题不是检查前缀,而是转义参数中的通配符以与 SQL Like 一起使用.
        • @stormtrooper 然后请发布有意义的示例。告诉@prefix 可以是什么。您对什么用例有疑问?
        • 我觉得没必要,问题清楚地说明了问题,代码只提供了上下文。
        • @stormtrooper 好的,然后看看另一个更通用的解决方案。
        猜你喜欢
        • 2017-06-28
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 2023-04-06
        • 2021-12-22
        • 1970-01-01
        相关资源
        最近更新 更多