2017-09-05 2 views
1

Ich versuche, einen Datensatz mit den Werten in Textfeldern zu aktualisieren, die beim Klicken auf Zeile aus DGV mit der ID ausgefüllt wurden. Ich habe die Datenbank überprüft und die Felder sind korrekt, aber es sagt, dass kein Wert für einen oder mehrere erforderliche Parameter angegeben ist.OleDb-Ausnahme: kein Wert für einen oder mehrere erforderliche Parameter angegeben. Abfrage aktualisieren

Hier ist mein Code:

#region adds update control to the form 
    public void AddUpdateControl() 
    { 
     // update and delete controls 
     Button updateFieldsButton = new Button() 
     { 
      Name = "btn_updateFields", 

      Text = "Update" 
     }; 

     updateFieldsButton.Font = new Font(updateFieldsButton.Font.FontFamily, 12); 

     updateFieldsButton.Location = new Point(78, 648); 

     updateFieldsButton.Size = new Size(120, 30); 

     updateFieldsButton.Click += (sender, args) => 
     { 
      if (MessageBox.Show("Are you sure you want to update this record?", "Update", MessageBoxButtons.OKCancel) == DialogResult.OK) 
      { 
       UpdateData(this); 
      } 
     }; 

     Controls.Add(updateFieldsButton); 
    } 
    #endregion 

