【问题标题】:Why doesn't my LIKE statement filter when using a parameter为什么我的 LIKE 语句在使用参数时没有过滤
【发布时间】:2013-10-18 00:44:24
【问题描述】:

当我在嵌入了“%”字符的查询中使用 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 上发生了相同的行为。

【问题讨论】:

    标签: entity-framework tsql sql-like


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

    【讨论】:

    • 如果未指定,SQL Server 假定 (n)varchar 的长度为 1。
    • 你对这个假设有参考吗?
    • 声明@a nvarchar select @a = N'hello world' select @a
    • 对不起,没有参考,只是根据你的回答观察。您之前的评论很好地展示了这种行为。
    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    相关资源
    最近更新 更多