Question

Les requêtes paramétrées dans .Net ressemblent toujours à 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 tombe sur un mur de briques 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;

  • Les identifiants de catégorie sont une liste de nombres séparés par des virgules "123 456 789". (sans guillemets)
  • Nom est une chaîne, éventuellement avec guillemets simples et autres caractères incorrects

Quelle est la bonne syntaxe pour cela?

Était-ce utile?

La solution

Supposons que vos identifiants de catégorie se trouvent dans un tableau entier et que Name est une chaîne. L'astuce consiste à créer le texte de la commande pour vous permettre de saisir tous vos identifiants de catégorie en tant que paramètres individuels et de construire la correspondance floue pour nom. Pour ce faire, nous utilisons une boucle pour construire une séquence de noms de paramètres de @ p0 à @ pN-1, où N est le nombre d'identificateurs de catégorie dans le tableau. Ensuite, nous construisons un paramètre et l’ajoutons à la commande avec la catégorie associée id comme valeur pour chaque paramètre nommé. Nous utilisons ensuite la concaténation sur le 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",<*>quot;%{Name}%");
comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN (";
comm.CommandText += string.Join(",", parameters) + ")";
comm.CommandText += " OR name LIKE @name";

Il s'agit d'une requête entièrement paramétrée qui devrait rendre votre administrateur de base de données heureux. Je suppose que puisque ce sont des entiers, il ne serait pas très risqué pour la sécurité de construire directement le texte de la commande avec les valeurs, tout en paramétrant le nom. Si vos identifiants de catégorie se trouvent dans un tableau de chaînes, divisez simplement le tableau en virgules, convertissez-les chacun en un entier et stockez-les dans le tableau d’entiers.

Remarque: je dis tableau et je l'utilise dans l'exemple, mais cela devrait fonctionner pour n'importe quelle collection, même si votre itération sera probablement différente.

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

Autres conseils

Vous avez besoin de "% " en 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 + "%";

Cette approche ne fonctionnera pas. Période.

La clause IN attend une liste de paramètres elle-même. Ainsi, lorsque vous lui associez un paramètre, vous avez la possibilité de transmettre la valeur un .

Construisez votre chaîne d'instructions de manière dynamique, en indiquant le nombre exact d'espaces réservés de clauses IN que vous souhaitez transmettre, puis ajoutez des paramètres et liez-les dans une boucle.

ne sais pas si c'est la bonne façon, mais c'est une façon que je l'ai faite dans le Avant

list templist = nouvelle liste

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top