Catch Zero Rows Updated - c#

I have the following code that is clearing the account logout flags for an application we use.
try
{
string connectionString = "Data Source=DBSERVER;Initial Catalog=AbraEmployeeSelfService;Integrated Security=False;user=FOO;pwd=BAR";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("UPDATE dbo.tUSERS SET UserUnsuccessfulLoginCount = 0, UserLockoutInd = 0 WHERE LEFT(UserAbraSuiteLogicalPrimaryKey, 4) = '" + BadgeNumber + "'", connection))
{
command.ExecuteNonQuery();
connection.Close();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
How can I get this to catch when zero rows are returned?

ExecuteNonQuery will return the number of affected rows. Use that. :)
int nbUpdatedRows;
(...)
nbUpdatedRows = command.ExecuteNonQuery();
(...)
if (nbUpdatedRows == 0) // do stuff

ExecuteNonQuery() method returns the total number of rows effected after executing the command.
From MSDN : ExecuteNonQuery()
Executes a Transact-SQL statement against the connection and returns
the number of rows affected.
You can check its return value to compare with zero.
Try This:
int status = command.ExecuteNonQuery();
if(status==0)
MessageBox.Show("No Rows Updated!");

Related

Show status when data in database MySQL was deleted in C#

I have issue when showing the status when data was delete or not. Here's the code
public bool isDelete (String nim, String pass)
{
String query = "delete from dbmahasiswa where NIM=#NIM AND Password=#Password";
class_Mahasiswa cm = new class_Mahasiswa();
try
{
connect.Open();
MySqlCommand cmd = new MySqlCommand(query, connect);
cmd.Parameters.AddWithValue("#NIM", nim);
cmd.Parameters.AddWithValue("#Password", pass);
cmd.ExecuteNonQuery();
MySqlDataReader reader;
reader = cmd.ExecuteReader();
int count = 0;
while (reader.Read())
{
count += 1;
}
if (count == 1)
{
System.Windows.Forms.MessageBox.Show("sukses!", "Status");
return true;
}
else
System.Windows.Forms.MessageBox.Show("akun tidak ditemukan", "Status");
return false;
connect.Close();
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message, "Warning");
return false;
}
return true;
}
If I type the wrong username or password, it will show MessageBox "akun tidak ditemukan"(account not found). Also when I type the right username and password to delete it, it will show that MessageBox because the function will read the database after data has been deleted.
My question is, how to show the "Sukses" MessageBox when data has been deleted?
You are calling ExecuteReader. The ExecuteReader is used to read data returning from the query with a SELECT statement. You can't use it to know if a row or more has been deleted. For this task you use just ExecuteNonQuery and get the return value to know the number of rows 'affected' by the query command
String query = "delete from dbmahasiswa where NIM=#NIM AND Password=#Password";
class_Mahasiswa cm = new class_Mahasiswa();
try
{
connect.Open();
MySqlCommand cmd = new MySqlCommand(query, connect);
cmd.Parameters.AddWithValue("#NIM", nim);
cmd.Parameters.AddWithValue("#Password", pass);
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
System.Windows.Forms.MessageBox.Show("sukses!", "Status");
return true;
}
else
{
System.Windows.Forms.MessageBox.Show("akun tidak ditemukan", "Status");
return false;
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message, "Warning");
return false;
}
finally
{
connect.Close();
}
}
Also, it seems that you are using a global connect object for your connection. This is usually the source of many bugs like the one you have in your catch clause. If your code results in an exception you forgot to close the connection and, in the next call to connect.Open, you will get an error. I have added a finally to ensure proper closure of your connection object. However it is a better practice to keep the connection local to the code where you need it, open inside a using statement block to have it closed and disposed at the end of the block

C# select from SQL Server database

