当我在具有嵌入式'%'字符的查询中使用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上发生的相同行为。
答案 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找到了解释。看看第一句话。