I have a method in DataBase class that resides in App_Code which I use to call a Stored Procedure for Login, but when I make the call I get no error but my Login will not complete.
This is the DataBase Class:
public class DataBaseClass
{
SqlDataAdapter da;
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
public DataBaseClass()
{
}
public DataTable CallSP(string UserName, string Password)
{
con = new SqlConnection(#"Data Source=MyServer;Initial Catalog=MyDataBase;Integrated Security=True");
con.Open();
cmd = new SqlCommand("LoginUser", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#UserName", SqlDbType.NVarChar, 20).Value = "UserName";
cmd.Parameters.Add("#Password", SqlDbType.NVarChar, 20).Value = "Password";
da = new SqlDataAdapter(cmd);
da.Fill(dt);
cmd.ExecuteNonQuery();
cmd.Dispose();
con.Close();
return dt;
}
This is the code I used to call for Login:
DataBaseClass dbClass = new DataBaseClass();
dt = new DataTable();
dt = dbClass.CallSP("UserName", "Password");
if (dt.Rows.Count > 0)
{
boolReturnValue = true;
Session["UserId"] = dt.Rows[0]["Id"].ToString();
string updateLastLogin = "Update [User] SET LastLogin='" + System.DateTime.Now.ToString() + "' where Id='" + Session["UserId"].ToString() + "'";
dbClass.ConnectDataBaseToInsert(updateLastLogin);
}
return boolReturnValue;
}
This is My Stored Procedure:
CREATE PROCEDURE [dbo].[LoginUser] (
#UserName nvarchar(20),
#Password nvarchar(20)
)
AS
SET NOCOUNT ON;
(
SELECT * FROM [User] WHERE Email = #UserName AND Password = #Password
)
Can anyone reproduce my code and tell me why my Login call could not work.
Try do the following changes in the CallSP method:
cmd.Parameters.Add("#UserName", SqlDbType.NVarChar, 20).Value = UserName;
cmd.Parameters.Add("#Password", SqlDbType.NVarChar, 20).Value = Password;
Now appling more attention in your code I saw that your parameters are around quotes, so you were passing the literal strings "UserName" and "Password" instead the values.
With this changes you will pass the values from your parameters.
Sorry by my mistakes.
I hope it can help you.
Related
I am trying to update my data in a SQL Server database through C#. I am getting updated. But the problem is the data is updated twice.
For example I have 10 (int) in my balance and if I add another 10, it turns to 30.
Any help would be appreciated.
Here is my code:
protected void LoginClick(object sender, EventArgs e)
{
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
int i = cmd.ExecuteNonQuery();
con.Close();
}
I would like to rectify few mistakes in your code,
DataTable is not needed to execute the update query, ExecuteNonQuery will do the job
The adapter.Fill and ExecuteNonQuery do the same job here and that's why your updates happening twice
Make use of parameterization while dealing with user inputs to avoid exceptions
For parsing integers use int.TryParse instead for Convert.ToInt32
I think the following code would help you to do the same function in a smarter way:
int currentBalance = 0;
if(int.TryParse(txtAdd.Text, out currentBalance))
{
string querSql = "Update [Order] set Balance = Balance + #balance," +
" Card = #card where email = #email"
using (SqlConnection dbConn = new SqlConnection("connectionString here"))
{
dbConn.Open();
using (SqlCommand sqlCommand = new SqlCommand(querySql, dbConn))
{
sqlCommand.Parameters.Add("#balance", SqlDbType.int).value = currentBalance;
sqlCommand.Parameters.Add("#card", SqlDbType.VarChar).value = card.Text;
sqlCommand.Parameters.Add("#email", SqlDbType.VarChar).value = email;
sqlCommand.ExecuteNonQuery();
}
}
}
Please note: YOu are parsing the balance as an integer value, so I assume the column Balance is an integer field in the database, if not make use of corresponding datatype for the parameter #balance also update the parsing technique
As per the documentation:
SqlDataAdapter(SqlCommand)
Initializes a new instance of the SqlDataAdapter class with the specified SqlCommand as the SelectCommand property.
What is going wrong in your code?
Actually you are passing SqlDataAdapter your update query as the Select command. So now when you will use this instance of SqlDataAdapter to Fill your datatable then actually you are executing your Update command. Look at the following code along with comments to see what is going wrong:
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
SqlDataAdapter sda = new SqlDataAdapter(cmd);//The Select command for SqlDataAdapter
//is actually now the update command specified by cmd instnace of SqlCommand
DataTable dt = new DataTable();
sda.Fill(dt);//here SqlDataAdapter will execute it's Select command which is actually set
//to an update statement so your record will be updated
int i = cmd.ExecuteNonQuery();//and here again the update command is being executed now
//directly using the SqlCommand cmd instance and thus your record gets updated twice
con.Close();
Fixed Code:
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
//Create a new SqlComamnd
SqlCommand selectCommand = new SqlCommand("Select * from [Order]");
//Put the newly created instance as SelectCommand for your SqlDataAdapter
SqlDataAdapter sda = new SqlDataAdapter(selectCommand);
DataTable dt = new DataTable();
sda.Fill(dt);
int i = cmd.ExecuteNonQuery();
con.Close();
Hope this help and do have a look at the documentation for better understanding of the SqlDataAdapter and DataTable. Thanks.
It shows invalid user credentials even though I inputted the right one. I don't know if I made the parameters wrong or if my query is wrong. I want to learn about parameterized queries but I don't know what I'm doing wrong here.
con.OpenConnection();
using (con.connection)
{
String query = "SELECT * FROM tblUser WHERE Username = #Username and Password = #Password";
try
{
MySqlCommand cmd = new MySqlCommand(query, con.connection);
cmd.Parameters.Add("#Username", MySqlDbType.VarChar).Value = txtUsername.Text;
cmd.Parameters.Add("#Password", MySqlDbType.VarChar).Value = txtPassword.Text;
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
MessageBox.Show("Invalid user credentials.");
}
else
{
//Do stuff
}
}
catch (MySqlException mse)
{
MessageBox.Show(mse.Message);
}
finally
{
con.CloseConnection();
}
Not sure why it is not working but if you use AddWithValue, it will work. Something like this
cmd.Parameters.AddWithValue("#Username", txtUsername.Text);
cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
Change your code so that it's calls a method, when you click on a Button, pass the Username and Password variable into this Method. Create a AutoProperty for UserName and Password at the Class Level
private DataTable PopulateSomeDatatSet(DataSet aDataset, string UserName, string Password)
{
var query = "SELECT * FROM tblUser WHERE Username = #Username and Password = #Password";
MySqlDataAdapter sda;
using (SqlConnection connStr = new SqlConnection(ConnString)) //replace with your ConnectionString Variable
{
using (MySqlCommand cmd = new MySqlCommand(query, connStr))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#Username", MySqlDbType.VarChar).Value = UserName;
cmd.Parameters.Add("#Password", MySqlDbType.VarChar).Value = Password;
sda = new MySqlDataAdapter(cmd);
new MySqlDataAdapter(cmd).Fill(aDataset);
}
}
((IDisposable)sda).Dispose();
return aDataset.Tables[0];
}
In an existing codebase there is hardcoded SQL and I want to avoid SQL injection.
The below code uses SqlCommand together with SqlParameters. The query does not return any data. However, when I remove the parameters the query returns the correct results.
How can I use SqlParameters with a SELECT statement?
string atUsername = "#username"; //does not work
//string atUsername = "Demo1"; //THIS WORKS
string atPassword = "#password"; //does not work
//string atPassword = "222"; //THIS WORKS
string sql = #"SELECT userId, userName, password, status, roleId, vendorId
FROM users
WHERE username = '" + atUsername + "' AND password = '" + atPassword + "'";
SqlCommand cmd = new SqlCommand(sql);
cmd.Parameters.Add(atUsername, SqlDbType.NVarChar, 20);
cmd.Parameters[atUsername].Value = "Demo1";
//cmd.Parameters.AddWithValue //also does not work
cmd.Parameters.Add(atPassword, SqlDbType.NVarChar, 20);
cmd.Parameters[atPassword].Value = "222";
//cmd.Parameters.AddWithValue //also does not work
SqlConnection conn = new SqlConnection(connStr);
cmd.Connection = conn;
conn.Open();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
Console.WriteLine(dt.Rows != null);
if (dt.Rows != null)
{
Console.WriteLine(dt.Rows.Count);
}
conn.Close();
conn.Dispose();
I have also unsuccessfully tried alternatives using
SqlCommand.ExecuteReader and SqlDataReader
IDisposable pattern
Replace cmd.Parameters.Add(atUsername with
SqlParameter pUsername = new SqlParameter();
pUsername.ParameterName = atUsername;
pUsername.Value = "Demo1";
cmd.Parameters.Add(pUsername);"
PS. I've heard of EntityFramework but I cannot use EF in this case (long story).
The root of your problem is that you use variable names inside string literal:
WHERE username = '#username' AND password = '#password'
So they are not treated as variable names by sql server. Instead you are searching for user with name "#username" and password "#password". Correct way is:
WHERE username = #username AND password = #password
I have created one method in data Access class to select data from database with parameter. I just want to use parameterized query.
Method Is :
public DataTable executeSelectQuery(String _query, SqlParameter[] sqlParameter)
{
SqlCommand myCommand = new SqlCommand();
DataTable dataTable = new DataTable();
dataTable = null;
DataSet ds = new DataSet();
try
{
myCommand.Connection = openConnection();
myCommand.CommandText = _query;
myCommand.Parameters.AddRange(sqlParameter);
myCommand.ExecuteNonQuery();
myAdapter.SelectCommand = myCommand;
myAdapter.Fill(ds);
dataTable = ds.Tables[0];
}
catch (SqlException e)
{
return null;
}
finally
{
myCommand.Connection = CloseConnection();
}
return dataTable;
}
but I can't understand how to use this method to fetch data and how to pass parameter?
My query may be "select password from tblUsers where email=#email" How to pass #email at business layer?
How to make method in data access class for getting Scalar value?
public string getpasswrd(string unm)
{
con.Open();
string cpaswrd;
cmd1 = new SqlCommand("select password from tbl_login where username='" + unm + "'", con);
cpaswrd = (String)cmd1.ExecuteScalar();
con.Close();
return cpaswrd;
}
SqlParameter param;
cmd1 = new SqlCommand("select password from tbl_login where username=#username, con);
param = new SqlParameter("#username", SqlDbType.VarChar);
param.Direction = ParameterDirection.Input;
param.Value = unm;
cmd1.Parameters.Add(param);
cpaswrd = cmd1.ExecuteScalar().ToString();
You just need to use the same name in the sql parameter:
new SqlParameter("email", "myemail#gmail.com")
I am trying to execute a stored procedure in a SqlCommand in C#.
This is the code in C#:
string s = ConfigurationManager.ConnectionStrings["connection"].ToString();
SqlConnection conn = new SqlConnection(s);
conn.Open();
SqlCommand cmd = new SqlCommand("Signup1", conn);
cmd.CommandType = CommandType.StoredProcedure;
string password = TextBox2.Text;
cmd.Parameters.Add(new SqlParameter("#email", email));
SqlParameter pass = cmd.Parameters.Add("#password", SqlDbType.VarChar, 50);
pass.Value = password;
SqlParameter usertype = cmd.Parameters.Add("#usrtype", SqlDbType.VarChar, 50);
usertype.Value =usertype.Value;
cmd.ExecuteNonQuery();
conn.Close();
This is the stored procedure:
Create Proc Signup1
#email varchar(20),
#password Varchar(24),
#usrtype Varchar(30)
as
Insert into Members(email, password)
Values(#email, #password)
if #usrtype = 'Normal User'
begin
Insert into Normal_Users(email)
Values(#email)
end
else if #usrtype = 'Development Team'
begin
Insert into Development_Eeams(email)
Values(#email)
end
else if #usrtype = 'Verified Reviewer'
begin
Insert into Verified_reviewers(email)
Values(#email)
end
else
raiserror('Invalid type',16,1)
When I execute the command I get this error
Procedure or function 'Signup1' expects parameter '#password', which was not supplied.
Though I did gave the procedure the value of the parameter, what is the solution? Thanks
string email = //where are you getting the email address
string password = TextBox2.Text;
string s = ConfigurationManager.ConnectionStrings["connection"].ToString();
using (SqlConnection connStr new SqlConnection(s);
using (SqlCommand cmd = new SqlCommand("Signup1", connStr))
{
c.Open();
command.Parameters.Add(new SqlParameter("#email", SqlDbType.VarChar) { Value = email });
command.Parameters.Add(new SqlParameter("#password", SqlDbType.VarChar) { Value = password });
command.Parameters.Add(new SqlParameter("#usrtype", SqlDbType.VarChar) { Value = userType }); //Where are you assigning userType
cmd.ExecuteNonQuery();
}
if the top example is to complicated then you can use the Parameters.AddWithValue Function and let the DB Server handle resolving the datatype for example
string email = //where are you getting the email address
string password = TextBox2.Text;
string s = ConfigurationManager.ConnectionStrings["connection"].ToString();
using (SqlConnection connStr new SqlConnection(s);
using (SqlCommand cmd = new SqlCommand("Signup1", connStr))
{
c.Open();
command.Parameters.AddWithValue("#email", email);
command.Parameters.AddWithValue"#password", password);
command.Parameters.AddWithValue("#usrtype", userType); //Where are you assigning userType
cmd.ExecuteNonQuery();
}