【问题标题】:Deleting specific record from Access database on button click单击按钮时从 Access 数据库中删除特定记录
【发布时间】:2017-06-04 22:57:06
【问题描述】:

我有一个包含 9 个字符的字符串,例如 LON052012(来自伦敦 23.05.2012.-day.month.year.)。我想从 Access 中的表中删除所有记录,其中所有城市都以该字符串中的前三个字母开头并具有这些月份和年份 (05.2007.)。

这是函数:

private void button2_Click(object sender, EventArgs e)
    {
        if (textBox1.Text != "")
        {
            try
            {
                string sTown, s1, s2;
                sTown = textBox1.Text.Substring(0, 3);
                s1 = textBox1.Text.Substring(3, 2);
                s2 = textBox1.Text.Substring(5);

                string sDelete = "DELETE * FROM Country WHERE Town LIKE @p1 and month(TownDate) = @p2 and year(TownDate) = @p3";
                OleDbCommand komDelete = new OleDbCommand(sDelete, connection);
                komDelete.Parameters.AddWithValue("@p1", sTown + "*");
                komDelete.Parameters.AddWithValue("@p2", s1);
                komDelete.Parameters.AddWithValue("@p3", s2);
                connection.Open();
                komDelete.ExecuteNonQuery();
                MessageBox.Show("Deleted");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                connection.Close();
            }
        }
        else
        {
            MessageBox.Show("TextBox is empty!");
        }
    }

这是表格 Country 的样子(CountryID、Town、TownDate):

它总是说记录被删除,即使没有。

【问题讨论】:

    标签: c# sql database ms-access ado.net


    【解决方案1】:

    试试这个:

            if (textBox1.Text != "")
        {
            //retrieve data
            string sTown, sMonth, sYear;
            sTown = textBox1.Text.Substring(0, 3);
            sMonth = textBox1.Text.Substring(3, 2);
            sYear = textBox1.Text.Substring(5);
    
            //validate input
            bool valid_town = new Regex(@"[a-z]", RegexOptions.IgnoreCase).IsMatch(sTown) && new Regex(@"[^0-9]").IsMatch(sTown) && sTown.Length ==3;
            bool valid_month = new Regex(@"[0][1-9]|[1][0-2]").IsMatch(sMonth) && new Regex(@"[^a-z]", RegexOptions.IgnoreCase).IsMatch(sMonth) && sMonth.Length ==2;
    
            int year = 0;
            bool isNum = int.TryParse(sYear,out year);
            bool valid_year = new Regex(@"[^a-z]", RegexOptions.IgnoreCase).IsMatch(sYear) && sYear.Length == 4 && (isNum ? year > 1980 && year < 2100 : false);
    
    
    
            string newLine = System.Environment.NewLine;
    
            //if input valid
            if (valid_town && valid_month && valid_year)
            {
                //create sql statements
                string sWhere = String.Format("WHERE Town LIKE {0} and month(TownDate) = {1] and year(TownDate) = {2}", sTown,sMonth,sYear);
                string sCount = String.Format("SELECT COUNT(*) FROM Country {0}", sWhere);
                string sDelete = String.Format("DELETE * FROM Country {0}",sWhere);
    
                //counts; to be deleted, actually deleted
                int initialCount = 0;
                int deletedCount = 0;
    
                try
                {
                    //create connection//NOTE: Using 'Use' statement will handle opening and closing. I dont know where you created your initial 'connection' object but it could cause you problems by haven a connection that is being used in multiple methods.
                    using (OleDbCommand connection = new OleDbCommand(ConnectionString))
                    {
                        //get total rows to be affected
                        connection.CommandText = sCount;
                        initialCount = connection.ExecuteNonQuery();
    
                        //delete rows and get delete count
                        connection.CommandText = sDelete;
                        deletedCount = connection.ExecuteNonQuery();
                        //display message
                        MessageBox.Show(String.Format("Found {0} rows to delete. {1}Deleted {2} rows.", initialCount, newLine, deletedCount));
    
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                finally
                {
                    connection.Close();
                }
            }
            {
                //else; input not valid
                MessageBox.Show(String.Format("Failed validation of TextBox:{0}Country:{1}{2}Month{3}{4}Year{5}.", newLine, valid_town.ToString(), newLine, valid_month.ToString(), newLine, valid_year.ToString())); ;
    
            }
        }
        else
        {
            MessageBox.Show("TextBox is empty!");
        }
    

    您需要使用以下方法添加:

    using System.Text.RegularExpressions;
    

    我没有机会创建示例项目来亲自尝试...

    【讨论】:

      【解决方案2】:

      对于 UPDATE、INSERT 和 DELETE 语句,ExecuteNonQuery 的返回值是受命令影响的行数。

      所以,修改你的代码为:

        var n= komDelete.ExecuteNonQuery();
        if (n >0 )
         {
                  MessageBox.Show("Deleted");
         }
      

      编辑

      查询中的问题是:

      • 参数数据类型 s1 , s2 它们是字符串,它们 应该作为整数传递。
      • 使用 * 应该是 %(访问使用 %,见我的评论)

      所以,你必须将代码修改为:

              var p1 = sTown + "%"; // not *
              komDelete.Parameters.AddWithValue("@p1", p1);
              var p2 = int.Parse(s1); //convert to numeric data type
              var p3 = int.Parse(s2);
              komDelete.Parameters.AddWithValue("@p2", p2);
              komDelete.Parameters.AddWithValue("@p3", p3);
      
      
            var n= komDelete.ExecuteNonQuery();
           if (n >0 )
           {
                  MessageBox.Show("Deleted");
           }
      

      我使用 access 2007 and 2007 Office System Driver: Data Connectivity Components 测试了该代码,它工作正常并删除了该行。

      【讨论】:

      • 你能否在传递参数后检查(并发布)你的sql语句,例如komDelete.CommandText。
      • 对于具有访问权限的 OLE 连接,使用 % 代替 * ,查看stackoverflow.com/a/17000335/3142139
      • 我已经从那里尝试了所有方法,但没有一个对我有用。当我从查询中删除月份(TownDate)和年份(TownDate)并仅按城市的前三个字母进行搜索时,它会从表中删除记录。
      • 因此,通过调试检查 s1、s2 是否为有效数字。使用 trim 删除字符串中多余的空格。
      • 如果您使用了 M. Hassan 提供的确切逻辑,那么数据库可能会在项目的每个构建中被复制到 project\bin\debug 文件夹。要查看是否是这样,数据库将显示在解决方案资源管理器中。在解决方案资源管理器中选择数据库,选择属性。如果“复制到输出目录”设置为“始终复制”,则将其更改为“如果更新则复制”。如果这不是解决方案,请验证您的目标是正确的数据库。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多