Identifying duplicate data, and re-search database based on new user input - c#

I have been able to identify if the value is duplicated or not but only for the very first value entered, it seems as if the first entry is being held as a search and it doesn't update the search when the value has been changed in the textbox. For visual representation see images below.
Here is my method I have used:
private void CheckContactNumber()
{
DataSet myDataSet = new DataSet();
try
{
string strAccessSelect = "select count(*) from Employee where ContactNumber='" + addContactNum.Text + "'";
OleDbCommand myAccessCommand = new OleDbCommand(strAccessSelect, conn);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(myAccessCommand);
conn.Open();
myDataAdapter.Fill(myDataSet, "Employee");
}
catch (Exception ex)
{
Console.WriteLine("Error: Failed to retrieve the required data from the DataBase.\n{0}", ex.Message);
return;
}
finally
{
conn.Close();
}
DataTable dt = myDataSet.Tables[0];
if (dt != null)
{
if (int.Parse(dt.Rows[0][0].ToString()) > 0)
{
uniqueContactNumber = false;
}
}
}
Here is the method of which the checkContactNumber method links to:
private void addEmployee_Click(object sender, EventArgs e)
{
string err = "";
if (addFirstName.Text.Trim() == "")
{
errorFirstName.Visible = true;
err += "Enter a value for First Name\r\n";
}
else if (!Regex.IsMatch(addFirstName.Text, #"^[a-zA-Z]+$"))//has numerical and has a value
{
errorFirstName.Visible = true;
err += "Enter a valid First Name\r\n";
}
else errorFirstName.Visible = false;
if (addLastName.Text.Trim() == "")
{
errorLastName.Visible = true;
err += "Enter a value for Last Name\r\n";
}
else if (!Regex.IsMatch(addLastName.Text, #"^[a-zA-Z]+$"))
{
errorLastName.Visible = true;
err += "Enter a valid Last Name\r\n";
}
else errorLastName.Visible = false;
if (addFirstName.Text.Trim() != "" && addLastName.Text.Trim() != "" && addFirstName.Text.Trim() == addLastName.Text.Trim())//identifies if FirstName + SecondName is equal to each other.
{
errorFirstName.Visible = true;
errorLastName.Visible = true;
err += "First Name and Second Name must be unique\r\n";
}
if (addRole.Text.Trim() == "")
{
errorRole.Visible = true;
err += "Select a Role type\r\n";
}
else errorRole.Visible = false;
if (!Regex.IsMatch(addContactNum.Text, #"^\d{11}$"))
{
errorContactNum.Visible = true;
err += "Enter a value for Contact Number\r\n";
}
else errorContactNum.Visible = false;
CheckContactNumber();
if(uniqueContactNumber == false && addContactNum.Text != "")
{
err += "Contact Number Already exist..\r\n";
errorContactNum.Visible = true;
}
if (err == "" && uniqueContactNumber == true)
{
string addEmployee = "INSERT INTO Employee (FirstName, LastName, Role, DateOfHire, ContactNumber)" +
"VALUES (#FirstName, #LastName, #Role, #DateOfHire, #ContactNumber)";
OleDbCommand cmd = new OleDbCommand(addEmployee, conn);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
cmd.Parameters.Add("#FirstName", OleDbType.VarChar).Value = addFirstName.Text;
cmd.Parameters.Add("#LastName", OleDbType.VarChar).Value = addLastName.Text;
cmd.Parameters.Add("#Role", OleDbType.VarChar).Value = addRole.Text;
cmd.Parameters.Add("#DateOfHire", OleDbType.VarChar).Value = addDateOfHire.Text;
cmd.Parameters.Add("#ContactNumber", OleDbType.VarChar).Value = addContactNum.Text;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
//addFirstName.Text = String.Empty;
//addLastName.Text = String.Empty;
//addRole.Text = String.Empty;
//addContactNum.Text = String.Empty;
addRole.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
}
//Save It
else
{
MessageBox.Show(err);
}
}
Here is an example image showing that it can identify if there is duplicate data.
This shows that I have re-entered to make it unique but it still says it exists.
This shows that I have closed the program and ran it again using the same contact number in image 2 and it then saves.

If you click the addEmployee button when contact number is a duplicate uniqueContactNumber is set to false and a message box is shown. If you than change the contact number with a new one and click the button again the CheckContactNumber method does nothing leaving uniqueContactNumber with the value false.
You need to make sure to set uniqueContactNumber to true in that case.
You can fix it using the code below:
if (int.Parse(dt.Rows[0][0].ToString()) > 0)
{
uniqueContactNumber = false;
}
else
{
uniqueContactNumber = true;
}

I'd recommend that you add a UNIQUE constraint to Index which contains the ContactNumber field for the Employee table and that you catch the error thrown by MySQL when a record is inserted which violates that constraint.
The first two images I see appear to be identical (http://i.stack.imgur.com/a3WLr.png, http://i.stack.imgur.com/W2SoA.png)
The 3rd image (XOE0Q.png, sorry SO won't let me post another link) appears to have a different number than the above two.
Thus, I think your code is doing the right thing unless the 2nd image was an error. If a different number was typed in for image 2 vs image 1, then your form is probably not calling the validate method again, upon further input. To verify this, use the debugger and set a breakpoint inside your checkContactNumber method and verify that it's being called again. Which event is this method bound to on the contactNumber input?

Related

How to check if user in mysql database exists (in c#)

So I know this is a often asked question but I want to check if the username is already taken in the database using c#. I tried this:
MySqlCommand cmd2 = new MySqlCommand("SELECT * FROM tablename WHERE(name = '" + tb1.Text + "');");
cmd2.Connection = connect;
connect.Open();
string unt = "";
try
{
MySqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
unt= dr.GetString("name");
}
dr.Close();
}
catch (Exception ex)
{
errorbox.Content = ex.Message;
}
finally
{
connect.Close();
}
if(unt == "" || unt == "0") {
continuel = false;
tb2.Text = "User " +tb1.Text+ " doesn't exist!";
Popup1.IsOpen = true;
}
Its a WPF project and the variable 'continuel' is set to true by default. The code doesn't recognize if a user doesn't exist.
First off your code is vulnerable to sql inject, you should never concatenate values into a query. secondly you can do a count and execute a scalar. Not I stripped down your code a little you'll have to add error handling back.
bool userExists = false;
private String sql = "SELECT COUNT(*) FROM tableName WHERE name = #usernameparam;";
MySqlCommand m = new MySqlCommand(sql);
m.Parameters.AddWithValue("#usernameparam", tb1.Text.Trim());
int userCount = Convert.ToInt32(m.ExecuteScalar());
if(userCount>0)
{
userExists = true;
}
//use userExists variable to evaluate if user exists

How can a test condition be based on the count from query result?

I want to create something like if (reader["assignID"].count > 2) then something happens. But I understand that MySqlDataReader does not have a count function. How else should I approach this?
I want to count the rows.
My code
try
{
string myConnectionString3;
myConnectionString3 = "server=localhost;uid=root;pwd=root;database=medicloud;SslMode=None;charset=utf8";
MySqlConnection connection3 = new MySqlConnection(myConnectionString3);
MySqlCommand cmd3 = new MySqlCommand();
EncodingProvider ppp3;
ppp3 = CodePagesEncodingProvider.Instance;
Encoding.RegisterProvider(ppp3);
cmd3.CommandType = CommandType.Text;
string sqlStr2 = "Select assignID from assign where userId=#name";
cmd3.Parameters.AddWithValue("#name", txtValue.Text);
cmd3.CommandText = sqlStr2;
cmd3.Connection = connection3;
connection3.Open();
MySqlDataReader reader1 = cmd3.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
if (reader1["assignID"].count > 2) //count rows if more than 2
{
txtAssignID1.Text += "Hello";
}
else
{
btnStart.IsEnabled = true;
string assignID = (reader1["assignID"].ToString());
txtAssignID1.Text += "Your exercise ID is: " + assignID;
}
}
}
else
{
txtAssignID1.Text += "You have not been assigned any exercise ID";
txtAssignID.IsEnabled = false;
}
connection3.Close();
}
catch (MySqlException)
{
}
If you want to know how many assignID for a single user are present then you should ask it to your database. Change your query to
string sqlStr2 = "Select COUNT(assignID) as Totals from assign where userId=#name";
then you use ExecuteScalar to get back the result
int assignCount = 0;
// We need to check for nulls, because if the where condition doesn't
// match any userid then ExecuteScalar returns null.
object result = cmd3.ExecuteScalar();
if(result != null)
assignCount = Convert.ToInt32(result);
And remove all the datareader stuff.
If you need to know also the value of AssignID then you should go back to the MySqlDataReader approach but with a different query again
string sqlStr2 = #"Select assignID, COUNT(assignID) as Totals
from assign where userId=#name
GROUP BY assignID";
.....
MySqlDataReader reader1 = cmd3.ExecuteReader();
if (reader1.HasRows)
{
while (reader1.Read())
{
if ((int)reader1["Totals"] > 2)
{
// Not clear what you want to do if Totals > 2
txtAssignID1.Text += "Hello";
}
else
{
btnStart.IsEnabled = true;
string assignID = (reader1["assignID"].ToString());
txtAssignID1.Text += "Your exercise ID is: " + assignID;
}
}
}
else
{
txtAssignID1.Text += "You have not been assigned any exercise ID";
txtAssignID.IsEnabled = false;
}
If you only need to know if the count is > 2 it may be better to use a count query and execute a GetScalar. This way you only retrieve the data that is necessary.

C# SQL Trying to create a voting system for sql entries (voter must have a customer number Record)

I am currently creating a voting system whereby existing users can vote on whether other entries are valid or not (upvote/Downvote) thru a sql dataset table.
Each user who is registered gets a customer number and the user needs a customer number to cast a vote. When the user casts a vote their customer number is recorded in the entry and the sql query updates the score to either add 1 to upvote or 1 to downvote. A unique constraint is applied to the voters ID on each entry voted to prevent a double vote and a user must have a customer number to vote.
My Code below attempts to do this however it always seems to end up with the message box saying "error, you cannot vote until you provide a valid customer number in the Textbox". All help is appreciated, thanks a lot!
protected void searchTheDB()
{
string s = "SELECT compName As 'Company/Organization Name', btcAddr As 'Bitcoin Address', Premium_User as 'Premium User'," +
"upvote as 'Upvotes',downvote As 'Downvotes' FROM clientDataTable WHERE compName LIKE '%" + searchBox.Text + "%'";
try
{
SqlConnection forSearch = new SqlConnection(connectionString);
SqlDataAdapter search = new SqlDataAdapter(s, forSearch);
DataSet dB = new DataSet();
search.Fill(dB);
searchGridView.DataSource = dB;
searchGridView.DataBind();
searchBox.Text = String.Empty;
}
catch (SqlException exp)
{
throw new InvalidOperationException("Sorry, the website is experiencing difficulties, please try again, error: ", exp);
}
}
protected void searchButton_Click(object sender, EventArgs e)
{
custVoteTextBox.Text = String.Empty;
searchTheDB();
generalLabel.Text = "results displayed below, if nothing is displayed your search returned no results";
}
protected void canUserVote()
{
submitCustNumButton_Click(new object(), new EventArgs());
string query = "INSERT INTO dbo.ClientDataTable (custNum) Values (#custNum)";
try
{
SqlConnection checkCustNum = new SqlConnection(connectionString);
SqlCommand isCustNumbValid = new SqlCommand(query, checkCustNum);
isCustNumbValid.Parameters.AddWithValue("#custNum", custNumber);
checkCustNum.Open();
isCustNumbValid.ExecuteNonQuery();
checkCustNum.Close();
}
catch (SqlException e)
{
if (e.Number == 2627) //checks if customer number is registered by activating unique constraint
{
canVote = true;
}
else //else user is not eligable to vote
{
canVote = false;
MessageBox.Show("invalid customer number, you cannot vote" + e);
}
}
}
protected void searchGridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
canUserVote();//calls this method to check if user is eligable to vote with the given custNum in the textbox
if (canVote == true && custVoteTextBox.Text.Length == 8)
{
try
{
SqlConnection voteDb = new SqlConnection(connectionString);
{
switch (e.CommandName)
{
case "Upvote":
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow selectedRow = searchGridView.Rows[index];
string upvoteUpdateQuery = "UPDATE dbo.clientDataTable SET upvote = #upvote WHERE compName = #compName";
SqlCommand Upvote = new SqlCommand(upvoteUpdateQuery, voteDb);
Upvote.Parameters.AddWithValue("#upvote", "#upvote" + 1);
Upvote.Parameters.AddWithValue("#compName", selectedRow.DataItem.Equals("#compName"));
string insertQuery = "INSERT INTO dbo.clientDataTable (voted) Values(#voted) WHERE compName = #compName";
SqlCommand insertVoterDetailsUpvote = new SqlCommand(insertQuery, voteDb); //inserts voter information into specific entries table
insertVoterDetailsUpvote.Parameters.AddWithValue("#voted", custNumber);
insertVoterDetailsUpvote.Parameters.AddWithValue("#compName", selectedRow.DataItem.Equals("compName"));
voteDb.Open();
Upvote.ExecuteNonQuery();
voteDb.Close();
break;
case "Downvote":
int downvoteindex = Convert.ToInt32(e.CommandArgument);
GridViewRow downvoteSelectedRow = searchGridView.Rows[downvoteindex];
string downvoteUpdateQuery = "UPDATE dbo.clientDataTable SET downvote = #downvote WHERE compName = #compName";
SqlCommand Downvote = new SqlCommand(downvoteUpdateQuery, voteDb);
Downvote.Parameters.AddWithValue("#downvote", "#downvote" + 1);
Downvote.Parameters.AddWithValue("#compName", downvoteSelectedRow.DataItem.Equals("#compName"));
string downvoteInsertQuery = "UPDATE clientDataTable SET downvote = downvote + 1 WHERE compName = #compName";
SqlCommand insertVoterDetailsDownvote = new SqlCommand(downvoteInsertQuery, voteDb); //inserts voter information into specific entries table
insertVoterDetailsDownvote.Parameters.AddWithValue("#voted", custNumber);
insertVoterDetailsDownvote.Parameters.AddWithValue("#compName", downvoteSelectedRow.DataItem.Equals("#compName"));
voteDb.Open();
Downvote.ExecuteNonQuery();
voteDb.Close();
break;
}
}
}
catch (SqlException exp)
{
if (exp.Number == 2627)
{
MessageBox.Show("Sorry, you have already voted");
}
else
{
throw new InvalidOperationException("Sorry, the website is experiencing difficulties, please try again, error: ", exp);
}
}
}
else
{
MessageBox.Show("error, invalid customer number in the Textbox");
}
}
protected void submitCustNumButton_Click(object sender, EventArgs e)
{
int custNo = int.Parse(custVoteTextBox.Text);
this.custNumber = custNo;
}
I can't tell for sure from your code but it seems that custNumber is a text box and so instead of:
if (canVote == true && custNumber.ToString().Length == 9)
you should have:
if (canVote == true && custNumber.Text.Length == 9)
If I'm wrong and it isn't a text box, put a breakpoint on that line and see what custNumber.ToString() actually equals.
Also note that your code is vulnerable to a SQL injection attack. Here's some interesting reading on the subject. How does the SQL injection from the "Bobby Tables" XKCD comic work?

Comparing data values from mySQL (WPF - C#)

I am attempting to learn .WPF and I've already encountered snag.
I'm trying to take 2 user input strings, via text-boxes, and compare both strings to values
retrieved from a mySQL database.
findUserFromDB function below: ( this is supposed to retrieve and compare the user values )
public static void findUserFromDB(string user, string pass)
{
List<User> users = new List<User> { };
MySqlDataReader reader = null;
bool userFound = false;
MainWindow main = new MainWindow();
try
{
myConn.Open();
MySqlCommand cmd = new MySqlCommand();
//Sets command text and connection database
cmd.CommandText = string.Format("Select * From users");
cmd.Connection = myConn;
reader = cmd.ExecuteReader();
while(reader.Read())
{
User forUser = new User
{
sName = reader.GetString("Forename").Trim(),
sPass = reader.GetString("Password").Trim(),
};
users.Add(forUser);
}
if (userFound == false)
{
MessageBoxResult msg = MessageBox.Show(main, "Username or Password" +
" not recognised.", "Login failed", MessageBoxButton.OK);
}
for (int i = 0; i < user.Count(); i++)
{
if (users[i].sName == user && users[i].sPass == pass)
{
Menu m = new Menu();
string message = "Welcome back " + user + ".";
MessageBoxResult msg = MessageBox.Show(main, message,
"Login successful", MessageBoxButton.OK);
m.Show();
main.Close();
break;
}
}
}
catch (MySqlException e)
{
}
finally
{
if (reader != null)
{
reader.Close(); //Close the reader
}
if (myConn != null)
{
myConn.Close(); //ensure you close the connection
}
}
looking at it now I realise that I should be retrieving the data and then closing the DB, before comparing the values...
My questions:
What am I doing wrong?
As soon as I press the button to login nothing happens.
I got it working.
Was referencing the wrong Database ^^,
God I feel stupid...

Inserting data query error

i have tried to insert the data by login to the system. my query doesn't have any error, but the exception has thrown by the run time as "Object reference not set to an instance of an object ". check my code and please correct me.
protected void Button1_Click(object sender, EventArgs e)
{
try
{
if (TextBox6.Text == " ")
{
string alertmessage = "";
alertmessage = "Username should not be blank";
this.CreateMessageAlert(this, alertmessage, "alertKey");
TextBox6.Focus();
}
else if (TextBox7.Text == " ")
{
string alertmessage = "";
alertmessage = "Username should not be blank";
this.CreateMessageAlert(this, alertmessage, "alertKey");
TextBox7.Focus();
}
else
{
string sq = "SELECT COUNT(*) FROM tbl_KKSUser WHERE Uname=#un and Password=#pas";
SqlCommand sd = new SqlCommand(sq, con);
SqlParameter unameparam;
unameparam = new SqlParameter("#un", SqlDbType.VarChar, 25);
unameparam.Value = TextBox6.Text;
sd.Parameters.Add(unameparam);
string original = TextBox7.Text.Trim();
string withhash = original;
b1 = Encoding.BigEndianUnicode.GetBytes(withhash);
encrypted = Convert.ToBase64String(b1);
SqlParameter passparam;
passparam = new SqlParameter("#pas", SqlDbType.VarChar, 8000);
passparam.Value = Convert.ToString(encrypted);
sd.Parameters.Add(passparam);
con.Open();
{
int iresults;
iresults = Convert.ToInt32(sd.ExecuteScalar().ToString());
if (iresults > 0)
{
string q = "insert into tbl_KKSMaterialRaise(MaterialCode,Source,Category,Population,StockInStores,Specification,PrearedBy,CheckedBy,ApprovedBy,CreatedDate) values(#mc,#sc,#cat,#pop,#sis,#spec,#pb,#cb,#ab,#cd)";
SqlCommand dm = new SqlCommand(q, con);
dm.Parameters.AddWithValue("#mc", Mcodeddl.SelectedItem.Text);
dm.Parameters.AddWithValue("#sc", TextBox1.Text.Trim());
dm.Parameters.AddWithValue("#cat", TextBox2.Text.Trim());
dm.Parameters.AddWithValue("#pop", TextBox3.Text.Trim());
dm.Parameters.AddWithValue("#sis", TextBox4.Text.Trim());
dm.Parameters.AddWithValue("#spec", TextBox5.Text.Trim());
dm.Parameters.AddWithValue("#pb", PBddl.SelectedItem.Text);
dm.Parameters.AddWithValue("#cb", CBddl.SelectedItem.Text);//In this line i have got error
dm.Parameters.AddWithValue("#ab", ABddl.SelectedItem.Text);
dm.Parameters.AddWithValue("#cd", DateTime.Today);
dm.ExecuteNonQuery();
string alertmessage = "";
alertmessage = "Component Details Saved";
this.CreateMessageAlert(this, alertmessage, "alertKey");
}
else
{
Response.Write("<script>alert('Invalid Username/Password')</script>");
}
}
con.Close();
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
It looks most likely that one of your dropdownlists has no option selected, i.e. the null reference is coming from one of the lines like:
dm.Parameters.AddWithValue("#mc", Mcodeddl.SelectedItem.Text);
Try checking that all of those have items selected before retrieving the .Text property.
If it isn't that, it would be useful to know which line is causing the exception - you can usually get that from the exception stack trace.
It means you have not initialized or assigned a variable. The debugger should tell you which variable specifically. Take a closer look at it. Then you only have to check that it is already initialized (= new Class()) or assigned (= instance).
You may want to take a look at this question.

Categories

Resources