I'm a beginner in SQL and c#. I'm trying to create a system that will lead the user to eligibility form if they have not done it before, but an error that says invalid column name keeps popping.
string query = "select * from Eligibility where Name = " + textBox1.Text;
sql.Open();
SqlCommand cmd = new SqlCommand(query, sql);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
label6.Text = (dr["name"].ToString());
}
sql.Dispose();
if (label6.Text == textBox1.Text)
{
this.Hide();
UserHomeView uhv = new UserHomeView();
uhv.Show();
}
else
{
this.Hide();
Eligibility eli = new Eligibility();
eli.Show();
}
You missed the single quotation
string query = "select * from Eligibility where Name = '" + textBox1.Text + "'";
Even so, there is some serious problem with the above code. This can cause a serious sql injection problem for you Check wikipedia entry on this
It's better to use the add parameters function which will sanitize the input and make it safe for you to execute the query.
The best solution would be something like this
string query = "select * from Eligibility where Name = #Name";
sql.Open();
SqlCommand cmd = new SqlCommand(query, sql);
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = textBox1.Text;
This way, your query will be injection safe.
Just to build on what others have said:
Once you're comfy with doing things this way check out Stored Procedures.
Stored Procedures lets you save the query in the database and all you do on the c# side is call the Stored Procedure and add the required parameters.
These tend to be a better way of doing this as you can then learn about how to restrict access to your database for only certain users and also it means the Query itself is in an environment that will check for mistakes as well.
This is a good article as an introduction to them:
http://www.sqlservertutorial.net/sql-server-stored-procedures/
You can use Parameters of SqlCommand, like this:
string query = "select * from Eligibility where Name = #Name";
sql.Open();
SqlCommand cmd = new SqlCommand(query, sql);
cmd.Parameters.Add("#Name", SqlDbType.Text);
cmd.Parameters["#Name"].Value = textBox1.Text;
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
label6.Text = (dr["name"].ToString());
}
sql.Dispose();
if (label6.Text == textBox1.Text)
{
this.Hide();
UserHomeView uhv = new UserHomeView();
uhv.Show();
}
else
{
this.Hide();
Eligibility eli = new Eligibility();
eli.Show();
}
Related
I've seen this question asked a couple times but I couldn't find a good answer. I've been stuck for hours on this.
Basically I have usernames saved in a database and when a new user registers I want to check if his username is available - and if it is available add him to the database. And they register through a textbox called FName. The table is called Users.
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand("SELECT FName FROM Users WHERE FName = ????? usernames????? ", con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader["text"].ToString());
}
How can I fix this code?
"SELECT FName FROM Users WHERE FName = #paramUsername"
and then you insert the parameter into the cmd like so:
cmd.Parameters.Add("paramUsername", System.Data.SqlDbType.VarChar);
cmd.Parameters["paramUsername"].Value = "Theusernameyouarelookingfor";
Check this out:
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
string validationQuery = "SELECT * FROM Users WHERE FName = #name";
SqlCommand validationCommand = new SqlCommand(validationQuery, connection);
validationCommand.Parameters.Add("#name", SqlDbType.VarChar).Value = loginUserSelected;
connection.Open();
SqlDataReader validationReader = validationCommand.ExecuteReader(CommandBehavior.CloseConnection);
if (!validationReader.Read())
{
string insertQuery = "INSERT INTO Users (FName) VALUES (#name)";
SqlCommand insertCommand = new SqlCommand(insertQuery, connection);
insertCommand.Parameters.Add("#name", SqlDbType.VarChar).Value = loginUserSelected;
connection.Open();
insertCommand.ExecuteNonQuery();
insertCommand.Dispose();
connection.Close();
}
else
{
//Uh oh, username already taken
}
validationReader.Close();
validationCommand.Dispose();
Things to note:
Use parameters, avoid concatenating strings because it's a security vulnerability
Always Close and Dispose your ADO objects
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE(ID= '" +
txtStudentIDnumber.Text + "')";
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
this.tableAdapterManager.UpdateAll(csharrpfinalprojectDataSet);
mydatabase.Close();
MessageBox.Show("Student Record Deleted.", "deleting record...");
In your command text you need to remove single quotes (') around the txtStudentIDnumber.Text as it appears ID is of type integer and you are passing it as string. Following should fix the error.
system.CommandText = "DELETE FROM Student WHERE(ID= " + txtStudentIDnumber.Text + ")";
EDIT: With respect to #mdb comments, you should always use Parameters in your query so that you can avoid SQL Injection. Consider the following:
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE ID = ?";
OleDbParameter parameter = new OleDbParameter("ID", txtStudentIDnumber.Text);
system.Parameters.Add(parameter);
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
OleDbCommand system = new OleDbCommand();
system.CommandType = CommandType.Text;
system.CommandText = "DELETE FROM Student WHERE ID=#ID";
system.Parameters.AddWithValue("#ID", txtStudentIDnumber.Text);
system.Connection = mydatabase;
mydatabase.Open();
system.ExecuteNonQuery();
dataGridView1.Update();
this.tableAdapterManager.UpdateAll(csharrpfinalprojectDataSet);
mydatabase.Close();
MessageBox.Show("Student Record Deleted.", "deleting record...");
What will happen when user input for txtStudentIDNumber is,
1 or 1=1
In that case hardcoded SQL string will be,
DELETE FROM Student WHERE(ID=1 or 1=1)
So prefer parameterized sql statement instead of hard-coded string.
using(OleDbConnection cn=new OleDbConnection(cnStr))
{
using(OleDbCommand cmd=new OleDbCommand())
{
cmd.CommandText="DELETE FROM Student WHERE ID=#ID";
cmd.Connection=cn;
cmd.Parameters.Add("#ID",SqlDbType.Int).Value=txtStudentIDnumber.Text;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
}
I am developing this website in ASP.NET and using C#. I am Getting the error that :Use of unassigned variable usn. The database is also not empty.
My code is:
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection();
SqlCommand cm = new SqlCommand();
SqlDataReader dr;
cn.ConnectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Vijaylaxmi\Desktop\TrainReserveold\App_Data\Database.mdf;Integrated Security=True;User Instance=True";
cn.Open();
cm.Connection = cn;
String usn;
cm.CommandText = "Select UserName from User where UserName='" + TextBox1.Text + "'";
dr = cm.ExecuteReader();
while (dr.Read())
{
usn = dr.GetString(0);
}
if (String.Compare(usn, TextBox1.Text) != 0)
{
Response.Write("Invalid user name... try again");
TextBox1.Text = "";
TextBox2.Text = "";
TextBox1.Focus();
}
Response.Write("user valid now");
}
Several problems I see here. In specific response to your question, you want to replace this:
dr = cm.ExecuteReader();
while(dr.Read())
{
usn = dr.GetString(0);
}
with this:
usn = cm.ExecuteScalar().ToString();
Be sure to check for DBNull first, just in case.
More generally, you want to
a) Parameterize your SQL (or, better, use a stored proc) instead of using raw input. This will protect you from SQL Injection attacks.
b) Not include your connection string directly in code. Put it in a config file. Most certainly don't post it on the internet.
assing the usn string up top as
string usn = string.empty; then go from there
//create a Stored Procedure and put your Select Statement in there.. to avoid Sql Injection
cmd.CommandText = "name of your stored proc";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
I would also read my sql connectiong string from a web.config or app.config depending on the type of application you are running.
change your cm.CommandText = "Select UserName from User where UserName=
to
cm.CommandText = string.Format("Select UserName from User where UserName= '{0}'",Textbox1.Text);
In my code below, the cmdquery works but the hrquery does not. How do I get another query to populate a grid view? Do I need to establish a new connection or use the same connection? Can you guys help me? I'm new to C# and asp. Here's some spaghetti code I put together. It may all be wrong so if you have a better way of doing this feel free to share.
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
while (read.Read())
{
xHoursGridView.DataSource = hrquery;
xHoursGridView.DataBind();
}
}
conn.Close();
Your data access code should generally look like this:
string sql = "SELECT * FROM Employee e INNER JOIN Clock_History c ON c.Badge = e.Badge WHERE e.Badge = #BadgeID";
using (var cn = new OracleConnection("your connection string here"))
using (var cmd = new OracleCommand(sql, cn))
{
cmd.Parameters.Add("#BadgeID", OracleDbType.Int).Value = Badge;
cn.Open();
xHoursGridView.DataSource = cmd.ExecuteReader();
xHoursGridView.DataBind();
}
Note that this is just the general template. You'll want to tweak it some for your exact needs. The important things to take from this are the using blocks to properly create and dispose your connection object and the parameter to protect against sql injection.
As for the connection question, there are exceptions but you can typically only use a connection for one active result set at a time. So you could reuse your same conn object from your original code, but only after you've completely finished with it from the previous command. It is also okay to open up two connections if you need them. The best option, though, is to combine related queries into single sql statement when possible.
I'm not even going to get into how you should be using usings and methods :p
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
//What's this next line? Setting the datasource automatically
// moves through the data.
//while (read.Read())
//{
//I changed this to "read", which is the
//datareader you just created.
xHoursGridView.DataSource = read;
xHoursGridView.DataBind();
//}
}
conn.Close();
I have the following code in my btn_click event:
Sqlconnection con = new Sqlconnection("server=.;database=bss;user id=ab;pwd=ab");
con.open();
SqlCommand cmd = new Sqlcommand("select * from login where username='"
+ txt4name.Text + "' and pwd='" + txt4pwd.Text + "'", con);
SqlDataReader reader = cmd.execute Reader();
Where login is the table and username and pwd are its fields. After this code all the values are stored in the reader object. I want to store username and pwd in the separate variables.
How can I accomplish this?
In general, when accessing your DB, you should be using something similar to this instead to eliminate SQL injection vulnerabilities:
using (SqlCommand myCommand = new SqlCommand("SELECT * FROM USERS WHERE USERNAME=#username AND PASSWORD=HASHBYTES('SHA1', #password)", myConnection))
{
myCommand.Parameters.AddWithValue("#username", user);
myCommand.Parameters.AddWithValue("#password", pass);
myConnection.Open();
SqlDataReader myReader = myCommand.ExecuteReader())
...................
}
But more realistically to store credentials, you should be using something like the Membership system instead of rolling your own.
You're running a huge risk of sql injection with that. Use SQL Parameters for values into SqlCommands.
If you mean c# variables, and if you want to get them from db, just do this:
SqlDataReader reader = cmd.execute Reader();
if (reader.Read())
{
string username = reader["username"];
string pwd = reader["password"];
}
While you are at it, parameterize your query and prevent sql injection:
SqlCommand cmd = new Sqlcommand("select * from login where username=#username and pwd=#pwd", con);
cmd.Parameters.AddWithValue("#username", txt4name.Text);
cmd.Parameters.AddWithValue("#pwd", txt4pwd.Text);
Definitely heed the advice about SQL injection but here is the answer to your question:
String username;
String pwd;
int columnIndex = reader.GetOrdinal("username");
if (!dataReader.IsDBNull(columnIndex))
{
username = dataReader.GetString(columnIndex);
}
columnIndex = reader.GetOrdinal("pwd");
if (!dataReader.IsDBNull(columnIndex))
{
pwd = dataReader.GetString(columnIndex);
}
string userName = txt4name.Text;
string password = txt4pwd.Text;
Is that really what you want? Just to get that data into variables?
You really need to use parameterized SQL. There's an example here
Furthermore, your question doesn't really make sense; you want the username and password in seperate variables? they already are seperate in your example. If you are unable to assign them to strings I suggest following some tutorials.
Another approach is to load the reader results into a DataTable like so:
DataTable Result = new DataTable();
Result.Load(reader);
If your login table only contains two columns (userName and password) that are unique you end up with Result containing only one row with the information. You can then get the column values from each column:
string userName = Result.Rows[0].Field<string>("userName");
string password = Result.Rows[0].Field<string>("pwd");
private void but_login_Click(object sender, EventArgs e)
{
string cn = "Data Source=.;Initial Catalog=mvrdatabase;Integrated Security=True";
SqlConnection con = new SqlConnection(cn);
con.Open();
SqlCommand cmd = new SqlCommand("select count (*) from logintable where username ='" + txt_uname.Text + "'and password='" + txt_pass.Text + "'", con);
int i = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
if (i == 1)
{
Form2 f2 = new Form2();
MessageBox.Show("User login successfully........");
this.Hide();
f2.Show();
}
else
{
MessageBox.Show("INCORRECT USERID AND PASSWORD", "Error");
}
}
You can usually find basic usage examples on MSDN, like this one for SqlDataReader.