9

每当我编写一个基于字符串变量(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 和“=”。再次感谢您的输入。

4

9 回答 9

13

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

于 2008-11-19T16:20:33.103 回答
8

Sunny几乎做对了:)

在 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”或“Sam”,不幸的是,列的排序规则不区分大小写。

像下面这样(添加了转义)是要走的路。

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

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

然而 ....

我认为varbinary 转换技巧不太容易出现错误并且更容易记住。

于 2008-11-20T01:11:00.537 回答
3

如果没有使用通配符,那么区别在于,“=”进行完全匹配,但 LIKE 将匹配带有尾随空格的字符串(来自 SSBO):

当您使用 LIKE 执行字符串比较时,模式字符串中的所有字符都是重要的,包括前导或尾随空格。如果查询中的比较是返回带有字符串 LIKE 'abc'(abc 后跟一个空格)的所有行,则不返回该列的值为 abc(没有空格的 abc)的行。但是,模式匹配的表达式中的尾随空格将被忽略。如果查询中的比较是返回所有带有字符串 LIKE 'abc'(abc 没有空格)的行,则返回所有以 abc 开头并且有零个或多个尾随空格的行。

于 2008-11-19T17:09:01.430 回答
2

使用LIKE关键字,您可以将字段u.username与指定的模式而不是固定的“字符串”进行匹配。

于 2008-11-19T16:18:18.350 回答
2

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

于 2008-11-19T18:54:01.483 回答
1

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

于 2008-11-19T16:22:59.883 回答
1

我遇到了同样的问题。运行类似的查询大约需要一分半钟=。当我更改=like查询时要快得多。

  • 尝试为您要比较的列创建索引。这大大加快了查询速度。
  • 尝试运行sp_updatestats。在我的情况下,这使得查询在不使用索引的情况下运行大约 6 秒=,并且几乎立即使用索引。
于 2013-12-06T15:36:35.157 回答
0

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

我还认为它用于已被 FULL TEXT CATALOGS 编目的字段以进行硬核字符串比较。

于 2008-11-20T01:13:51.280 回答
-1

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

于 2008-11-19T16:21:54.333 回答