更新数据库错误

时间:2014-02-14 16:45:24

标签: c# database winforms sql-server-ce

我有一个表单,用于在文本框中显示所选的datagridviewrow数据。我想编辑和更新此表单中的数据,并在用户单击更新时更新并保存到数据表中。 当我点击更新时,我收到一条错误消息:
解析查询时出错。 [令牌行号= 1,令牌行偏移= 25,令牌错误=(]

private void editBTN_Click(object sender, EventArgs e)
{
    bool notEditable = true;
    if (editBTN.Text == "Update")
    {
        UpdateDataBase();
        editBTN.Text = "Edit";
        deleteBTN.Visible = true;
        notEditable = true;
    }
    else
    {
        deleteBTN.Visible = false;
        editBTN.Text = "Update";
        deleteBTN.Visible = false;
        notEditable = false;
    }
    firstTxt.ReadOnly = notEditable;
    surenameTxt.ReadOnly = notEditable;
    address1Txt.ReadOnly = notEditable;
    address2Txt.ReadOnly = notEditable;
    countyTxt.ReadOnly = notEditable;
    contactTxt.ReadOnly = notEditable;
    emailTxt.ReadOnly = notEditable;
    postTxt.ReadOnly = notEditable;

}

private void UpdateDataBase()
{
    if (MessageBox.Show("Customer information will be updated. This change cannot be undone. Are you sure you want to continue? ", "Confirm Edit", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        string constring = @"Data Source=|DataDirectory|\LWADataBase.sdf";
        string Query = "update customersTBL set ([First_Name] = '" + this.firstTxt.Text + "',surename= '" + this.surenameTxt.Text + "',[Address Line 1] = '" + this.address1Txt.Text + "',[Address Line 2] = '" + this.address2Txt.Text + "',County = '" + this.countyTxt.Text + "',[Post Code] = '" + this.postTxt.Text + "' , Email = '" + this.emailTxt.Text + "';,[Contact Number] = '" + this.contactTxt.Text + "');";
        SqlCeConnection conDataBase = new SqlCeConnection(constring);
        SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase);
        SqlCeDataReader myReader;
        try
        {
            conDataBase.Open();
            myReader = cmdDataBase.ExecuteReader();
            MessageBox.Show("Customer information has been updated", "Update Sucessful");
            while (myReader.Read())
            {

            }
            MessageBox.Show("Please exit the Customers window and re-open to update the table");
            this.Close();
            //displays a system error message if a problem is found
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题 一个是微不足道的,可以很容易地修复(在[Contact Number]之前删除分号,但还有其他隐藏的问题可能更严重。

  • 首先:记得始终关闭并处理一次性物品 (在这种情况下为连接和命令)。 using语句确保 use块所包含的对象将被正确关闭 在例外的情况下也处理
  • 第二:使用参数化查询。这避免了Sql注入和 解析问题。如果您的一个或多个输入数据包含单个数据 quote,用于构建sql命令文本的字符串连接 将导致无效命令
  • 第三:更新命令作用于表中存在的所有记录 如果您不添加WHERE条件。通常WHERE条件是 添加以识别唯一需要更新的记录 具有UNIQUE索引的字段的值或您的PRIMARY KEY的值 表。当然,你可以用更少的记录更新多个记录 限制性WHERE子句但似乎不是这种情况
  • 第四:对命令使用ExecuteNonQuery而不是ExecuteReader 更新/插入数据库(它的工作原理相同,但为什么要使用 应保留用于其他用途的方法?)

    private void UpdateDataBase(int customerID)
    {
         string constring = @"Data Source=|DataDirectory|\LWADataBase.sdf";
         string Query = @"update customersTBL set [First_Name] = @fname,
                      surename = @sur, [Address Line 1] = @addr1,
                      [Address Line 2] = @addr2, County = @county,
                      [Post Code] = @pcode, Email = @mail, [Contact Number] = @ctNo
                      WHERE customerID = @id";
         using(SqlCeConnection conDataBase = new SqlCeConnection(constring))
         using(SqlCeCommand cmdDataBase = new SqlCeCommand(Query, conDataBase))
         {
            try
            {
                conDataBase.Open();
                cndDataBase.Parameters.AddWithValue("@fname", this.firstTxt.Text);
                cndDataBase.Parameters.AddWithValue("@sur", this.surenameTxt.Text );
                cndDataBase.Parameters.AddWithValue("@addr1", this.address1Txt.Text );
                cndDataBase.Parameters.AddWithValue("@addr2", this.address2Txt.Text );
                cndDataBase.Parameters.AddWithValue("@county", this.countyTxt.Text );
                cndDataBase.Parameters.AddWithValue("@pcode", this.postTxt.Text );
                cndDataBase.Parameters.AddWithValue("@mail", this.emailTxt.Text );
                cndDataBase.Parameters.AddWithValue("@ctNo", this.contactTxt.Text );
                cndDataBase.Parameters.AddWithValue("@id", customerID );
                int rowsUpdated = cmdDataBase.ExecuteNonQuery();
                if(rowsUpdate == 0)
                    MessageBox.Show("No customer found to update");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
    

正如您所看到的,使用参数化查询更难以编写带有隐藏问题的错误sql文本,并且引用作业将传递给更好地了解如何格式化参数值的数据库代码。

您需要解决的唯一问题是如何检索customerID的值或您可以在WHERE子句中使用的其他值来唯一标识客户的记录

此时,您调用UpdateDatabase方法,该方法现在需要一个包含密钥的UserID变量来识别表中的用户

private void editBTN_Click(object sender, EventArgs e)
{
    bool notEditable = true;
    if (editBTN.Text == "Update")
    {
        // Here you need to identify uniquely your modified user
        // Usually when you load the data to edit you have this info extracted from your 
        // database table and you have saved it somewhere 
        // (of course the user should not edit in any way this value
        int UserID = ... ???? (from an hidden textbox? from a global variable, it is up to you
        UpdateDataBase( UserID );

答案 1 :(得分:0)

我认为你将Update结构与Insert混淆了。

对于您的更新,它看起来像这样:

更新customersTBL set([First_Name] ='data',surename ='',[Address Line 1] ='',[Address Line 2] ='',County ='',[Post Code] ='' ,Email ='';,[联系电话] ='');

你需要一个where子句。

更新/设置不会将更改放入()

发送电子邮件后,您有';'