0

I have a string that contains 9 characters, for example LON052012 (from London 23.05.2012. - day.month.year.). I want to delete all records from table in Access where all cities start with first three letters from that string and have those months and year (05.2007.).

This is the function:

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

This is how table Country looks like (CountryID, Town, TownDate):

enter image description here

It always says that the record is deleted even if it's not.

YowE3K
  • 23,852
  • 7
  • 26
  • 40
Nikola
  • 55
  • 1
  • 6

2 Answers2

0

For UPDATE, INSERT, and DELETE statements, the return value of ExecuteNonQuery is the number of rows affected by the command.

So, modify your code as:

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

Edit

The problems in the query are:

  • The parameter data type s1 , s2 which they are string , and they should be passed as integer.
  • Using * and it should be % (access use %, see my comment)

so, you have to modify the code to be:

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

I tested that code with access 2007 and 2007 Office System Driver: Data Connectivity Components and it's working fine and deleted the row.

M.Hassan
  • 10,282
  • 5
  • 65
  • 84
  • Can you check (and post) your sql statement after passing the parameters, e.g komDelete.CommandText. – M.Hassan Jun 04 '17 at 23:37
  • For OLE connection with access, use % instead of * , review https://stackoverflow.com/a/17000335/3142139 – M.Hassan Jun 04 '17 at 23:55
  • I've tried all from there, but non of them worked for me. When i delete month(TownDate) and year(TownDate) from query and just search by first three letters of city, it deletes the record from table. – Nikola Jun 05 '17 at 00:05
  • So, check, by debugging, that s1, s2 are valid numbers. Use trim to remove the extra spaces from the string. – M.Hassan Jun 05 '17 at 00:15
  • If you used the exact logic supplied by M. Hassan then it may be possible that the database is being copied to the project\bin\debug folder on each build of the project. To see if this is so, the database would be shown in the solution explorer. Select the database in solution explorer, select properties. If Copy to Output Directory is set to "Copy Always" then change it to Copy if Newer. If this is not a solution, validate you are targeting the right database. – Karen Payne Jun 05 '17 at 00:26
0

Try this:

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

you will need to add this using:

using System.Text.RegularExpressions;

I didn't get a chance to create sample project to try it myself...

CPearson
  • 113
  • 5