2017-09-05 2 views
1

IDを持つDGVから行をクリックすると入力されたテキストボックスの値でレコードを更新しようとしています。私はデータベースをチェックして、フィールドは正しいが、1つまたは複数の必須パラメータに対して値が与えられていないと言っている。ここでOleDb例外:1つまたは複数の必須パラメータ更新クエリに値が指定されていません

は私のコードです:

#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 

例外スクリーンショット - https://imgur.com/6pstqOH

アプリケーションのスクリーンショット - https://imgur.com/CTGZgeG

データベースのスクリーンショット(アクセス) - https://imgur.com/UkEjxdm

私は混乱していますinsertイベントは同じことをします(テキストボックスやinseから値を取得しますそれらをrtsします)。

何か不足していますか?

私はこれが不明である場合

が助けに

感謝に感謝しようとすると、より多くの情報を提供することができます!

+0

UPDATEステートメントに_spouse_phone_のフィールドがあるとしか言えませんが、このフィールドはSELECTステートメントにはありません。 – Steve

+0

更新クエリに6つ以上のパラメータがあるのに対し、fromには6つのテキストボックスしかないことがわかります。あなたは 'updatedTextboxes'辞書にコードをデバッグし、いくつのアイテムを取得しましたか? –

+0

空の値を受け入れることができます。 – user2101411

答えて

1

さまざまなテキストボックスのvalueプロパティを渡しています。これらのテキストボックスが有効なテキストで設定されていない場合、valueプロパティはnullになります。これは.Netのヌルで、データベースのヌルと同じではありません。 db nullを渡すには、パラメータ値をDBNull.Valueに設定する必要があります。そうしないと、表示されているエラー・メッセージ、パラメータ・エラーがあります。これは、ループのためにあなたを変更避けるために:あなたはテキストボックスを持っているフィールドだけに、あなたの更新ステートメントを制限するために

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); 
    } 
} 

編集

、あなたは動的にUPDATEステートメントを構築する必要があります。これらの行に沿って何かが動作するはずです:

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) ..... 

このコードはテストしていませんのでご注意ください。さらに、それを機能させるには、TextBoxのNameの値をデータのフィールド名に変更する必要があります。これは次のようにすることができます。

var textBox = new TextBox 
{ 
    Name = qbcDataGridView.Columns[i].DataPropertyName, ... 

Key.ToString()は必要ありません。 string、stringのKeyValuePairsがあるので、Keyはすでに文字列です。

私はこれらの変更が機能するには十分だと思いますが、そうでない場合は教えてください!私は意図的に最小限の変更を維持しようとしたので、コードはあなたのものに最もよく似ています。これは、私自身がこのようにコード化することを意味するものではありません。私は巨大な量の赤いインクで初心者の仕事を汚さないように信じています!

+0

私はまだ同じエラーを受けています。 – user2101411

+0

テキストボックスには値があり、クリックするとDGVから読み込まれます。 – user2101411

+0

テキストボックスの数がパラメータの数と一致していますか?あなたのスクリーンショットはずっと少ないです。 –

関連する問題