I have an interface in which one of my functions include deleting a Serial Number from Access. If the Serial Number does exist then it deletes everything as it is supposed to with a confirmation message. The problem is, I can type in a Serial Number that does not exist and it acts like it is deleting it anyway. How do I check to see if the value exists when clicking the delete button, so I can then throw a notification to the user ?
private void btnDelete_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSerial.Text))
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
string deleteEntry = "delete from Inventory where SerialNumber='" + txtSerial.Text + "' ";
DialogResult result = MessageBox.Show("ARE YOU SURE YOU WANT TO DELETE SERIAL NUMBER = " + txtSerial.Text + " ? ", "LAST CHANCE !", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
if (result.Equals(DialogResult.OK))
{
command.CommandText = deleteEntry;
command.ExecuteNonQuery();
MessageBox.Show("Data Has Been Deleted".PadLeft(28));
}
if (dataGridFB.DataSource != null)
{
dataGridFB.DataSource = null;
txtSerial.Clear();
comboSerial.Text = string.Empty;
comboPart.Text = string.Empty;
comboRO.Text = string.Empty;
comboLocation.Text = string.Empty;
comboSerial.Items.Clear();
comboPart.Items.Clear();
comboRO.Items.Clear();
comboLocation.Items.Clear();
}
else
{
dataGridFB.Rows.Clear();
}
ItemsLoad();
connection.Close(); // CLOSE HERE OR YOU CANNOT ENTER RECORDS SIMULTANEOUSLY
}
catch (OleDbException ex)
{
MessageBox.Show(ex.Message);
connection.Close();
}
}
The OleDbCommand.ExecuteNonQuery returns the number of rows affected by the command. If there is no row to delete the return value will be zero. So it is easy to discover this situation
int rowsDeleted = command.ExecuteNonQuery();
if(rowsDeleted == 0)
MessageBox.Show("No Serial number found to delete");
else
....
Said that, remember that string concatenation to build command text is considered bad practice and you should never use it. A parameterized query is the only correct way to create commands that requires inputs from the user.....
string deleteEntry = "delete from Inventory where SerialNumber=#num"
command.CommandText = deleteEntry;
command.Parameters.Add("#num", OleDbType.VarWChar).Value = txtSerial.Text;
int deletedRows = command.ExecuteNonQuery();
The OleDbCommand.ExecuteNonQuery method you're using returns an Int32 which represents the number of rows affected. You could use this to find out whether a row was deleted or not.
if (command.ExecuteNonQuery() > 0)
{
// Row was deleted
}
else
{
// Row was not deleted
}
You can do a Console.WriteLine("Nothing to delete") in an if based statement, but if it is compiled and you can not see the console, try a MessageBox.Show("Nothing to delete") function after an if based statement.
if (command.ExecuteNonQuery == 0)
{
Console.WriteLine("0-removed")
}
else
{
Console.WriteLine("not deleted")
As an example...
private void timer1_Tick(object sender, EventArgs e)
if (command.ExecuteNonQuery == 0)
{
Console.WriteLine("0-removed")
}
else
{
Console.WriteLine("not deleted")
Related
This question already has answers here:
Check if a record exists in the database
(13 answers)
Closed 4 months ago.
As of now, I can delete a record based on rank without checking if it exists, after that, it will pop up a message "Movie deleted" to notify the user.
protected void bn_delete_Click(object sender, EventArgs e)
{
string rank = tb_rank.Text;
string query = "SELECT * FROM MovieList WHERE Rank= #Rank";
new System.Data.OleDb.OleDbCommand(query, new System.Data.OleDb.OleDbConnection(connectionString));
System.Data.OleDb.OleDbCommand ocmd =
new System.Data.OleDb.OleDbCommand(query,
new System.Data.OleDb.OleDbConnection(connectionString));
ocmd.CommandType = CommandType.Text;
ocmd.CommandText = "DELETE FROM MovieList WHERE Rank= #Rank";
ocmd.Parameters.AddWithValue("#Rank", rank);
ocmd.Connection.Open();
ocmd.ExecuteNonQuery();
ocmd.Connection.Close();
string notification = "Movie deleted";
ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + notification + "');", true);
}
How can I make sure that the record exists first before deleting it?
If the record does not exist, I want to pop up a message showing "Movie not exists" and do nothing.
Thank you!
Instead of selecting and then deleting, you can use the fact that ExecuteNonQuery() returns an int that represents the number of rows effected by the SQL statement it executed. If it returns 0, it means that no record was deleted.
var rowsEffected = ocmd.ExecuteNonQuery();
var notification = rowsEffected == 0
? "Movie deleted"
: "Movie does not exist" ;
ExecuteNonQuery() returns the number of rows affected see. You could simply check if this integer is 0 and then return the message.
Besides using ExecuteNonQuery you can use ExecuteScalar. This executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. The query can be a count and check if the count is larger than 0. Here is a snippet of how your code would look like:
void Main(string[] args)
{
string rank = tb_rank.Text;
if (!MovieExists(rank))
{
// show message
return;
}
DeleteMovie(rank);
}
private bool MovieExists(string rank)
{
string query = "SELECT COUNT(*) FROM MovieList WHERE Rank= #Rank";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(query);
command.Connection = connection;
command.Parameters.AddWithValue("#Rank", rank);
try
{
connection.Open();
if (Convert.ToInt32(command.ExecuteScalar()) > 0)
{
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return false;
}
private void DeleteMovie(string rank)
{
string query = "DELETE FROM MovieList WHERE Rank= #Rank";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbCommand command = new OleDbCommand(query);
command.Connection = connection;
command.Parameters.AddWithValue("#Rank", rank);
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
I have a log in page that checks with a database for current registered users. At the moment my code will tell me me the user does not exist, when in fact they are on the database, or the page will remain the same if they aren't, when the text corresponding to the problem should come up.
So the name 'Tom' is already on the database, when i type 'Tom' i get the message
"user does not exist".
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SqlDataSource1_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
}
protected void Button_LogIn_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[#"\\MAC\HOME\DESKTOP\NIMV1.MDFConnectionString"].ConnectionString);
conn.Open();
string checkuser = "select count(*) from [Table] where UserName= '" + TextBoxLogIn.Text + "'";
SqlCommand com = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
if (checkuser == TextBoxLogIn.Text)
{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
}
else
{
Response.Write("user does not exist");
}
conn.Close();
}
}
You're comparing your SQL string against the user name that has been passed in.
string checkuser = "select count(*) from [Table] where UserName= '" + TextBoxLogIn.Text + "'";
//...
if (checkuser == TextBoxLogIn.Text)
{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
} else {
Response.Write("user does not exist");
}
I assume this will always evaluate to false unless the user has an SQL query for a name :D
[EDIT] Actually even if their name was an SQL query the code would never get to that point because you wouldn't find their name in the database in the first place.
You are comparing records using user name in database with entered text.
string checkuser = "select count(1) from [Table] where UserName= '" +
TextBoxLogIn.Text + "'";
After executing query instead of:
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
if (checkuser == TextBoxLogIn.Text)
///
///
Use following code:
if (temp >= 1)//if there is any user we will get temp >= 1
{
//conn.Open(); //No need to open connection again
//checkuser is SQL query so will never be equal to
//what user enters (like joe#example.com)
//if (checkuser == TextBoxLogIn.Text)
//{
Session["New"] = TextBoxLogIn.Text;
Response.Write("User name is correct");
//}
else //if no user with given name, temp will be 0
{
Response.Write("user does not exist");
//}
//conn.Close();
}
Peope already told you about the error you've made about comparing the variable that holds the query agains the value you typed (doh!!) but i want to DISCOURAGE you against writing the queries the way you do: it isn't a good practice to write query the way you've done because you are vulnerable to SQL Injection or at least nasty bugs if you don't escape correctly your variables.
I invite you to read about how to use what the .Net framework gives to you: use Parameters!
here you can find another answer with code that you can use or at least understand: https://stackoverflow.com/a/11905249/1716620
I'm making a windows form where in all the checkedlist values are stored in one row. However it only stores one value.
Question is, is it possible to store all the checkedlist values in a single row in which only their assigned ids are stored?
This is my previous code below. if you find any mistakes or if you have any idea on how to edit to make it work, it would be a big help for me. Thanks!
foreach (DataRowView item in this.checkedListBox1.CheckedItems)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into name(eid, name, famid) Values (#eid, #name, #famid)", conn);
cmd.Parameters.AddWithValue("#eid", textBox1.Text);
cmd.Parameters.AddWithValue("#name", textBox2.Text);
string value = item.Row[0].ToString().Split(',');
cmd.Parameters.AddWithValue("#famcon", value);
cmd.ExecuteNonQuery();
}
Since you are using C#, use this code but gotta change the default name to yours.
private void button1_Click(object sender, EventArgs e)
{
try
{
string Str = "";
if (checkedListBox1.CheckedItems.Count > 0)
{
for (int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
{
if (Str == "")
{
Str = checkedListBox1.CheckedItems[i].ToString();
label1.Text = Str;
}
else
{
Str += ", " + checkedListBox1.CheckedItems[i].ToString();
label1.Text = Str;
}
}
// Make your connection to the DataBase and insertion code starting within that area.
MessageBox.Show("Your selection is for :" + Str);
}
else
{
MessageBox.Show("Please select one name at least to work it out!");
}
while (checkedListBox1.CheckedItems.Count > 0)
{
checkedListBox1.SetItemChecked(checkedListBox1.CheckedIndices[0],false);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.ToString());
}
}
I want to get the values from MySQL database and that would need to show the messages according to values. But it does not happen and that will always show int privilege is 0. If I did not assign that default value, errors will be showing on the code.
How can I solve this issue and show messages according to the int privilege values?
private void button_login_Click(object sender, RoutedEventArgs e)
{
string username = usernameInput.Text;
string password = passwordInput.Password;
int privilege = 0;
try
{
//This is command class which will handle the query and connection object.
string Query = "SELECT`tbl_user_login`.`u_id`,`tbl_user_login`.`u_username`,
`tbl_user_login`.`u_password`,`tbl_user_login`.`u_privilege`
FROM `bcasdb`.`tbl_user_login`WHERE `tbl_user_login`.`u_username` = '"
+ username + "' AND `tbl_user_login`.`u_password` ='" + password
+ "' AND `tbl_user_login`.`u_privilege` = #privi;";
MySqlConnection conn =
new MySqlConnection(BCASApp.DataModel.DB_CON.connection);
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.Parameters.AddWithValue("#privi", privilege);
MySqlDataReader MyReader;
conn.Open();
MyReader = cmd.ExecuteReader();
// Here our query will be executed and data saved into the database.
if (MyReader.HasRows && this.Frame != null)
{
while (MyReader.Read())
{
if (privilege == 1)
{
DisplayMsgBox("click ok to open the admin page ", "OK");
}
if (privilege == 2)
{
DisplayMsgBox("click ok to open the staff page ", "OK");
}
else
{
DisplayMsgBox("privilege 0", "ok");
}
}
}
else
{
DisplayMsgBox("sucess else", "ok");
}
conn.Close();
}
catch (Exception )
{
DisplayMsgBox("sucess catch", "ok");
}
}
Looks like what you're trying to do is checking the value of u_privilege column from tbl_user_login table instead of making a where condition based on privilege. You need to remove this where condition
AND `tbl_user_login`.`u_privilege` = #privi
and also remove the parameter assignment
cmd.Parameters.AddWithValue("#privi", privilege);
You can get the value of tbl_user_login.u_privilege by using MySqlDataReader.GetInt32 syntax inside while (MyReader.Read()) block
MyReader.GetInt32(3)
Please note that 3 is used because MyReader.GetInt32 requires a zero based index parameter and tbl_user_login.u_privilege is the fourth column from your query. The value should be assigned to privilege variable as below
privilege = MyReader.GetInt32(3)
On a side note, you should parameterize your query to avoid SQL injection. Here's the complete code after implementing the above changes
int privilege = 0;
try
{
//This is command class which will handle the query and connection object.
string Query = "SELECT`tbl_user_login`.`u_id`,`tbl_user_login`.`u_username`,
`tbl_user_login`.`u_password`,`tbl_user_login`.`u_privilege`
FROM `bcasdb`.`tbl_user_login`WHERE `tbl_user_login`.`u_username` =
#username AND `tbl_user_login`.`u_password` = #password;";
MySqlConnection conn =
new MySqlConnection(BCASApp.DataModel.DB_CON.connection);
MySqlCommand cmd = new MySqlCommand(Query, conn);
cmd.Parameters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#password", password);
MySqlDataReader MyReader;
conn.Open();
MyReader = cmd.ExecuteReader();
// Here our query will be executed and data saved into the database.
if (MyReader.HasRows && this.Frame != null)
{
while (MyReader.Read())
{
privilege = MyReader.GetInt32(3)
if (privilege == 1)
{
DisplayMsgBox("click ok to open the admin page ", "OK");
}
if (privilege == 2)
{
DisplayMsgBox("click ok to open the staff page ", "OK");
}
else
{
DisplayMsgBox("privilege 0", "ok");
}
}
}
else
{
DisplayMsgBox("sucess else", "ok");
}
conn.Close();
}
catch (Exception )
{
DisplayMsgBox("sucess catch", "ok");
}
If im not wrong, the privilege is being returned as a string type. Try take it in as a string then cast it to an integer?
I have a list of 1933 user names that have to be set to deleted in a mysql table (change the deleted field from 0 to 1). I'm pasting a comma delimited list (username, realname) in a list box and using a foreach statement to send each username, realname group to an update command in a static class. When I run it, I don't get any errors but none of the users rows are updated. I'm doing something wrong but I'm not sure what the issue is. Please review my code below and let me know if you find something wrong that I'm not seeing.
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
try
{
if (listBox1.Items.Count > 0)
{
foreach (string s in listBox1.Items)
{
Cursor.Current = Cursors.WaitCursor;
string[] sname = s.Split(',');
Data.RemoveUser(sname[0].ToString(), sname[1].ToString());
i++;
label3.Text = i.ToString();
}
}
else
MessageBox.Show("No user names found. Please paste a list of names to be deleted.");
Cursor.Current = Cursors.Default;
MessageBox.Show(i.ToString() + " users set to deleted.");
}
catch (Exception ex)
{
throw ex;
}
}
public static void RemoveUser(string UserName, string FullName)
{
MySqlConnection conn = new MySqlConnection(constr);
try
{
conn.Open();
string qry = "Update host_user set deleted = 1 where username = #username and name = #fname";
MySqlCommand cmd = new MySqlCommand(qry, conn);
cmd.Parameters.AddWithValue("#username", UserName);
cmd.Parameters.AddWithValue("#fname", FullName);
cmd.ExecuteNonQuery();
conn.Close();
}
catch (MySqlException e)
{
if (conn != null) conn.Close();
throw e;
}
}
When you are doing:
string[] sname = s.Split(',');
Do you end up with spaces on either side of you first name and last name? If your input was like:
"John, Doe"
You would end up search on "John" & " Doe".
If this is the case, call .Trim() on those strings before passing passing them into RemoveUser().