How to check if user in mysql database exists (in c#) - 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

Related

Update query not throwing error

Thanks for the help in advance.
Im trying to use update query in C#
Error : command is getting executed even if I use incorrect values
Design view
Code :
protected void Button1_Click(object sender, EventArgs e)
{
try
{
con.Open();
cmd = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id='" + TxtEMPID.Text + "' and AvayaID ='" + TxtAvayaID.Text + "'", con);
cmd = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID ='" + TxtAvayaID.Text + "'", con);
cmd.ExecuteNonQuery();
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
con.Close();
}
catch (SqlException ex)
{
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
your code would look better like this, it not the most optimal, but ia already a way better piece of code then your snippet
1) added parameters using a helper function for the sql injection issue
2) an ExecuteNonQuery returns the rows affected, so if you are expecting that 1 row was updated, you can check on that
3) if you update a row with an id that not exists, it will not throw a SqlException like you are expecting in your code, this happens e.g. when locking occurs
public void Update()
{
var con = new SqlConnection();
try
{
var empId = TxtEMPID.Text
var avayaId = TxtAvayaID.Text
con.Open();
var cmd1 = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id=#empId and AvayaID = #avayaId", con);
cmd1.Parameters.Add(AddParameter("#empId",empId));
cmd1.Parameters.Add(AddParameter("#avayaId", avayaId));
var cmd2 = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID =avayaId", con);
cmd2.Parameters.Add(AddParameter("#avayaId", avayaId));
var rowsaffected1 = cmd1.ExecuteNonQuery();
var rowsAffected2 = cmd2.ExecuteNonQuery();
if (rowsaffected1 == 1 && rowsAffected2 == 1)
{
//success code goes here
//--------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
}
else
{
// failure code goes here
//-----------------------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
}
catch (SqlException ex)
{
//handle errors
}
finally
{
con.Close();
}
Console.ReadLine();
}
private SqlParameter AddParameter(string name, object value) {
var par = new SqlParameter();
par.ParameterName = name;
par.Value = value;
return par;
}
If you put "incorrect" values it just updates zero of records. No errors/exception expected here.

If there is no row in database sum command return an error

An error is thrown when there is no data in data base while converting a string value into int.
try {
SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con);
string companya_credit_amount = null, comapnyb_credit_amount = null;
con.Open();
SqlDataReader drc = cmdc.ExecuteReader();
if (drc.HasRows)
{
while (drc.Read())
{
companya_credit_amount = drc[0].ToString();
}
drc.Close();
con.Close();
}
SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con);
con.Open();
SqlDataReader drcp = cmdcp.ExecuteReader();
if (drcp.HasRows)
{
while (drcp.Read())
{
companyb_credit_amount = drcp[0].ToString();
}
drcp.Close();
con.Close();
}
if (!Page.IsPostBack)
{
int companyA = 0,companyB=0;
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companya_credit_amount.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyb_credit_amount.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }
If there is value its working fine.but when there is no value in data base there is an error msg.
System.FormatException: Input string was not in a correct format.
Use IsDBNull to check for null values
Create and destroy all your type instances that implement IDisposable in using blocks. This ensures that connections are always released and resources are cleaned up.
Do not use connections across a class. Create them when needed and then dispose of them. Sql Server will handle connection pooling.
Get the native types directly, not the string equivalent! See changes to GetInt32 instead of ToString on the data reader.
You should refactor this to use SqlParameter's and make the retrieval statement generic OR get both SUM values in 1 sql call.
There is an if (!Page.IsPostBack) statement, if none of this code does anything if it is a postback then check at the top of the page and do not execute the sql statements if it is a postback. Otherwise the code is making (possibly) expensive sql calls for no reason.
try
{
int companyA = 0,companyB=0;
using(var con = new SqlConnection("connectionStringHere"))
{
con.Open();
using(SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con))
using(SqlDataReader drc = cmdc.ExecuteReader())
{
if (drc.Read() && !drc.IsDBNull(0))
companyA = drc.GetInt32(0);
}
using(SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con))
using(SqlDataReader drcp = cmdcp.ExecuteReader())
{
if (drcp.Read() && !drcp.IsDBNull(0))
companyB = drcp.GetIn32(0);
}
}
// if you are not going to do anything with these values if its not a post back move the check to the top of the method
// and then do not execute anything if it is a postback
// ie: // if (Page.IsPostBack) return;
if (!Page.IsPostBack)
{
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companyA.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyB.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }
Try to replace this
SELECT SUM(Credited_amount)
WITH
SELECT ISNULL(SUM(Credited_amount),0)
Also find one confusing code while converting Credited amount values
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
---------^^^^^
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
I don't know about your business requirement but What i think Instead of using credit_amount value companya_credit_amount should be use to show value for companyA variable right?
You should do 2 things:
string companya_credit_amount = "", comapnyb_credit_amount = "";
Before assigning the value to these string variable you should check for db null as following:
while (drc.Read())
{
companya_credit_amount = (drc[0] != DbNull.Value) ? drc[0].ToString() : "" ;
}
Similarely
while (drcp.Read())
{
companyb_credit_amount = (drcp[0] != DbNull.Value) ? drcp[0].ToString() : "";
}
Try it.
You need to initialize credit_amount to empty and check if db value is null as shown below:
try {
companya_credit_amount = string.Empty;
companyb_credit_amount = string.Empty;
SqlCommand cmdc = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=1 AND Crdt_typ_id=1", con);
string companya_credit_amount = null, comapnyb_credit_amount = null;
con.Open();
SqlDataReader drc = cmd
c.ExecuteReader();
if (drc.HasRows)
{
while (drc.Read())
{
companya_credit_amount = drcp.IsDBNull(0)?string.Empty:Convert.ToString(drcp[0]);
}
drc.Close();
con.Close();
}
SqlCommand cmdcp = new SqlCommand("SELECT SUM(Credited_amount) FROM IMS_Credit_Dir WHERE Credit_comp_id=2 AND Crdt_typ_id=1", con);
con.Open();
SqlDataReader drcp = cmdcp.ExecuteReader();
if (drcp.HasRows)
{
while (drcp.Read())
{
companyb_credit_amount = drcp.IsDBNull(0)?string.Empty:Convert.ToString(drcp[0]);
}
drcp.Close();
con.Close();
}
if (!Page.IsPostBack)
{
int companyA = 0,companyB=0;
if (companya_credit_amount != "") { companyA = Convert.ToInt32(credit_amount.ToString()); }
if (companyb_credit_amount != ""){ companyB = Convert.ToInt32(companyb_credit_amount); }
int total = (companyA+companyB);
count_total_lbl.Text = "Rs." + " " + total.ToString();
count_comapnya_lbl.Text = "Rs." + " " + companya_credit_amount.ToString();
count_companyb_lbl.Text ="Rs."+" "+ companyb_credit_amount.ToString();
}
}
catch(Exception ex) { Label2.Text = ex.ToString(); }

