2017-09-27 2 views
0

Edit1: "Sie können Kennungen in SQL nicht parametrisieren. SET @Column = @Value wird nicht funktionieren."SqlCommand UPDATE die Datenbank nicht aktualisieren

Also, wenn ich die Datagridview ändern, kann ich keine Iteration machen, wo ich dem SQL-Server sagen, welche Spalten aktualisiert werden sollten? Muss ich jedes Element der Zeile aktualisieren? Danke auch für die anderen Ratschläge.

Ich versuche, meine SQL Server-Datenbank mit diesem C# -Code zu aktualisieren:

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 die Anzahl der geänderten Zeilen und columnIndexes sind ihre Positionen. Der Code wird ohne Ausnahme ausgeführt, aber die Daten werden nicht aktualisiert. In SQL Server Profiler bekomme ich das:

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' 

So erhalten alle Parameter Werte. Wenn ich den Befehl UPDATE in SSMS kopiere und exakte Werte anstelle von Parametern verwende, funktioniert es einwandfrei und wird aktualisiert.

Wenn ich die gleiche Methode im Programm mit INSERT-Befehl anstelle von UPDATE verwenden, funktioniert es ohne Probleme. Ich hoffe ich habe alles aufgeschrieben und du könntest helfen.

Tibor

+2

Sie können Kennungen in SQL nicht parametrisieren. 'SET @Column = @ Value' funktioniert nicht. –

+1

Was ist die Verwendung von '@ Column'? Sie können die zu aktualisierende Spalte nicht sicher als Parameter übergeben. Versuchen Sie, diesen Parameter zu entfernen und einen bestimmten Spaltennamen in den Befehl einzufügen. Dann sehen Sie, es funktioniert gut. –

+0

Ich denke, sie haben eine Tabellenspalte namens "Column". Der Tisch ist eine Eigentumstasche. Hier geht es nicht um die Parametrisierung eines Spaltenbezeichners. Warum die Zuweisung von @Column mit @ in der Profilerausgabe angezeigt wird, ist eine andere Geschichte. Beachten Sie, wie die folgenden Zuordnungen nicht sind. – dlatikay

Antwort

0

Nach der Bemerkung, die ich gemacht, ich kann ein verbessertes Codebeispiel bieten:

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!"); 

Hinweis, dass der try/catch Block jetzt eine einzige Zeile enthält - den Datenbank-Aufruf. Es könnte Fehler erzeugen, die außerhalb unserer Kontrolle liegen.

Ferner SqlConnection und SqlCommand implementieren Disposable Pattern so müssen sie in einem using Block verwendet werden, um memory leak zu verhindern.

Verwandte Themen