2010-11-10 8 views
1

hey, j'ai fait une connexion db en C# avec SQL mais il y a quelques inconvénients que je veux couvrir. par exemple. quand je mets à jour même si il n'y a pas d'enregistrement, il ne montrera pas une erreur aussi ne mettra pas à jour. Même cas avec DELETE.Vérifiez le nombre de lignes mises à jour

private void button3_Click(object sender, EventArgs e) 
{ 
    setData(); 
    bool flag = db.UpdateData("UPDATE trytb SET Name = '"+dc.Name+"' WHERE ID = '"+dc.ID+"'"); 
    if (flag) 
     MessageBox.Show("Record Updated"); 
    else 
     MessageBox.Show("Not Updated"); 
} 

public bool DeleteData(string qry) 
{ 
    try 
    { 
     conn.Open(); 
     SqlCommand cmd = new SqlCommand(qry, conn); 
     cmd.ExecuteNonQuery(); 
     flag = true; 
     conn.Close(); 
     return flag; 
    } 
    catch 
    { 
     return flag; 
    } 
} 
+0

vous comptez sur le drapeau étant faux par défaut. Cela fonctionne, mais c'est une mauvaise pratique et difficile à lire/comprendre – smirkingman

+3

A propos: utilisez des requêtes paramétrées au lieu de la concaténation de chaînes pour éviter les attaques par injection SQL. –

+2

@David - pauvres "Bobby Tables" * sera * contrarié si vous corrigez cela ... –

Répondre

3

Votre variable de drapeau est définie sur true sans condition. Vous devez le définir sur true en fonction de la valeur de retour cmd.ExecuteNonQuery(). cela vous indiquera si zéro ou plusieurs enregistrements ont été mis à jour/supprimés. Et basé sur cela, vous pouvez définir votre drapeau.

+0

merci cela a fonctionné – salman

5

ExecuteNonQuery peut renvoyer le nombre de lignes affectées; vous pouvez l'attraper et réagir en conséquence; vous généralement attendre que ce soit 1 (sauf si vous avez des déclencheurs, etc.):

Pour les instructions UPDATE, INSERT et DELETE, la valeur de retour est le nombre de lignes affectées par la commande. Lorsqu'un déclencheur existe sur une table en cours d'insertion ou de mise à jour, la valeur de retour inclut le nombre de lignes affectées par l'opération d'insertion ou de mise à jour et le nombre de lignes affectées par le ou les déclencheurs. Pour tous les autres types d'instructions, la valeur de retour est -1. Si une annulation se produit, la valeur de retour est également -1.

Pour les requêtes plus complexes, retournant une valeur liée à @@ROWCOUNT (capturé à un moment donné dans la requête) peut être utile, ainsi que ExecuteScalar. Dans certains cas, vous devrez peut-être vérifier les données manuellement pour leur existence.

0

Que diriez-vous refactorisation votre code à quelque chose comme ceci:

private buttonUpdate_Click((object sender, EventArgs e) 
{ 
    // You should use parameterized query. But for now, this example would do. 
    string sql = "UPDATE TABLE SET NAME = " + dc.Name + " WHERE ID = '" + dc.ID +"'"; 
    bool flag = UpdateRecord(sql); 

    if(flag) 
     MessageBox.Show("Record updated!"); 
    else 
     MessageBox.Show("Update failed!"); 
} 

private bool UpdateRecord(sql) 
{ 
    bool flag = false; // Presume update failed. 

    SqlConnection conn = new SqlConnection(yourConnString); 
    try 
    { 
     conn.Open(); 
     SqlCommand cmd = new SqlCommand(sql); 
     flag = (bool)cmd.ExecuteNonQuery(); 
    } 
    catch 
    { 
      // Do some error logging. 
    } 
    finally 
    { 
     // Finally block always execute, so close here your connection and return here the flag value. 
     conn.Close(); 
     return flag; // Return default value of flag, (false) 
    } 
    return flag; 
} 
Questions connexes