C# 在SQL LIKE子句中使用SqlParameter无效

C# 在SQL LIKE子句中使用SqlParameter无效,c#,sql-server,tsql,ado.net,sql-like,C#,Sql Server,Tsql,Ado.net,Sql Like,我有以下代码: 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 '%@

我有以下代码:

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 + "%'");
    ...
}
但这并不奏效。出什么事了?有什么建议吗?

您想要的是:

tblCustomerInfo.Info LIKE '%' + @SEARCH + '%'
(或编辑参数值,将%包含在第一位)

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

在某些方面,让TSQL只使用@SEARCH等
,并在调用者处处理它可能更容易:

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

这两种方法都应该有效。

你可以像@SEARCH
那样做
,在你的C#code中,做

searchString = "%" + 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%');";
使用此代码:

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 + '%');";

稍微小心一点,AddAddWithValue方法之间有一点区别。当我使用Add方法并输入错误的SqlType参数时,我遇到了以下问题

  • nchar
    nvarchar
    可以存储Unicode字符
  • char
    varchar
    无法存储Unicode字符
例如:

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!!!

command.Parameters.AddWithValue(“@SEARCH”、“%”+searchString+“%”);如果成功了,额外的单引号就是问题所在,正如您所指出的那样。第二种方法对我来说更好,因为最终语句看起来确实很整洁。当搜索字符串包含字符
%
\ucode>或
[
,假设您希望实际搜索这些字符中的一个。对于100%的解决方案,您需要将这些字符包装在括号
[]
中的searchString中。C#code
Regex.Replace(searchString,@“([%\[]),@“[$1]”)
会起作用。@MattMiller将把searchString放在方括号中
command.Parameters.AddWithValue(“@SEARCH”、“%[“+searchString+”]%”;
而不是regex not work?@thabisomofoken否,括号与引号不同(除非它包含一个字符)。类SQL中括号的作用是告诉它匹配其中的任何字符,例如'a[123]z'匹配'a1z'、'a2z'和'a3z',但不匹配'a12z',因为括号中的表达式只匹配一个字符。我建议使用正则表达式将括号中的每个特殊字符包装起来,强制LIKE逐字匹配这些字符。这不会暴露sql注入的机会吗?是的。或者,更可能的是,某人是g正在搜索包含“字符”的字符串,它将爆炸。不要这样做。这对我来说没有任何意义,但它可以工作。你能解释为什么吗?(@需要在注释中转义)@SEARCH参数被转换为SQL varchar,然后与%chars连接,最后在LIKE语句中对其进行比较,将变为:tblCustomer.Name(如“%”+“Joan”+“%”),注意此处的“Joan”已完全转义,->tblCustomer.Name(如“%Joan%”)。如果搜索参数包含任何意外字符(%or),则在给定\@search=“%Ji'm”.tblCustomer.Name(如“%”+“[%]Ji'm”+“%”的情况下,它们将被转义。=>“%[%]Ji'm%”(%通过方括号转义,单引号通过加倍转义)。使用字符串插值时,您甚至不需要转义反单引号:
var query=$“从客户处选择*,如“%”++{parameterValue}++'%'”;
我建议首先使用SQL变量在t-SQL中进行测试:
DECLARE@parameterValue VARCHAR(10)='Cust';
SELECT*FROM Customer LIKE“%”++@parameterValue++'%
我认为第一个示例没有按预期工作的原因是您指定了列类型。如果您使用采用参数名称和值的构造函数,它应该按预期工作。查看AddWithValue的源代码,它们所做的只是调用获取参数名称和值的构造函数。so:p=newsqlparameter(“@LOGIN”,“%%”+LOGIN+“%”);command.Parameters.Add(p);