La respuesta corta es que debe colocar el comodín en el valor del parámetro, no en el texto del comando. es decir,
no es eso:sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode%"
esto:
sqlCommand.CommandText = "SELECT * FROM JOB WHERE JOB_POSTCODE LIKE @postcode";
sqlCommand.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = postCode + "%";
Respuesta larga aquí:
Regresé y reduje mi código a lo esencial para poder publicarlo aquí, y mientras lo hacía descubrí que el último método que probé en mi pregunta original realmente funciona. Debe haber habido algo mal en mis pruebas. Así que aquí hay un resumen, con el código completo que se ejecutó:
Sql dinámico original, vulnerable a la inyección de 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");
El primer intento de usar el parámetro arroja un 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");
La segunda técnica realmente funciona:
///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");
Gracias por todos los aportes y perdón por la pregunta engañosa original...