0

当我在嵌入了 '%' 字符的查询中使用 LIKE 子句时,查询不会返回预期的行。但是如果我使用一个常量字符串,它会按预期工作。这只会在我使用StartsWith ( LIKE 'x%') 而不是Contains ( LIKE '%x%') 时引起问题。

我做错什么了!???

重现代码(最终查询出乎意料):

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

环境:Entity Framework 5 针对 SQL Server 2012 SP1 生成的 SQL。检查在 SQL 2000 和 2008R2 SP2 上发生了相同的行为。

4

1 回答 1

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中找到了解释。看第一句话。

于 2013-10-18T01:49:13.387 回答