在SQL LIKE子句中使用SqlParameter不起作用


76

我有以下代码:

const string Sql = 
    @"select distinct [name] 
      from tblCustomers 
      left outer join tblCustomerInfo on tblCustomers.Id = tblCustomerInfo.CustomerId  
      where (tblCustomer.Name LIKE '%@SEARCH%' OR tblCustomerInfo.Info LIKE '%@SEARCH%');";

using (var command = new SqlCommand(Sql, Connection))
{       
    command.Parameters.AddWithValue("@SEARCH", searchString);
    ...
}

这行不通,我也尝试这样做:

const string Sql = 
    @"select distinct [name] 
     from tblCustomers 
     left outer join tblCustomerInfo on tblCustomers.Id = tblCustomerInfo.CustomerId  
     where (tblCustomer.Name LIKE @SEARCH OR tblCustomerInfo.Info LIKE @SEARCH );";

using (var command = new SqlCommand(Sql, Connection))
{       
    command.Parameters.AddWithValue("@SEARCH", "'%" + searchString + "%'");
    ...
}

但这效果不佳。怎么了?有什么建议?

Answers:


152

您想要的是:

tblCustomerInfo.Info LIKE '%' + @SEARCH + '%'

(或编辑参数值以首先包含%)。

否则,您要么(第一个示例)搜索文字“ @SEARCH”(而不是arg值),要么将一些额外的引号嵌入查询中(第二个示例)。

在某些方面,仅使用TSQLLIKE @SEARCH并在调用方处进行处理可能会更容易:

command.Parameters.AddWithValue("@SEARCH","%" + searchString + "%");

两种方法都应该起作用。


2
command.Parameters.AddWithValue(“ @ SEARCH”,“%” + searchString +“%”); 经过努力,多余的单引号就是您指出的问题
nmdr,2009年

1
第二种方法对我来说看起来更好,因为最终声明的确看起来很整洁。
Javid 2014年

12
当searchString包含字符% _或时[,这将无法正常工作,假设您想实际搜索这些字符文字之一。对于100%的解决方案,您需要将这些字符包装在searchString中的方括号中[]。C#代码Regex.Replace(searchString, @"([%_\[])", @"[$1]")可以解决问题。
马特·米勒

@MattMiller只会将searchString放在方括号中command.Parameters.AddWithValue("@SEARCH","%[" + searchString + "]%"); 而不是正则表达式不起作用吗?
Thabiso Mofokeng

1
@ThabisoMofokeng不,方括号不像引号(除非它包含单个字符)。括号在SQL LIKE中的作用是告诉它匹配其中的任何字符,因此,例如,“ a [123] z”匹配“ a1z”,“ a2z”和“ a3z”,但不匹配“ a12z”,因为括号中的表达式只匹配一个字符。我的建议是使用正则表达式将每个特殊字符包装在方括号中,这迫使LIKE从字面上匹配这些字符。
马特·米勒

7

而不是使用:

const string Sql = 
@"select distinct [name] 
  from tblCustomers 
  left outer join tblCustomerInfo on tblCustomers.Id = tblCustomerInfo.CustomerId  
  where (tblCustomer.Name LIKE '%@SEARCH%' OR tblCustomerInfo.Info LIKE '%@SEARCH%');";

使用此代码:

const string Sql = 
@"select distinct [name] 
  from tblCustomers 
  left outer join tblCustomerInfo on tblCustomers.Id = tblCustomerInfo.CustomerId  
  where (tblCustomer.Name LIKE '%' + @SEARCH + '%' OR tblCustomerInfo.Info LIKE '%' + @SEARCH + '%');";

4
这对我来说没有任何意义,但可以。你能解释为什么吗?
蒂莫西

(@需要在注释中转义)@SEARCH参数被转换为SQL varchar,然后与%chars串联,最后将其与LIKE语句进行比较。对于前\ @SEARCH的val“ Joan”,将变成:tblCustomer.Name LIKE'%'+'Joan'+'%',请注意,此处的'Joan'已完全转义,-> tblCustomer.Name LIKE'%Joan% '。如果搜索参数包含任何意外字符(%或',给定\ @SEARCH =“%Ji'm”,它们将被转义。tblCustomer.Name类似于'%'+'[%] Ji'm'+' %'。=>'%[%] Ji'm%'(%被方括号转义,单引号被加倍转义)
Noman_1

5

只需稍加注意,AddAddWithValue方法之间的细微差别即可。当我使用Add方法并放入错误的SqlType参数时,出现以下问题。

  • ncharnvarchar可以存储Unicode字符。
  • char并且无法存储Unicode字符。varchar

例如:

string query = " ... WHERE stLogin LIKE @LOGIN ";

SqlParameter p = new SqlParameter("@LOGIN", SqlDbType.Char, 255) 
{ 
    Value = "%" + login + "%" 
};

command.Parameters.AddWithValue(p.ParameterName, p.Value); //works fine!!!

command.Parameters.Add(p); // won't work

当我将SqlType更改为NVarChar时,这两种方法对我来说都可以正常工作。

SqlParameter p = new SqlParameter("@LOGIN", SqlDbType.NVarChar, 255) 
{ 
    Value = "%" + login + "%" 
};

command.Parameters.AddWithValue(p.ParameterName, p.Value); //worked fine!!!

command.Parameters.Add(p); //worked fine!!!

我认为第一个示例未按预期工作的原因是因为您指定了列类型。如果您使用带有参数名称和值的构造函数,则它应能按预期工作。查看AddWithValue的源代码,他们所做的只是调用带有参数名称和值的构造函数。所以:p = new SqlParameter(“ @ LOGIN”,“%” +登录名+“%”); command.Parameters.Add(p);
Heriberto Lugo

-7

您可以这样做,LIKE @SEARCH并在C#代码中执行

searchString = "%" + searchString + "%"

6
这不会暴露出进行sql注入的机会吗?
Ben Pretorius 2014年

2
是的,会的。或者,可能是某人将要搜索包含'字符的字符串,并且该字符串会爆炸。不要这样做。
Taran
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.