How to Display Messagebox When No Values Found on SQL

Following is a code to get values from table in sql and set it to relevant fields. However i want to know how to write if condition in below block code so if the datatable contains the USERID it will performs function below but if it didn't find the USERID it should popup a error message saying no User Found.
SqlCommand myCommand = new SqlCommand
("SELECT * From USER_TABLE WHERE USERID =" + userIdTextBox.Text, con1);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
nameTextBox.Text = (myReader["FIRST_NAME"].ToString());
lnameTextBox.Text = (myReader["LAST_NAME"].ToString());
posTextBox.Text = (myReader["POSITION"].ToString());
emailTextBox.Text = (myReader["E_MAIL"].ToString());
phoneTextBox.Text = (myReader["PHONE"].ToString());
usernameTextBox.Text = (myReader["USERNAME"].ToString());
userLevelTextBox.Text = (myReader["USER_LEVEL"].ToString());
string filename = (myReader["PROFILE_PICTURE"].ToString());
profilePicBox.Load(filename);
}
You need to check if(myReader.HasRows)
if(MyReader.HasRows)
{
while (myReader.Read())
{
//your code here.
}
}
else
{
// your alert.
}
if (myReader.Read()) //assuming you only ever have a single result...
{
//set form fields.
}
else
{
//message box
}
Edit based on comment from #dmitry-bychenko

foreach item in ListBox | SqlReader

