Pregunta

Las consultas parametrizadas en .Net siempre se ven así en los ejemplos:

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID = @categoryid
", 
   conn);
comm.Parameters.Add("@categoryid", SqlDbType.Int);
comm.Parameters["@categoryid"].Value = CategoryID;

Pero me encuentro con una pared de ladrillos tratando de hacer lo siguiente:

SqlCommand comm = new SqlCommand(@"
   SELECT * 
   FROM   Products 
   WHERE  Category_ID IN (@categoryids) 
      OR  name LIKE '%@name%'
", 
   conn);
comm.Parameters.Add("@categoryids", SqlDbType.Int);
comm.Parameters["@categoryids"].Value = CategoryIDs;
comm.Parameters.Add("@name", SqlDbType.Int);
comm.Parameters["@name"].Value = Name;

Dónde

  • Id. de categoría es una lista de números separados por comas "123,456,789" (sin comillas)
  • Nombre es una cadena, posiblemente con comillas simples y otros caracteres incorrectos

¿Cuál es la sintaxis correcta para esto?

¿Fue útil?

Solución

Supongamos que tiene sus identificadores de categoría en una matriz entera y Nombre es una cadena. El truco consiste en crear el texto del comando para permitirle ingresar todos los identificadores de categoría como parámetros individuales y construir la coincidencia difusa para el nombre. Para hacer lo primero, usamos un bucle para construir una secuencia de nombres de parámetros @ p0 a @ pN-1 donde N es el número de identificadores de categoría en la matriz. Luego construimos un parámetro y lo agregamos al comando con el ID de categoría asociado como el valor para cada parámetro con nombre. Luego usamos concatenación en el nombre en la consulta para permitir la búsqueda difusa en el nombre.

string Name = "someone";
int[] categoryIDs = new int[] { 238, 1138, 1615, 1616, 1617,
                                1618, 1619, 1620, 1951, 1952,
                                1953, 1954, 1955, 1972, 2022 };

SqlCommand comm = conn.CreateCommand();

string[] parameters = new string[categoryIDs.Length];
for(int i=0;i<categoryIDs.Length;i++)
{
   parameters[i] = "@p"+i;
   comm.Parameters.AddWithValue(parameters[i], categoryIDs[i]);
}
comm.Parameters.AddWithValue("@name",<*>quot;%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";

Esta es una consulta completamente parametrizada que debería hacer feliz a su DBA. Sospecho que dado que estos son números enteros, aunque no sería un gran riesgo para la seguridad solo construir el texto del comando directamente con los valores, sin dejar de parametrizar el nombre. Si sus identificadores de categoría están en una matriz de cadenas, simplemente divida la matriz en comas, convierta cada una en un entero y almacénela en la matriz de enteros.

Nota: digo matriz y la uso en el ejemplo, pero debería funcionar para cualquier colección, aunque su iteración probablemente diferirá.

Idea original de http://www.tek-tips.com /viewthread.cfm?qid=1502614&page=9

Otros consejos

Necesita "% " en valor del parámetro sql.

SqlCommand comm = new SqlCommand("SELECT * FROM Products WHERE Category_ID IN (@categoryid1, @categoryid2) OR name LIKE @name", conn);
comm.Parameters.Add("@categoryid1", SqlDbType.Int);
comm.Parameters["@categoryid1"].Value = CategoryID[0];
comm.Parameters.Add("@categoryid2", SqlDbType.Int);
comm.Parameters["@categoryid2"].Value = CategoryID[1];
comm.Parameters.Add("@name", SqlDbType.Int);
comm.Parameters["@name"].Value = "%" + Name + "%";

Este enfoque no funcionará. Período.

La cláusula IN espera una lista de parámetros en sí misma, por lo que cuando se le vincula un parámetro one , tiene la posibilidad de pasar el valor one .

Cree su cadena de declaración dinámicamente, con la cantidad exacta de marcadores de posición de la cláusula IN individuales que desea pasar, y luego agregue parámetros y valores de enlace en un bucle.

no estoy seguro si esta es la forma correcta, pero es una forma en que lo he hecho en el Antes

list templist = nueva lista

comm.Parameters.Add (" @ categoryids " ;, SqlDbType.varchar); comm.Parameters [" @ categoryids "]. value = string.join (", ", templist.toarray ())

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top