0

试图通过用户 ID(一个 int)将一些记录与用户匹配。但它将动态完成,我需要能够同时匹配所有记录(我为 LIKE 通配符传递了一个 '%' 字符)。我以前做过这个,不小心遇到了这个问题。

Declare 
   @uid varchar = 300

SELECT * FROM items WHERE user_id LIKE @uid

不起作用,但这确实

Declare
   @uid varchar(10) = 300

SELECT * FROM items WHERE user_id LIKE @uid

它匹配得很好,为什么没有声明 varchar 的大小时第一个版本不起作用?为什么它不抛出错误?

环境是 MSSQL SERVER 2008 R2

4

1 回答 1

1

代表以后必须维护您的代码的每个人,请不要这样做。

varchar 不起作用的原因是因为这相当于varchar(1)- 一个字符宽。话虽如此,如果您想允许检索所有内容或一个用户,请尝试以下操作:

DECLARE @Uid int
-- Get user id 300
SET @Uid = 300
-- Will match on 'User_ID = @Uid'
SELECT * FROM Items WHERE (User_ID = @Uid or @Uid is null) OPTION (RECOMPILE)
-- Get all users
SET @Uid = null
-- Will match on '@Uid is null'
SELECT * FROM Items WHERE (User_ID = @Uid or @Uid is null) OPTION (RECOMPILE)

使用LIKE要求服务器将您要过滤的每一行都转换为字符串,然后进行字符串比较,几乎是强制进行表扫描。使用=withis null将导致处理器(希望)注意到@Uid is null计算结果与true行无关。


根据 Martin Smith 的建议,我最终对其进行了更多研究,并发现MVP Erland Sommarskog 对该主题进行了更完整的讨论。长短,一定要包括OPTION (RECOMPILE),以避免次优的计划选择。该建议有一些警告,我建议您阅读这篇文章以避免被他们抓住 - 我要修复一些表现不佳的搜索 SP...

于 2013-02-22T20:11:57.597 回答