代码之家  ›  专栏  ›  技术社区  ›  kristof

Like与“=”用于使用SQL Server匹配字符串

  •  9
  • kristof  · 技术社区  · 16 年前

    每当我编写一个基于字符串变量(varchar、nvarchar、char)选择数据的存储过程时,我都会得到类似这样的结果:

    procedure dbo.p_get_user_by_username(
        @username      nvarchar(256)
    as
    begin
        select
            u.username
            ,u.email
            --,etc
        from
            sampleUserTable u
        where
            u.username = @username
    end
    

    换言之,为了与我的记录相匹配

    u.username = @username
    

    但有时我会遇到使用 LIK E代替 =

    u.username like(@username)
    

    你什么时候用? 难道不应该只在需要通配符匹配时使用吗?

    编辑

    谢谢你的回答。

    我认为我需要澄清的是,我真正想问的是:在某些情况下,是否更倾向于使用like代替“=”进行精确的字符串匹配。从答案中,我可以说不会有。 根据我自己的经验,即使在需要忽略大小写、前导和结尾空格的情况下,我也会在两个字符串上使用ltrim、rtrim、lower,然后使用“=”。再次感谢您的意见。

    9 回复  |  直到 7 年前
        1
  •  13
  •   Aheho    16 年前

    你说得对。除非你正在进行通配符匹配,否则使用LIKE没有任何好处。此外,在没有通配符的情况下使用它可能会导致使用低效的查询计划。

        2
  •  8
  •   Community CDub    8 年前

    桑尼几乎做对了:)

    在SQL2005的默认安装中,在QA中运行以下命令

    select * from sysobjects where name = 'sysbinobjs   '
    -- returns 1 row
    select * from sysobjects where name like 'sysbinobjs   '
    -- returns 0 rows
    

    因此,LIKE在尾随空格上不匹配,在查询计划端,两者的性能几乎相同,但“=”连接的性能要好一点。

    使用LIKE时必须记住的另一件事是正确转义字符串。

    declare @s varchar(40) 
    set @s = 'escaped[_]_%'
    
    select 1 where 'escaped[_]_%'  like @s 
    --Return nothing = BAD 
    
    set @s = '_e_s_c_a_p_e_d_[___]___%' 
    
    select 1 where 'escaped[_]_%'  like @s escape '_'
    --Returns 1 = GOOD
    

    一般来说,人们不会使用LIKE进行精确匹配,因为逃逸问题会导致各种并发症和微妙的错误,人们会忘记逃逸,这是一个痛苦的世界。

    但是。..如果你想要一个真正有效的精确匹配,LIKE可以解决这个问题。

    比如说,你想将用户名与“sam”匹配,而不想得到“sam”或“山姆”,不幸的是,该列的排序规则不区分大小写。

    以下内容(添加了转义符)是可行的方法。

    select * from sysobjects
    WHERE name = 'sysbinobjs' and name COLLATE Latin1_General_BIN LIKE 'sysbinobjs'
    

    进行双重匹配的原因是为了避免表扫描。

    然而。...

    我认为 varbinary casting trick 不易出错,更容易记住。

        3
  •  3
  •   Sunny Milenov    16 年前

    如果不使用通配符,那么不同的是,“=”进行精确匹配,但LIKE将匹配带有尾随空格的字符串(来自SSBO):

    执行字符串比较时 使用LIKE 模式串是重要的, 包括前导或尾随空格。 如果查询中的比较是 使用字符串LIKE返回所有行 abc(abc后面跟着一个字母) 空格),其中的值为 该列是abc(abc没有a 空格)不返回。然而, 尾随空格,在表达式中 与图案匹配的图案是 忽略。如果查询中的比较是 返回包含字符串的所有行 像“abc”(abc没有空格),所有 以abc开头且为零的行 或者返回更多尾随空格。

        4
  •  2
  •   bruno conde    16 年前

    随着 LIKE 您可以匹配该字段的关键字 u.username 针对指定的模式,而不是固定的“字符串”。

        5
  •  2
  •   Tom H zenazn    16 年前

    如果你在其他人的代码中看到了这一点,也许他们打算允许一个人传递一个包含模式或通配符的字符串。

        6
  •  1
  •   silverbugg    16 年前

    是的,你说得对,它应该只用于通配符匹配。它应该谨慎使用,特别是在非索引字段上的非常大的表上,因为它会大大减慢查询速度。

        7
  •  1
  •   Chad Carisch    11 年前

    我也遇到了同样的问题。使用以下命令运行类似的查询大约需要一分半钟 = 当我改变时 = like 查询速度要快得多。

    • 尝试为要比较的列创建索引。这大大加快了查询速度。
    • 试着跑步 sp_updatestats 在我的例子中,这使得查询在大约6秒内运行,使用 = 没有索引,几乎立刻就有了索引。
        8
  •  0
  •   Pure.Krome    16 年前

    LIKE用于通配符匹配,其中as=(equals)用于精确匹配。

    我还认为它用于由FULL TEXT CATALOGUES编目的字段,用于硬核字符串比较。

        9
  •  -1
  •   Kevin    16 年前

    是的,据我所知,使用like而不使用任何通配符与使用=运算符是一样的。您确定输入参数中没有通配符吗?

    推荐文章