what I'am trying to do here is to select the connected people,
but I don't really know how to do this. I have x names on the Listbox.
I want to check for every name the login & logout times and if login is bigger then logout time, it types near the name "Connected", "not connected" on ListBox.
Thank you in advance .
foreach (var Item in listBoxControl2.Items)
{
try
{
SqlConnection sqlConnection = new SqlConnection(ConnectDatabase);
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "Select login_time_value,logout_time_value ConnectionTime.dbo.Avalaible where name = '" + Item.ToString() +"'";
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (true)
{
bool flag = sqlDataReader.Read();
if (!flag)
{
break;
}
DateTime login = sqlDataReader.GetDateTime(0);
DateTime logout = sqlDataReader.GetDateTime(1);
if (login > logout)
{
}
else
{
}
}
sqlDataReader.Close();
sqlConnection.Close();
}
catch
{
}
}
There are many things that could be changed in your code, but to answer just to your problem, I would change the loop to use a simple for loop so you could access directly the items in the listBox and change the text for the matched items.
for(x = 0; x < listBoxControl2.Items.Count; x++)
{
while(sqlDataReader.Read())
{
DateTime login = sqlDataReader.GetDateTime(0);
DateTime logout = sqlDataReader.GetDateTime(1);
if (login > logout)
{
listBoxControl2.Items[x] = listBoxControl2.Items[x] + " connected";
}
else
{
listBoxControl2.Items[x] = listBoxControl2.Items[x] + " logged off";
}
}
}
The problem with the foreach is that you get a copy of the string text, you have to replace the original and this is easier with a for loop.
About the other problems.
Where is the FROM clause in the command text?
Move the opening of the connection outside the loop.
Use the using statement to open/use/close/dispose the disposable
objects (Why?)
Use parameterized query when building command texts to pass to the
database engine (Why?)
So the updated code could be
string cmdText = "Select login_time_value,logout_time_value ConnectionTime.dbo.Avalaible " +
"FROM ??????????" +
"where name = #name";
using(SqlConnection sqlConnection = new SqlConnection(ConnectDatabase))
using(SqlCommand sqlCommand = new SqlCommand(cmdText, sqlConnection))
{
sqlCommand.Parameters.AddWithValue("#name", "dummy");
sqlConnection.Open();
for(x = 0; x < listBoxControl2.Items.Count; x++)
{
string name = listBoxControl2.Items[x].ToString();
sqlCommand.Parameters["#name"].Value = name;
using(SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
{
while(sqlDataReader.Read())
{
DateTime login = sqlDataReader.GetDateTime(0);
DateTime logout = sqlDataReader.GetDateTime(1);
if (login > logout)
{
listBoxControl2.Items[x] = name + " connected";
}
}
}
}
}

When ASP.NET username exists, change to username(x)

Using SQL Membership Provider for ASP.NET membership. I'm using first.last as the username, which is created programmatically from the user details filled in on a form.
When user submits the form, I want to be able to check if the username exists, and change it to username1 if it does, check username1 exists, and make it username2 if it exists, etc. until it is a unique username.
I don't know how to do stored procedures, so I'm trying to use a SQLDataReader to check if username exists.
The problem is my loop. The logic is basically to set a boolean and keep looping and adding 1 to the counter, until it doesn't find a duplicate. I have stepped through this many times, and even when it sets the boolean to false, it keeps looping.
Ideas please?
Code behind:
protected void Membership_add()
{
SqlConnection con = new SqlConnection(connectionString);
string NewUserNameString = FirstName.Text + "." + LastName.Text;
//Check for duplicate aspnet membership name and add a counter to it if exists
// Check for valid open database connection before query database
bool match = true;
SqlDataReader _SqlDataReader = null;
string TestNameString = NewUserNameString;
string selectDupeString = "SELECT UserId FROM aspnet_Users WHERE UserName = '" + TestNameString + "'";
SqlCommand SQLdatareaderCmd = new SqlCommand(selectDupeString, con);
int UserNameCounter = 0;
con.Open();
while (match = true)
{
//Open the connection
try
{
//Read the table
_SqlDataReader = SQLdatareaderCmd.ExecuteReader();
}
catch (Exception ex)
{
lblDatareaderEx.Text = "An Exception occurred. " + ex.Message + " " + ex.GetType().ToString();
}
if (_SqlDataReader.HasRows)
{
//match = true;
//increase counter by 1 for each record found and change First.Name to First.Namex
TestNameString = NewUserNameString;
UserNameCounter = UserNameCounter + 1;
TestNameString = TestNameString + UserNameCounter.ToString();
_SqlDataReader.Close();
_SqlDataReader.Dispose();
selectDupeString = "SELECT UserId FROM aspnet_Users WHERE UserName = '" + TestNameString + "'";
SQLdatareaderCmd = new SqlCommand(selectDupeString, con);
}
else
{
// close sql reader
_SqlDataReader.Close();
_SqlDataReader.Dispose();
//get out of loop
match = false;
}
}
con.Close();
con.Dispose();
}
This line:
while (match = true)
does an assignment.
If you want your code to work you have to do a comparison:
while (match == true)
Or, since your variable is already a bool, you can just use the variable directly:
while(match)
At the moment you're setting match rather than comparing it's value.
Try setting while (match = true) to while (match == true)
If you break your code out into smaller blocks, the code becomes simpler and easer to read.
private string MembershipAddUser(string firstName, string lastName)
{
string username = firstName + "." + lastName;
int i = 0;
while (UserExists(username))
{
i++;
username = firstName + "." + lastName + i.ToString();
}
return username;
}
private bool UserExists(string username)
{
string sql = "SELECT COUNT(*) FROM dbo.aspnet_Users WHERE UserName = #UserName";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("#UserName", username);
using (connection)
{
connection.Open();
int count = (int) command.ExecuteScalar();
return (count != 0);
}
}

Categories

Resources