55 votes

Les Requêtes paramétrées avec COMME et DANS des conditions

Les Requêtes paramétrées dans .Net toujours ressembler à ceci dans les exemples:

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

Mais je suis en cours d'exécution dans un mur de brique en essayant de faire ce qui suit:

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;

  • CategoryIDs est une liste séparée par des virgules des numéros de "123,456,789" (sans les guillemets)
  • Le nom est une chaîne de caractères, éventuellement avec des guillemets simples et d'autres mauvais caractères

Quelle est la bonne syntaxe pour cela?

62voto

tvanfosson Points 268301

Disons que vous avez votre id de catégorie dans un tableau d'entiers et le Nom est une chaîne de caractères. L'astuce est de créer le texte de commande pour vous permettre d'entrer votre id de catégorie comme paramètres individuels et la construction de la correspondance floue pour le nom. Pour la première, nous utilisons une boucle pour construire une séquence de noms de paramètre @p0 via @pN-1 où N est le numéro d'id de catégorie dans le tableau. Puis nous construisons un paramètre et l'ajouter à la commande avec la catégorie associée id, comme la valeur de chaque paramètre nommé. Ensuite, nous utilisons la concaténation du nom dans la requête elle-même pour permettre la recherche floue sur le nom.

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 + '%'";

C'est entièrement paramétrable requête qui devrait faire votre DBA heureux. Je soupçonne que, puisque ce sont des nombres entiers, mais il ne serait pas beaucoup d'un risque de sécurité juste pour construire le texte de la commande directement avec les valeurs, tout en continuant de le paramétrage du nom. Si votre id de catégorie sont dans un tableau de chaîne, juste diviser le tableau sur les virgules, convertir chaque nombre entier, et de le stocker dans le tableau entier.

Note: je dis de tableau et de l'utiliser dans l'exemple, mais il devrait fonctionner pour n'importe quelle collection, bien que votre version sera probablement différentes.

Idée originale de http://www.tek-tips.com/viewthread.cfm?qid=1502614&page=9

18voto

TcKs Points 13249

Vous avez besoin de "%" dans la valeur de paramètre 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 + "%";

6voto

Tomalak Points 150423

Cette approche ne fonctionnera pas. Période.

La clause prévoit une liste de paramètres, de sorte que lorsque vous liez un paramètre, vous avez la chance de passer dans l'un de valeur.

Construire votre chaîne de requête dynamiquement, avec le montant exact de l'individu DANS la clause espaces réservés que vous avez l'intention de passer, puis d'ajouter des paramètres et valeurs de liaison dans une boucle.

-2voto

B.A.Hammer Points 18

vous ne savez pas si c'est la bonne voie, mais il est un moyen que j'ai fait Avant

liste templist = new liste

comm.Les paramètres.Add("@categoryids", SqlDbType.varchar); comm.Les paramètres["@categoryids"].valeur = string.join(",",templist.toarray())

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X