#region shows data grid view for update 
    public void ShowDataGridViewForUpdate() 
    { 
     qbcDataGridView.Show(); 

     qbcDataGridView.Font = new Font(qbcDataGridView.Font.FontFamily, 10); 

     qbcDataGridView.Location = new Point(80, 100); 

     qbcDataGridView.Size = new Size(1500, 500); 


     DataTable dt = new DataTable(); 


     DbAdapter = new OleDbDataAdapter("select ID, household_head AS head, birthday, phone, email, address, status, " + 
      "spouse, spouse_birthday AS sbirthday, spouse_email AS semail, anniversary, spouse_status AS sstatus, " + 
      "child1, child1_birthday AS birthday1, child1_email AS email1, " + 
      "child2, child2_birthday AS birthday2, child2_email AS email2, " + 
      "child3, child3_birthday AS birthday3, child3_email AS email3, " + 
      "child4, child4_birthday AS birthday4, child4_email AS email4, " + 
      "child5, child5_birthday AS birthday5, child5_email AS email5, " + 
      "child6, child6_birthday AS birthday6, child6_email AS email6, " + 
      "child7, child7_birthday AS birthday7, child7_email AS email7 from members", dbc); 

     DbAdapter.Fill(dt); 

     if (dt != null && dt.Rows.Count > 0) 
     { 
      if (dt.Columns.Count > 0) 
      { 
       for (int i = dt.Columns.Count - 1; i >= 0; i--) 
       { 
        if (dt.AsEnumerable().All(row => row[i] == null || row[i].ToString() == "")) 
        { 
         dt.Columns.RemoveAt(i); 
        } 
       } 

       qbcDataGridView.DataSource = dt; 


       qbcDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; 

       qbcDataGridView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; 

       qbcDataGridView.DefaultCellStyle.WrapMode = DataGridViewTriState.True; 


       Controls.Add(qbcDataGridView); 



       qbcDataGridView.RowHeaderMouseClick += (object sender, DataGridViewCellMouseEventArgs e) => 
       { 
        id = Convert.ToInt32(qbcDataGridView.Rows[e.RowIndex].Cells[0].Value.ToString()); 

        // get all the columns and assign them to textboxes text 
        for (int i = 1; i < qbcDataGridView.Rows[e.RowIndex].Cells.Count; i++) 
        { 
         // enable how many textboxes were found based on the dgv 
         var textBox = new TextBox 
         { 
          Name = qbcDataGridView.Rows[e.RowIndex].Cells[i].Value.ToString(), 

          Font = new Font(qbcDataGridView.Font.FontFamily, 12), 

          Text = qbcDataGridView.Rows[e.RowIndex].Cells[i].Value.ToString(), 

          Location = new Point(80 + (i * 140), 50) 
         }; 


         Controls.Add(textBox); 
        } 
       }; 
      } 
     } 
     else 
     { 
      HideAllControls(this); 

      MessageBox.Show("No records exist", "Records Error", MessageBoxButtons.OK); 
     } 

     dbc.Close(); 
    } 
    #endregion 


    #region updates records in the database 
    public void UpdateData(Control ctrl) 
    { 
     try 
     { 
      foreach (Control c in Controls) 
      { 
       if (c is TextBox) 
       { 
        if (!string.IsNullOrEmpty(((TextBox)c).Text)) 
        { 
         updatedTextboxes.Add(new KeyValuePair<string, string>(((TextBox)c).Name, ((TextBox)c).Text)); 
        } 
       } 
      } 

      using (dbc) 
      { 
       dbc.Open(); 

       dbCmd = new OleDbCommand("UPDATE members SET household_head = ?, birthday = ?, phone = ?, " + 
        "email = ?, address = ?, status = ?, spouse = ?, spouse_birthday = ?, " + 
        "spouse_phone = ?, spouse_email = ?, anniversary = ?, spouse_status = ?, " + 
        "child1 = ?, child1_birthday = ?, child1_email = ?, " + 
        "child2 = ?, child2_birthday = ?, child2_email = ?, " + 
        "child3 = ?, child3_birthday = ?, child3_email = ?, " + 
        "child4 = ?, child4_birthday = ?, child4_email = ?, " + 
        "child5 = ?, child5_birthday = ?, child5_email = ?, " + 
        "child6 = ?, child6_birthday = ?, child6_email = ?, " + 
        "child7 = ?, child7_birthday = ?, child7_email = ? WHERE ID = " + id, dbc); 


       for (int i = 0; i < updatedTextboxes.Count; i++) 
       { 
        dbCmd.Parameters.AddWithValue(updatedTextboxes[i].Key.ToString(), updatedTextboxes[i].Value); 
       } 

       if (dbCmd.ExecuteNonQuery() > 0) // RAWR not updating.. wrong parameter value.. check query 
       { 
        MessageBox.Show("Record updated", "QBC", MessageBoxButtons.OK); 

        ClearAll(ctrl); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 

     dbc.Close(); 
    } 
    #endregion 

Die Ausnahme Screenshot - https://imgur.com/6pstqOH

die Anwendung Screenshot - https://imgur.com/CTGZgeG

der Datenbank Screenshot (Zugang) - https://imgur.com/UkEjxdm

Ich bin verwirrt weil das insert-ereignis dasselbe tut (packt Werte aus textboxen und inse rts sie) ohne jeden Fehler.

Fehle ich etwas?

kann ich versuchen, mehr Informationen zur Verfügung stellen, wenn diese

die Hilfe

Dank Appreciate unklar ist!

+0

Ich kann nur sagen, dass Sie UPDATE-Anweisung ein Feld für _spouse_phone_ hat, während dieses Feld nicht in Ihrer SELECT-Anweisung vorhanden ist. – Steve

+0

Ich sehe, es gibt nur 6 Textfelder auf der von während die Update-Abfrage mehr als 6 Parameter hat. Haben Sie Ihren Code debuggt und überprüft, wie viele Elemente Sie im 'updatedTextboxes' Dictionary bekommen? –

+0

kann es leere Werte akzeptieren. – user2101411

Antwort

1

Sie übergeben die Value-Eigenschaft verschiedener TextBoxen. Wenn für diese TextBoxen kein gültiger Text festgelegt wurde, ist die Werteigenschaft null. Dies ist ein .Net-Nullwert, der nicht mit dem Nullwert einer Datenbank übereinstimmt. Um eine db-Null zu übergeben, müssen Sie den Parameterwert auf DBNull.Value setzen, sonst erhalten Sie genau die Fehlermeldung, die Sie sehen, einen fehlenden Parameterfehler. Um dies zu vermeiden Ihre ändern for-Schleife:

for (int i = 0; i < updatedTextboxes.Count; i++) 
{ 
    if (updatedTextboxes[i].Value == null) 
    { 
     dbCmd.Parameters.AddWithValue(updatedTextboxes[i].Key, DBNull.Value); 
    } 
    else 
    { 
     dbCmd.Parameters.AddWithValue(updatedTextboxes[i].Key, updatedTextboxes[i].Value); 
    } 
} 

bearbeiten

Um Ihre Update-Anweisung zu beschränken, um nur die Felder, für die Sie Textfelder haben, müssen Sie Ihre Update-Anweisung dynamisch erstellen. Etwas in dieser Richtung sollte funktionieren:

dbc.Open(); 
dbCmd = new OleDbCommand(); 
var sB = new StringBuilder("UPDATE members SET "); 

for (int i = 0; i < updatedTextboxes.Count; i++) 
{ 
    if (i == 0) 
    { 
     sB.Append(updatedTextboxes[i].Key + " = ?"); 
    } 
    else 
    { 
     sB.Append(", " + updatedTextboxes[i].Key + " = ?"); 
    } 
    if (updatedTextboxes[i].Value == null) 
    { 
     dbCmd.Parameters.AddWithValue(updatedTextboxes[i].Key, DBNull.Value); 
    } 
    else 
    { 
     dbCmd.Parameters.AddWithValue(updatedTextboxes[i].Key, updatedTextboxes[i].Value); 
    } 
} 

sB.Append(" WHERE ID = " + id); 
dbCmd.CommandText = sB.ToString(); 

dbCmd.Connection = dbc; 

if (dbCmd.ExecuteNonQuery() > 0) ..... 

Bitte beachten Sie, dass ich diesen Code nicht getestet habe! Außerdem müssen Sie den Wert Name Ihrer TextBoxen in den Feldnamen der Daten ändern, damit sie funktioniert. Dies können Sie folgendermaßen tun:

Beachten Sie auch, dass Sie Key.ToString() nicht benötigen. Sie haben KeyValuePairs von string, string, also ist der Key bereits eine string.

Ich denke, diese Änderungen sollten ausreichen, um es zum Laufen zu bringen, aber lassen Sie mich bitte wissen, wenn es nicht tut! Ich habe bewusst versucht, die Änderungen auf ein Minimum zu beschränken, so dass der Code Ihrer eigenen am ähnlichsten ist. Das bedeutet nicht, dass ich es selbst so schreiben würde; Ich glaube daran, die Arbeit von Anfängern nicht mit riesigen Mengen roter Tinte zu ersticken!

+0

Ich bekomme immer noch den gleichen Fehler .. – user2101411

+0

die Textfelder haben Werte, sie werden vom DGV beim Anklicken geladen. – user2101411

+0

Entspricht die Anzahl der Textfelder der Anzahl der Parameter? Dein Screenshot zeigte viel weniger. –

Verwandte Themen