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 + '%');";
稍微小心一点,Add和AddWithValue方法之间有一点区别。当我使用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#codeRegex.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);