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.
Related
As the name suggest's, this is an issue with the Reader's while loop only running when a value is returned. See below in this scenario, in the case of if (email == rdr[0].ToString()) returns true, the while loop itself executes. However if it's not true the else does not execute. Also important to note that Debug.Log("Checking to see if the account exists"); only actually executes if the account exist's, as the check intends.
My assumption is, that if the Connector cannot find a row, it will not run the loop. How can I achieve this running?
Thanks.
conn.Open();
Debug.Log("SUCCESSFULL CONNECTION!");
if (!isLogin)
{
Debug.Log("Is not login");
bool doesEmailExist = false;
string seecQuery = "SELECT * FROM accounts WHERE email = '"+ email +"'";
Debug.Log(seecQuery);
MySqlCommand cmd = new MySqlCommand(seecQuery, conn);
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Debug.Log("Checking to see if the account exists");
if (email == rdr[0].ToString())
{
Debug.Log("The account exists");
accountExists.SetActive(true);
//doesEmailExist = true;
}
else //if (!doesEmailExist)
{
Debug.Log("Email is not in use. Starting OTA");
StartCoroutine(sendOTA()); // Start the OTP process
OTARead.SetActive(true);
}
Your primary issue is that the resultset has no rows, so rdr.Read() returns false on the first run and never executes the loop.
If the email column is unique, then all you want is a single result. For that you can obviate a reader and just use cmd.ExecuteScalar
Note correct use of parameterization, preventing dangerous SQL injection
Note using blocks, which will guarantee the connection gets closed in the event of an exception
bool doesEmailExist = false;
const string seecQuery = #"
SELECT 1
FROM accounts
WHERE email = #email;
";
Debug.Log(seecQuery);
using (var conn = new MySqlConnection(yourConnString))
using (var cmd = new MySqlCommand(seecQuery, conn))
{
cmd.Parameters.AddWithValue("#email", email);
conn.Open();
Debug.Log("SUCCESSFULL CONNECTION!");
Debug.Log("Checking to see if the account exists");
if (cmd.ExecuteScalar() == (object)1)
{
Debug.Log("The account exists");
accountExists.SetActive(true);
//doesEmailExist = true;
}
else
{
Debug.Log("Email is not in use. Starting OTA");
StartCoroutine(sendOTA()); // Start the OTP process
OTARead.SetActive(true);
}
}
Just an update for this, I managed to fix the issue with a workaround.
Here it is. Rather than performing a while loop I checked to see if the Reader returned any rows or not. Worked fine.
conn.Open();
Debug.Log("SUCCESSFULL CONNECTION!");
if (!isLogin)
{
Debug.Log("Is not login");
bool doesEmailExist = false;
string seecQuery = "SELECT * FROM accounts WHERE email = '"+ email +"'";
Debug.Log(seecQuery);
MySqlCommand cmd = new MySqlCommand(seecQuery, conn);
MySqlDataReader rdr = cmd.ExecuteReader();
if (!rdr.HasRows)
{
Debug.Log("Email is not in use. Starting OTA");
StartCoroutine(sendOTA()); // Start the OTP process
OTARead.SetActive(true);
}
else
{
Debug.Log("The account exists");
accountExists.SetActive(true);
}
rdr.Close();
conn.Close();
}
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
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;
I'm checking if a name already exists in the database. When I execute the query in the sql server it shows data but in application, it shows, no rows affected and it always returns false.
Here is my code:
string productExtentionName = productExtensionEntryTextBox.Text;
bool doesProductNameExtentionExist = false;
doesProductNameExtentionExist = _aProductEntryManager.DoesProductNameAlreadyExist(productExtentionName);
_aProduct.ProductNameExtention = productExtentionName;
if (doesProductNameExtentionExist != true)
{
if (!string.IsNullOrEmpty(_aProduct.ProductNameExtention))
{
saveNewProduct = _aProductEntryManager.SaveProductNameExtention(_aProduct);
if (saveNewProduct)
{
MessageBox.Show("Product name extention saved successful");
}
else
{
MessageBox.Show("Error saving product name extention");
}
}
else
{
MessageBox.Show("Please enter a product specication/extention");
}
}
else
{
MessageBox.Show("Product name extention / specification already exists");
}
Here is my Gateway
public bool DoesProductNameAlreadyExist(string productExtentionName)
{
_connection.Open();
string query = string.Format("SELECT ProductNameExtention FROM ProductNameExtentionEntryTable WHERE ProductNameExtention='{0}'", productExtentionName);
_command = new SqlCommand(query, _connection);
int affectedRows = _command.ExecuteNonQuery();
_connection.Close();
if (affectedRows > 0)
{
return true;
}
return false;
}
int affectedRows = _command.ExecuteNonQuery();
this will return -1;
Execute the query onto a SqlDataReader and check if it has rows.
Dont forget to close the reader.
SqlDataReader reader = _command.ExecuteReader();
if (reader.HasRows) MessageBox.Show("Yes"); else MessageBox.Show("No");
reader.Close();
try this
_command = new SqlCommand(query, _connection);
da.SelectCommand = _command ;
DataSet ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0] != null)
{
if (ds.Tables[0].Rows.Count > 0)
{
//write your code
return true;
}
}
Use execute scalar instead of execute non query, as this is a select query and select query does not returns the no of rows affected, which is returned by the execute non-query.
so, in this case it's returning the default value 0, hence your method is returning false.
Also, you can modify query to use top 1 1, as here you are only checking if the product exists.
SELECT TOP 1 1 FROM ProductNameExtentionEntryTable WHERE ProductNameExtention=#productExtentionName
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!");