我正在尝试将使用LIKE关键字的搜索查询与通配符进行参数化。原始的sql有这样的动态sql:
"AND JOB_POSTCODE LIKE '" + isPostCode + "%' "
所以我尝试了这个,但是我得到了一个FormatException:
"AND JOB_POSTCODE LIKE @postcode + '%' "
编辑:我想FormatException不会来自Sql Server CE,所以根据要求,这是我在C#代码中设置参数的方法。该参数在以下代码中设置:
command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode;
我也尝试过:
"AND JOB_POSTCODE LIKE @postcode"
与
command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode + "%";
但这不会返回任何结果。谁能建议如何在这个搜索sql中使用参数?
答案 0 :(得分:21)
简短的回答是你应该将通配符放在参数的值中,而不是在CommandText中。即
不是这样的:
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode%"
这样:
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode";
sqlCommand.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = postCode + "%";
这里的答案很长:
我回去把我的代码剥离到基本要素,以便我可以在这里发布,并且在这样做时我发现我在原始问题中尝试的最后一种方法确实有效。我的测试肯定有问题。所以这是一个摘要,已经运行了完整的代码:
原始动态sql,容易受到sql注入:
//Dynamic sql works, returns 2 results as expected,
//but I want to use parameters to protect against sql injection
string postCode = "G20";
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE '"
+ postCode + "%'";
return Database.fGetDataSet(sqlCommand,
iiStartRecord,
iiMaxRecords,
"JOBVISIT");
首次尝试使用参数会出错:
//This syntax with a parameter gives me an error
//(note that I've added the NVarChar length as suggested:
//System.FormatException : @postcode : G20 -
//Input string was not in a correct format.
//at System.Data.SqlServerCe.SqlCeCommand.FillParameterDataBindings()
//at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText(IntPtr& pCursor,
// Boolean& isBaseTableCursor)
string postCode = "G20";
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode
+ '%'";
sqlCommand.Parameters.Add("@postcode",
SqlDbType.NVarChar,
10).Value = postCode;
return Database.fGetDataSet(sqlCommand, iiStartRecord, iiMaxRecords, "JOBVISIT");
第二种技术确实有效:
///This syntax with a parameter works, returns 2 results as expected
string postCode = "G20";
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode";
sqlCommand.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = postCode
+ "%";
return Database.fGetDataSet(sqlCommand, iiStartRecord, iiMaxRecords, "JOBVISIT");
感谢所有的意见,并对最初的误导性问题感到抱歉......
答案 1 :(得分:3)
这会在SQL Server 05中返回适当的结果(也包含在SP中),所以看起来你尝试的最后一件事应该有效。但是我没有Compact Edition的试用版,所以也许这会产生影响(我很想知道是不是这样,以及为什么)。
declare @p1 nvarchar(50)
set @p1 = 'f' -- initial value passed from your app
set @p1 = @p1 + '%' -- edit value for use with LIKE
select * from JOB
where JOB_POSTCODE like @p1
修改强>
您使用的是什么版本的SQLCE?你能告诉你的参数值是否实际从代码传递到数据库吗?我浏览了this MSDN tutorial,并且能够获得您正在寻找的结果,至少从Visual Studio查询设计器中获取。 (唯一的区别是我使用的是VS 2008和SQL Server Compact 3.5)。请参阅标题为“创建新查询”的部分;我用一些数据模拟了一个表,这个查询按照你的意图运行。
SELECT JobID, PostCode, OtherValue
FROM Job
WHERE (PostCode LIKE @p1 + '%')
就像我说的那样,我没有编写任何代码来调用查询,但它在设计器中起作用。换句话说,“它可以在我的机器上运行”。
答案 2 :(得分:2)
使用:
"AND JOB_POSTCODE LIKE '" + isPostCode + "%' "
...表示在添加到动态SQL之前构造字符串。这样您就不必在sp_executesql / EXEC的参数列表中指定参数,而这样:
"AND JOB_POSTCODE LIKE @postcode + '%' "
...一样。请发布更多查询。
答案 3 :(得分:1)
请发布您的完整示例(包括您组装通话的外部客户端代码)。如果正确传递参数,则第二个和第三个选项都应该有效。您是在存储过程或内联参数化SQL中调用它吗?
我认为没有SP,因为我只是看到你正在使用CE ......
我认为您需要add a length to your .Add
call,因为它是nvarchar
。
答案 4 :(得分:0)
select province_address
from address
where (@postcode is null or postcode like '%' + @postcode '%')
如果你这样使用,这意味着如果你没有在@postcode 中发送任何值,它会带来所有,否则它只会带来包含@postcode
答案 5 :(得分:-1)
你的答案是:
"AND JOB_POSTCODE LIKE '' + @postcode + '%' "
和参数:
command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode;