为什么我的LIKE语句在使用参数时不会过滤

时间:2013-10-18 00:44:24

标签: entity-framework tsql sql-like

当我在具有嵌入式'%'字符的查询中使用LIKE子句时,查询不会返回预期的行。但是如果我使用常量字符串,它会按预期工作。当我使用 StartsWith LIKE 'x%')而非包含LIKE '%x%')时,这只会导致问题。

我做错了什么!??!

Repro代码(最终查询是意外的):

DECLARE @p__linq__StartsWith nvarchar 
SET @p__linq__StartsWith = N'm%'
DECLARE @p__linq__Contains nvarchar
SET @p__linq__Contains = N'%m%'

-- OK: Returns "Me" and "Not Me"
SELECT * FROM
    (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE N'%m%'

-- OK: Returns "Me"
SELECT * FROM
    (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE N'm%'


-- OK: Returns "Me" and "Not Me"
SELECT * FROM
    (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE @p__linq__Contains

-- Unexpected: Returns nothing
-- And why doesn't the last query do the same thing???
SELECT * FROM 
    (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE @p__linq__StartsWith

环境:实体框架5针对SQL Server 2012 SP1生成的SQL。检查SQL 2000和2008R2 SP2上发生的相同行为。

1 个答案:

答案 0 :(得分:1)

在代码末尾添加:

print @p__linq__StartsWith

结果解释了意外的结果。现在试试这段代码:

DECLARE @p__linq__StartsWith nvarchar(5)
SET @p__linq__StartsWith = N'm%'
DECLARE @p__linq__Contains nvarchar(5)
SET @p__linq__Contains = N'%m%'

-- OK: Returns "Me" and "Not Me"
SELECT * FROM (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE N'%m%'

-- OK: Returns "Me"
SELECT * FROM (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE N'm%'

-- OK: Returns "Me" and "Not Me"
SELECT * FROM (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE @p__linq__Contains

-- Unexpected: Returns nothing
-- And why doesn't the last query do the same thing???
SELECT * FROM  (SELECT N'Me' AS F UNION ALL SELECT N'Not Me' AS F) x
WHERE f LIKE @p__linq__StartsWith

print @p__linq__StartsWith

您只需指定nvarchar的长度即可解决此问题。

我在BOL http://technet.microsoft.com/en-us/library/ms179859.aspx找到了解释。看看第一句话。