OleDb异常:没有给出一个或多个必需参数更新查询的值

时间:2017-09-05 19:29:26

标签: c# ms-access

我尝试使用带有ID的DGV行点击时填充的文本框中的值来更新记录。我已经检查了数据库并且字段是正确的,但它表示没有给出一个或多个必需参数的值。

这是我的代码:

#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事件执行相同的操作(从文本框中获取值并插入它们)而没有任何错误。

我错过了什么吗?

如果不清楚,我可以尝试提供更多信息

感谢帮助

谢谢!

1 个答案:

答案 0 :(得分:1)

您正在传递各种TextBox的value属性。如果尚未使用有效Text设置这些TextBox,则value属性将为null。这是一个.Net null,它与数据库null不同。要传递db null,您必须将参数值设置为DBNull.Value,否则您将获得您正在看到的错误消息,即缺少参数错误。为避免这种情况,请将for循环更改为:

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

编辑

为了将更新语句限制为仅具有TextBoxes的字段,您需要动态构建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) .....

请注意,我还没有测试过此代码!此外,为了使其工作,您将不得不将TextBoxes的Name值更改为数据的字段名称。你可以这样做:

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

另请注意,您不需要Key.ToString()。你有KeyValuePairs的字符串,字符串,所以Key已经是一个字符串了。

我认为这些更改应该足以使其正常工作,但如果不是,请告诉我!我故意试图将更改保持在最低限度,以便代码最接近您自己的代码。这并不意味着,我自己会这样编码;我相信不会让初学者感到窒息。使用大量的红色墨水!