Pergunta

parametrizadas consultas em .Net sempre olhar como este nos exemplos:

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

Mas eu estou correndo em uma parede de tijolos tentando fazer o seguinte:

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;

Onde

  • CategoryIDs é uma vírgula lista de números "123456789" separado (sem aspas)
  • O nome é uma string, possivelmente com aspas simples e outros personagens maus

O que é a sintaxe correta para isso?

Foi útil?

Solução

Vamos dizer que você tem seus IDs de categoria em uma matriz de inteiros e nome é uma string. O truque é criar o texto de comando para permitir que você insira todos os seus IDs de categoria como parâmetros individuais e construir o jogo nebulosa para nome. Para fazer o primeiro, usamos um circuito para a construção de uma sequência de nomes de parâmetro @ p0 através @ PN-1, onde N é o número de IDs de categoria na matriz. Em seguida, construir um parâmetro e adicioná-lo para o comando com o ID de categoria associada como o valor para cada parâmetro nomeado. Então nós usamos concatenação sobre o nome na própria consulta para permitir a pesquisa difusa no nome.

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",$"%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";

Esta é uma consulta totalmente parametrizado que deve fazer a sua feliz DBA. Eu suspeito que uma vez que estes são números inteiros, embora não seria muito de um risco de segurança apenas para construir o texto de comando diretamente com os valores, enquanto ainda parametrizar o nome. Se os seus IDs de categoria estão em uma matriz de cadeia, apenas dividir a matriz em vírgulas, converter cada para um inteiro, e armazená-lo na matriz inteiro.

Nota:. eu digo array e usá-lo no exemplo, mas deve funcionar para qualquer coleção, embora a sua iteração provavelmente será diferente

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

Outras dicas

Você precisa de "%" no valor do 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 + "%";

Esta abordagem não vai funcionar. Período.

A cláusula IN espera uma própria lista de parâmetros, então quando você vincular um parâmetro para isso, você tem a chance de passar em um valor.

Construa a sua cadeia de instrução de forma dinâmica, com a quantidade exata de espaços reservados cláusula individuais você pretende passar, e depois adicionar os parâmetros e vincular os valores a eles em um loop.

Não tenho certeza se este é o caminho certo, mas é uma maneira de eu ter feito isso no Antes

lista templist = new list

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top