2017-09-27 6 views
0

Edit1: "Vous ne pouvez pas paramétrer les identifiants dans sql. SET @Column = @Value ne fonctionnera pas." Donc, si je modifie le datagridview, je ne peux pas faire une itération où je dis au serveur sql quelles colonnes devraient être mises à jour? Ai-je besoin de mettre à jour tous les éléments de la rangée? Merci pour les autres conseils aussi.SqlCommand UPDATE ne met pas à jour la base de données

Je suis en train de mettre à jour ma base de données SQL Server avec ce code C#:

try 
{ 
    string parancs = "UPDATE Equipment SET @Column = @Value, Modifier = @Modifier, Modified = @Modified " + 
        "WHERE Description = @Description AND [Plane_A/C] = @Plane"; 

    SqlCommand sqlComm = new SqlCommand(parancs, connection); 
    DateTime time = DateTime.Now; 

    foreach (DataGridViewRow row in dataGridView.Rows) 
    { 
     foreach (DataGridViewCell cell in row.Cells) 
     { 
      if (cell.Value == null) 
      { 
       cell.Value = DBNull.Value; 
      } 
     } 
    } 

    sqlComm.Connection.Open(); 

    for (int i = 0; i < rowIndexes.Count; i++) 
    { 
     sqlComm.Parameters.Clear(); 
     sqlComm.Parameters.AddWithValue("@Column", dataGridView.Columns[columnIndexes[i]].HeaderText); 
     sqlComm.Parameters.AddWithValue("@Value", dataGridView.Rows[rowIndexes[i]].Cells[columnIndexes[i]].Value); 
     sqlComm.Parameters.AddWithValue("@Description", dataGridView.Rows[rowIndexes[i]].Cells["Description"].Value); 
     sqlComm.Parameters.AddWithValue("@Plane", ChoosenAC); 
     sqlComm.Parameters.AddWithValue("@Modifier", "TesztAdmin"); 
     sqlComm.Parameters.AddWithValue("@Modified", time); 

     sqlComm.ExecuteNonQuery(); 
    } 

    sqlComm.Connection.Close(); 
    MessageBox.Show("Sikeres módosítás!"); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.ToString()); 
} 

rowIndexes.Count est le nombre de lignes et columnIndexes modifiées sont leurs positions. Le code s'exécute sans exception, mais les données ne sont pas mises à jour. Dans le profileur SQL Server, j'obtiens ceci:

exec sp_executesql N'UPDATE Equipment SET @Column = @Value, Modifier = @Modifier, Modified = @Modified WHERE Description = @Description AND [Plane_A/C] = @Plane',N'@Column nvarchar(11),@Value float,@Description nvarchar(6),@Plane nvarchar(8),@Modifier nvarchar(10),@Modified datetime',@Column=N'InspectHour',@Value=800,@Description=N'Engine',@Plane=N'TEST-REP',@Modifier=N'TesztAdmin',@Modified='2017-09-27 12:44:14.773' 

Donc tous les paramètres obtiennent des valeurs. Si je copie la commande UPDATE à SSMS et utilise des valeurs exactes au lieu de paramètres, cela fonctionne très bien et se met à jour.

Lorsque j'utilise la même méthode dans le programme avec la commande INSERT au lieu de UPDATE, cela fonctionne sans problème. J'espère avoir tout noté et vous pourriez m'aider.

Tibor

+2

Vous ne pouvez pas paramétrer les identificateurs en SQL. 'SET @Column = @ Value' ne fonctionnera pas. –

+1

Quelle est l'utilisation de '@ Column'? Vous ne pouvez pas passer la colonne à mettre à jour en tant que paramètre dans la commande à coup sûr. Essayez de supprimer ce paramètre et de placer un nom de colonne spécifique dans la commande. Ensuite, voyez ça fonctionne bien. –

+0

Je pense qu'ils ont une colonne de table appelée "Colonne". la table est un sac de propriété. Il ne s'agit pas de paramétrer un identifiant de colonne. Quant à savoir pourquoi l'affectation de @Column est affichée avec @ dans la sortie du profileur, c'est une histoire différente. notez comment les affectations suivantes ne sont pas. – dlatikay

Répondre

0

Après le commentaire que je fait, je peux offrir un exemple de code amélioré:

const string parancs = 
    "UPDATE Equipment SET {column-name} = @Value, Modifier = @Modifier, Modified = @Modified " + 
    "WHERE Description = @Description AND [Plane_A/C] = @Plane"; 

DateTime time = DateTime.Now; 

foreach (DataGridViewRow row in dataGridView.Rows) 
{ 
    foreach (DataGridViewCell cell in row.Cells) 
    { 
     if (cell.Value == null) 
     { 
      cell.Value = DBNull.Value; 
     } 
    } 
} 

using (connection) 
using (var sqlComm = connection.CreateCommand()) 
{ 
    connection.Open(); 

    for (int i = 0; i < rowIndexes.Count; i++) 
    { 
     sqlComm.Parameters.Clear(); 
     sqlComm.Parameters.AddWithValue("@Value", dataGridView.Rows[rowIndexes[i]].Cells[columnIndexes[i]].Value); 
     sqlComm.Parameters.AddWithValue("@Description", dataGridView.Rows[rowIndexes[i]].Cells["Description"].Value); 
     sqlComm.Parameters.AddWithValue("@Plane", ChoosenAC); 
     sqlComm.Parameters.AddWithValue("@Modifier", "TesztAdmin"); 
     sqlComm.Parameters.AddWithValue("@Modified", time); 

     sqlComm.CommandText = parancs.Replace("{column-name}", dataGridView.Columns[columnIndexes[i]].HeaderText); 

     try 
     { 
      sqlComm.ExecuteNonQuery(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
      throw; 
     } 
    } 

    sqlComm.Connection.Close(); 
} 

MessageBox.Show("Sikeres módosítás!"); 

Notez que le bloc try/catch contient désormais une seule ligne - l'appel de la base de données. Cela pourrait produire des erreurs qui sont hors de notre contrôle.

En outre, SqlConnection et SqlCommand mettre en œuvre Disposable Pattern ils doivent être utilisés dans un bloc using, afin d'éviter memory leak.