I want to make a extra control in my C# application if the record exist.
I have got the following code - but it keeps returning a result of -1 even though the record does exist in the SQL Server database.
Can someone help me with this? I have added --> for where it went wrong
private void btnVerwijderen_Click(object sender, RoutedEventArgs e)
{
if (autonrTextBox.Text == "")
{
MessageBox.Show("Waarschuwing u kunt geen auto verwijderen indien er GEEN autonr is ingevuld");
}
else
{
--> SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-RSEBNR7;Initial Catalog=AudiDealer;Integrated Security=True");
--> string check = "SELECT autonr FROM auto WHERE autonr =#autonr";
--> SqlCommand command1 = new SqlCommand(check, con);
--> command1.Parameters.AddWithValue("#autonr", autonrTextBox.Text);
con.Open();
int auto = command1.ExecuteNonQuery();
con.Close();
--> X - 1 MessageBox.Show(auto.ToString());
if (auto > 0)
{
try
{
con.Open();
using (SqlCommand command = new SqlCommand("DELETE FROM auto WHERE autonr =" + autonrTextBox.Text, con))
{
command.ExecuteNonQuery();
}
con.Close();
}
catch (SystemException ex)
{
MessageBox.Show(string.Format("An error occurred: {0}", ex.Message));
}
}
else
{
MessageBox.Show("Het opgegeven autonr komt niet voor in de database. controleer deze.");
}
}
}
The ExecuteNonQuery() method doesn't work like you think it does. The return value for this method is the number of rows changed, not anything from the result set. SELECT queries don't change rows, so -1 is the expected result. 0 rows would imply a WHERE clause that matched no rows in an UPDATE, DELETE, or INSERT. -1 is used to indicate a different situation... either a statement that doesn't change rows or a rollback. Check the remarks section in the documentation for the method.
You want to use the ExecuteScalar() method instead.
int auto = -1;
using (var con = new SqlConnection(#"Data Source=DESKTOP-RSEBNR7;Initial Catalog=AudiDealer;Integrated Security=True"))
using (var cmd = new SqlCommand("SELECT autonr FROM auto WHERE autonr =#autonr", con))
{
cmd.Parameters.Add("#autonr", SqlDbType.Int).Value = int.Parse(autonrTextBox.Text);
con.Open();
auto = (int)cmd.ExecuteScalar();
}
Finally... why check before deleting? This is just wasteful. Just issue the DELETE statement. There's no need to do a SELECT first. Your try/catch and the if() checks already handle situations where the record doesn't exist just fine.
int autonr = 0;
if (!int.TryParse(autonrTextBox.Text, autonr))
{
MessageBox.Show("Waarschuwing u kunt geen auto verwijderen indien er GEEN autonr is ingevuld");
}
else
{
try
{
using (var con = new SqlConnection(#"Data Source=DESKTOP-RSEBNR7;Initial Catalog=AudiDealer;Integrated Security=True"))
using (var cmd = new SqlCommand("DELETE FROM auto WHERE autonr = #autonr;", con))
{
cmd.Parameters.Add("#autonr", SqlDbType.Int).Value = autonr;
con.Open();
int result = cmd.ExecuteNonQuery();
if (result <= 0)
{
MessageBox.Show("Het opgegeven autonr komt niet voor in de database. controleer deze.");
}
}
}
catch (SystemException ex)
{
MessageBox.Show(string.Format("An error occurred: {0}", ex.Message));
}
}
Please use ExecuteScalar, ExecuteNonQuery will not return the result.
ExecuteNonQuery return only the the row that was change/add/remove
if you want to know how many you have use in the query Count and get the rows'number
SELECT Count(*) as CountAutonr FROM auto WHERE autonr =#autonr
and then you will get the from the CountAutonr the number of Rows
There're many things wrong in that piece of code, I really recommend you to encapsulate those database queries inside a business class that will connect to the database, retrieve the data and return as a DAO object... but that won't answer your question.
The issue is in the select command execution, ExecuteNonQuery is meant for executing UPDATE, INSERT and DELETE statements, returning the number of affected rows:
con.Open();
**int auto = command1.ExecuteNonQuery();**
con.Close();
You must use ExecuteReader method to retrieve the SELECT results as explained in the following article:
Retrieving Data Using a DataReader
The problem is in command1.ExecuteNonQuery() which returns the number of modified rows. Your query doesn't modify anything but only reads data from database, so the return value will be always -1.
So use ExecuteScalar instead - it will return your autonr value. Just remember to check it for null and cast it to correct type:
int auto = 0;
object result = command1.ExecuteScalar();
if (result != null)
auto = (int)result;

Check on the result of an update is failing

Every time I click on change password it will change the password but it prompts the invalid combination
Here is my code
using (SqlCommand cmd = new SqlCommand("UPDATE LoginReport SET PassLogin = #NewPassLogin WHERE UserLogin = #UserLogin AND PassLogin = #PassLogin ", conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#UserLogin", txtUser.Text);
cmd.Parameters.AddWithValue("#PassLogin", txtOldPass.Text);
cmd.Parameters.AddWithValue("#NewPassLogin", txtNewPass.Text);
SqlDataReader Dr = cmd.ExecuteReader();
if (Dr.HasRows == true)
{
MessageBox.Show("Sucessfully Updated Account");
}
else
{
MessageBox.Show("Invalid Combination");
}
}
Why is the check failing?
An update does not return any rows, a select does. Hence, HasRows is false.
You have to check another way if the update was succesful: by checking the result of ExecuteNonQuery(). It will return the rows affected. If that is more than 0, it was successful.
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show("Sucessfully Updated Account");
}
else
{
MessageBox.Show("Invalid Combination");
}
Instead of cmd.ExecuteReader(); you have to use cmd.ExecuteNonQuery(); which returns the number of affected rows.
int RowsAffected = cmd.ExecuteNonQuery();
if (RowsAffected == 1)
{
MessageBox.Show("Sucessfully Updated Account");
}
else
{
MessageBox.Show("Invalid Combination");
}
An Update Command does not return any rows so it's correct that Dr.HasRows == true returns false.
You should have to use ExecuteNonQuery.
ExecuteNonQuery: Use this operation to execute any arbitrary SQL statements in SQL Server if you do not want any result set to be returned.

Having troubles with a command's execution

So, basically what I'm doing is, after adding a diagnosis on the TextBox I'm checking if there is a Diagnosis with the same name already. The connection works fine, however, I'm having difficulties with executing the command in this line here:
var count = (int)cmd.ExecuteNonQuery();
Here's the full method
protected void MesmoDiagnostico_ServerValidate(object source, ServerValidateEventArgs args)
{
string connectionString = ConfigurationManager.ConnectionStrings["BDClinica"].ConnectionString;
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("Select COUNT(*) from Diagnosticos Where Diagnostico_Nome=#Diagnostico_Nome", connection);
connection.Open();
cmd.Parameters.AddWithValue("#Diagnostico_Nome", source);
var count = (int)cmd.ExecuteNonQuery();
if (count > 0)
{
args.IsValid = false;
}
else
{
args.IsValid = true;
}
connection.Close();
}
Am I missing something? Thanks!
According to MSDN, ExecuteNonQuery is for executing catalog or UPDATE/INSERT/DELETE operations and returns the number of rows affected. By using a COUNT, you're still looking for "number of rows" but it's being executed as query, not an update.
Since you only want one piece of data, technically the first column of the first row, you can use ExecutScalar instead.
This is almost the exact code that you need :
SqlConnection con = new SqlConnection(Settings.Default.FrakoConnectionString);
SqlCommand maxcommand = new SqlCommand("SELECT MAX(Counter) AS max FROM ppartikulieren", con);
try
{
con.Open();
max = (int)maxcommand.ExecuteScalar() + 1;
}
catch (Exception ex)
{
MessageBox.Show("Fout bij het plakken:\n" + ex.Message, "Frako planner", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
finally
{
con.Close();
}
you can also use a using statement of course. But the point is that you really need to cast the output of ExecuteScalar.

SQL rows are not being deleted

So I have this code that is designed to delete a row in mySQL server database judging by what is selected in my list box. Here is the code I have to remove the rows:
private void remove_btn_Click(object sender, EventArgs e)
{
try
{
if (Calls_lsb.SelectedItem == null)
MessageBox.Show("Please select an item for deletion.");
}
else
{
int i = Calls_lsb.SelectedIndex;
if (i > 0)
{
SqlConnection connection = new SqlConnection(//My Connection String);
string sqlStatement1 = "DELETE FROM Records WHERE CallID = #Id";
string sqlStatement2 = "DELETE FROM Calls WHERE CallID = #Id";
connection.Open();
SqlCommand cmd1 = new SqlCommand(sqlStatement1, connection);
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd1.ExecuteNonQuery();
SqlCommand cmd2 = new SqlCommand(sqlStatement2, connection);
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
cmd2.ExecuteNonQuery();
connection.Close();
Calls_lsb.Items.Remove(Calls_lsb.Items[i]);
}
else
{
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I get no exceptions and I have similar code that adds records that works fine. I tried stepping into the code but it all seemed fine. It simply just does not delete the row from the database. It removes the correct item from the list, just not the database.
If anyone could shine some light on this situation that would be great, thanks!
Edit : Ok, I seem to have fixed the problem. I just removed the whole i = selected index stuff and replace the 'Calls_lsb.Items[i]' with '(Calls_lsb.SelectedIndex + 1)'. I don't really understand why I was getting an exception when I tried to add 1 to i as this is basically doing the same thing.
Replace your below line code.
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
//with
cmd1.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);
and
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i]);
// with
cmd2.Parameters.AddWithValue("#Id", Calls_lsb.Items[i].Value);

Categories

Resources