How to use parameter with LIKE in Sql Server Compact Edition

This returns appropriate results in SQL Server 05 (also works wrapped in a SP), so it seems like the last thing you tried should have worked. But I don't have a test bed for Compact Edition, so maybe that makes a difference (I'd be curious to see if that's so, and why).

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

EDIT:

What version of SQLCE are you using? Can you tell if your parameter values are actually being passed from your code to the DB? I skimmed through this MSDN tutorial and was able to get the results you're looking for, at least from the Visual Studio Query Designer. (only difference is that I'm using VS 2008 and SQL Server Compact 3.5). See the section titled "Creating a new query"; I mocked up a table with some data and this query worked as you intend.

SELECT     JobID, PostCode, OtherValue
FROM         Job
WHERE     (PostCode LIKE @p1 + '%')

Like I said, I didn't write any code to call the query, but it worked from within the designer. In other words, "it works on my machine".


Using:

"AND JOB_POSTCODE LIKE '" + isPostCode + "%' "

...means that the string is constructed before being tacked onto the dynamic SQL. This is so that you don't have to specify the parameter in the parameter list for sp_executesql/EXEC, while this:

"AND JOB_POSTCODE LIKE @postcode + '%' "

...does. Please post more of the query.


The short answer is that you should put the wildcard in the Value of the parameter, not in the CommandText. i.e.

not that: sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode%"

this:

sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode";
sqlCommand.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = postCode + "%";

Long answer here:

I went back and stripped my code down to the essentials so that I could post it here, and while doing that I discovered that the last method I tried in my original question does actually work. Must have been something wrong in my testing. So here's a summary, with full code that's been run:

Original dynamic sql, vulnerable to sql injection:

//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");

First attempt to use parameter gives an error:

//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");

Second technique does actually work:

///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");

Thanks for all the input, and sorry about the original misleading question...


Please post your complete example (including the outer client code where you are assembling your call). Both your second and third options should work if you are passing the parameter correctly. Are you calling this in a stored procedure or inline parameterized SQL?

I assume no SPs since I just see you are using CE...

I think you need to add a length to your .Add call since it's an nvarchar.