J'utilise ce code pour supprimer des enregistrements qui est sélectionné par la case à cocher dans la datagridview , mais il faut trop de temps pour exécuter la commande
private void Chkselectall_CheckedChanged(object sender, EventArgs e)
{
for(int n = 0; n< advancedDataGridView1.Rows.Count;n++)
{
advancedDataGridView1.Rows[n].Cells[0].Value = chkselectall.Checked;
}
}
4 Réponses :
Eh bien, vous exécutez un tas de commandes dans une séquence. Pour chacun d'eux, vous ouvrez une nouvelle connexion, la fermez et, aussi vite qu'elle soit, il y a toujours une surcharge. Vous feriez mieux d'obtenir une liste des identifiants à supprimer et de modifier votre commande en
delete from tabl where id in (â¦)
Non, je veux dire quelque chose comme ids = ids + "," + item.Cells [1] .Value.ToString () , et après le look, créez un SqlCommand
Vous devriez mettre les opérations SQL hors de la boucle foreach. Concattez la chaîne sql dans la boucle et exécutez-la hors de la boucle.
private void delete_Click(object sender, EventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach(DataGridViewRow item in advancedDataGridView1.Rows)
{
if(bool.Parse(item.Cells[0].Value.ToString()))
{
sb.AppendFormat("delete from tabl where id='{0}';{1}", item.Cells[1].Value, Environment.NewLine);
}
}
conn.Open();
SqlCommand cmd = new SqlCommand(sb.ToString(), conn);
cmd.ExecuteNonQuery();
conn.Close();
MessageBox.Show("Successfully Deleted....");
}
Théoriquement, passer des paramètres sql directement est assez dangereux à cause de l'injection SQL. Vous devez vous en occuper vous-même
Il est en fait plus facile d'écrire du code correct qui utilise des paramètres de commande au lieu d'analyser.
@PanagiotisKanavos comment est-ce
@AhmedAlKhteeb Nick a déjà publié une bonne réponse. Si vous avez plus de 1000 lignes à supprimer, il existe d'autres moyens
@PanagiotisKanavos oui j'ai plus de 1000 lignes
@AhmedAlKhteeb Que font 1K lignes dans une grille et comment ont-elles été sélectionnées? Les critères utilisés pour sélectionner ces 1K lignes dans la grille doivent probablement être utilisés dans la requête à la place. Dans tous les cas, je vous suggère de mettre à jour la question. Une clause IN ne peut pas contenir plus de 1K éléments. Vous pouvez utiliser un paramètre table pour transmettre les ID et utiliser un JOIN dans l'instruction DELETE , ou vous pouvez insérer les ID dans une table intermédiaire et joindre avec cela
l'utilisateur l'a sélectionné en sélectionnant tout ou un par un ou en faisant un filtre et en sélectionnant tout il existe de nombreuses façons de faire la sélection. alors à quoi devrait ressembler la mise à jour ??
Peu de choses que vous faites de manière incorrecte.
Je préfère que vous utilisiez les étapes suivantes:
Veuillez trouver l'exemple de code ci-dessous:
private void delete_Click(object sender, EventArgs e)
{
List<string> selectedIds = new List<string>();
foreach (DataGridViewRow item in advancedDataGridView1.Rows)
{
if (bool.Parse(item.Cells[0].Value.ToString()))
{
selectedIds.Add("'" + item.Cells[1].Value.ToString() + "'");
// collecting all ids
}
}
String sql = "delete from tabl where id in(@idsToDelete)";
using (SqlConnection cn = new SqlConnection("Your connection string here"))
{
cn.Open();
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@idsToDelete", SqlDbType.VarChar).Value = string.Join(",", selectedIds);
cmd.ExecuteNonQuery();
}
}
}
IN traitera le paramètre comme une valeur unique , pas comme une liste de valeurs
Veuillez ne pas préconiser l'utilisation de AddWithValue: AddWithValue is Evil ; Comment polluer votre cache de plan avec des instructions SQL paramétrées ; AddWithValue est diabolique! ...
@AndrewMorton: Ouais ..! moi aussi lu cet article, fait ces changements. Merci pour le reste
Cela ne peut toujours pas fonctionner pour le raison donnée par Panagiotis plus tôt . Vous pouvez essayer d'utiliser un paramètre table , mais je suis pas certain que cela peut être fait sans procédure stockée.
@AndrewMorton je n'utilise pas de procédure stockée car je suis nouveau dans le codage et je ne l'ai pas encore appris
@sujithkarivelil j'obtiens cette erreur (ExecuteNonQuery nécessite une connexion ouverte et disponible. L'état actuel de la connexion est fermé)
@AhmedAlKhteeb: Le message est assez clair na? oublié d'ouvrir la connexion. vérifier le code mis à jour dans ma réponse
@sujithkarivelil (La conversion a échoué lors de la conversion de la valeur varchar `` 1499840 '' en type de données int)
@sujithkarivelil où est le problème?
merci à tous pour votre aide, j'ai trouvé ce dont j'avais besoin et j'espère que cela aidera quelqu'un d'autre à avoir besoin de quelque chose comme ça
String sql;
int parameterCounter;
SqlParameter parameter;
private void delete_Click(object sender, EventArgs e)
{
sql = "delete from tabl where id in (";
parameterCounter = 0;
using (SqlConnection cn = new SqlConnection("....")) {
using (SqlCommand cmd = new SqlCommand(sql, cn)) {
foreach (DataGridViewRow item in advancedDataGridView1.Rows) {
if (bool.Parse(item.Cells[0].Value.ToString())) {
parameterCounter++;
parameter = new SqlParameter();
parameter.ParameterName = "@par" + parameterCounter.ToString();
parameter.DbType = System.Data.DbType.Int32;
parameter.Value = item.Cells[1].Value;
cmd.Parameters.Add(parameter);
sql = sql + $"{parameter.ParameterName},";
// collecting all ids
}
}
sql = sql.TrimEnd(',');
sql = sql + ")";
cmd.CommandText = sql;
cmd.Connection = cn;
cn.Open();
cmd.ExecuteNonQuery();
MessageBox.Show("Successfully Deleted....");
}
Vérifiez la requête SQL générée et utilisez le profileur dans le serveur SQL pour détecter le problème. Je pense que l'exécution des requêtes prend beaucoup de temps
À première vue, je placerais
conn.Open ()etconn.Close ()en dehors de la boucle.Votre code ressemble à un excellent endroit pour jouer avec l'injection SQL ... Google un peu pour "Paramètres ADO.NET"
première chose, essayez d'exécuter la même requête dans le studio de gestion et voyez si cela prend autant de temps. si oui, alors vous devriez regarder dans votre schéma de table / indexes.profiling et vérifier le plan d'exécution aiderait à identifier les goulots d'étranglement. De plus, placer une requête simple dans le code n'est pas sûr et pose également un problème de maintenabilité.
Oui, votre code pose des questions sur l'injection SQL, moyen d'éviter: stackoverflow.com/questions/14376473/...
Veuillez ne pas écrire de code comme celui-ci:
new SqlCommand ("delete from tabl where id = '" + item.Cells [1] .Value.ToString () + "'", conn);< b> Paramétrez votre SQL. Propriété SqlCommand.ParametersOutre le risque évident d'injection SQL, le code ouvre une nouvelle connexion à chaque exécution. Le simple fait d'ouvrir la connexion à l'extérieur de la boucle entraînerait une amélioration significative.