2009-12-16 46 views
11

Estoy intentando parametrizar una consulta de búsqueda que use la palabra clave LIKE con un comodín. El original tiene SQL SQL dinámico como éste:Cómo usar el parámetro con LIKE en Sql Server Compact Edition

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

Así He probado este lugar, pero me da un FormatException:

"AND JOB_POSTCODE LIKE @postcode + '%' " 

Editar: supongo que la FormatException no va a venir desde Sql Server CE, según lo solicitado, así es como configuro el parámetro en mi código C#. El parámetro se establece en el código como el siguiente:

command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode; 

También probé:

"AND JOB_POSTCODE LIKE @postcode" 

con

command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode + "%"; 

pero eso no devuelve ningún resultado. ¿Alguien puede aconsejar cómo usar parámetros en esta búsqueda sql?

+0

consulta completa: @ "SELECT * FROM JOB WHERE DELETED = false AND JOB_POSTCODE LIKE '" + isPostCode +'% '" – Colin

Respuesta

21

La respuesta corta es que debe poner el comodín en el valor del parámetro, no en el texto de comando. es decir

no

que: 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í:

Volví y desnudé mi código a lo esencial para que pudiera publicar aquí, y al hacerlo descubrí que el último método que probé en mi pregunta original sí funciona. Debe haber sido algo malo en mi prueba. Así que aquí está un resumen, con el código completo que se ha ejecutado:

SQL dinámico original, vulnerable a la inyección 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"); 

primer intento de utilizar el parámetro da 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"); 

segunda técnica funciona realmente:

///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 toda la entrada, y lo de la pregunta engañosa originales ...

+1

SQLCE (o, más probablemente, el proveedor) debe tener un problema con la expresión en línea: esa podría ser la razón por la cual el proveedor arroja el error.No tengo un banco de pruebas para SQLCE y ni siquiera noté que esta era realmente una pregunta de SQL CE hasta que ya había publicado mi primera respuesta :-( –

+0

Cade, gracias por su aporte. Me ayudó a perseverar con mi código y pruebas, y me ayudó a avanzar hacia el código en lugar de la sql. – Colin

2

Usando:

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

... significa que la cadena se construye antes de ser pegado en el SQL dinámico. Esto es para que usted no tiene que especificar el parámetro en la lista de parámetros de sp_executesql/EXEC, si bien esto:

"AND JOB_POSTCODE LIKE @postcode + '%' " 

... hace. Por favor publique más de la consulta.

+1

The El sql dinámico funciona pero quiero usar un parámetro para protegerme contra la inyección de sql, y no puedo hacer que funcione – Colin

1

Por favor, publique su ejemplo completo (incluido el código del cliente externo donde está reuniendo su llamada). Tanto la segunda como la tercera opción deberían funcionar si pasas el parámetro correctamente. ¿Está llamando esto en un procedimiento almacenado o SQL parametrizado en línea?

que no asumen ninguna SP ya que acabo de ver que está utilizando CE ...

Creo que se necesita para add a length to your .Add call ya que es un nvarchar.

+0

Tienes razón, no hay SP. Está en línea con parámetros SQL. He editado la pregunta para agregar la línea donde agrego el parámetro al comando. ¿Podría ser el problema SqlDbType.NVarChar? – Colin

+0

Cade, traté de agregar longitud y encontré que no importaba, pero durante más pruebas encontré que la tercera opción estaba funcionando. Mis disculpas. Por favor, vea la respuesta que publiqué para todos los detalles. Tengo curiosidad acerca de por qué la segunda opción no funcionó ......... – Colin

3

Esto arroja los resultados adecuados en SQL Server 05 (también funciona en un SP), por lo que parece que lo último que ha intentado debería haber funcionado. Pero no tengo un banco de pruebas para Compact Edition, así que tal vez eso haga la diferencia (me gustaría saber si eso es así, y por qué).

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:

¿Qué versión de SQLCE está usando? ¿Puedes decir si los valores de tus parámetros se están pasando realmente de tu código al DB? Revisé el this MSDN tutorial y pude obtener los resultados que está buscando, al menos desde el Diseñador de consultas de Visual Studio. (La única diferencia es que estoy usando VS 2008 y SQL Server Compact 3.5). Vea la sección titulada "Creando una nueva consulta"; Me burlé de una tabla con algunos datos y esta consulta funcionó según tu intención.

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

Como he dicho, no escribí ningún código para llamar a la consulta, pero funcionó dentro del diseñador. En otras palabras, "funciona en mi máquina".

+0

Sql Server CE no permite parámetros con nombre, y la palabra clave declare no existe, por lo que no puedo usar su sql . No sé cómo asignar un parámetro sin nombre en Management Studio. Intentaba esto: ¿SELECCIONAR * DESDE EL TRABAJO DONDE EL CODIGO_POSITO TIENE GUSTO? + '%', 'G20' pero la sintaxis es incorrecta – Colin

+1

@Colin, creo que aprendí más de su comentario que de mi respuesta;) - ¿Tal vez la edición ayuda? – Matt

+0

Matt, Gracias por el enlace, ahora podré probar consultas parametrizadas fuera de mi código (he intentado hacerlo en Management Studio en lugar de Server Explorer). No creo que el error provenga de SqlServerCE, creo que proviene del proveedor de datos de .NET Compact Framework; consulte la respuesta que he publicado para el texto de error. Para el registro estoy usando VS2005 y Sql Server Compact 3.5 – Colin

-1

Su respuesta es:

"AND JOB_POSTCODE LIKE '' + @postcode + '%' " 

y el parámetro:

command.Parameters.Add("@postcode", SqlDbType.NVarChar).Value = isPostCode; 
Cuestiones relacionadas