SQL Invalid Column name detection from Query - c#

I've tried running the code and I have no idea what's wrong with the query. Because it keeps saying invalid column name, when I'm trying to retrieve the data from that column instead. The column name matches the one in the DB. It's well connected because it's connected to a login form where it detects the other given password and name. I'm using based on a search textbox.
private void btnSearch_Click(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ToString());
try
{
cnn.Open();
SqlCommand command = new SqlCommand();
command.Connection = cnn;
string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
---[Converting String from db /Insert to textboxes]---
}
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
}

You need to wrap the username text in quotes.
Your emitted sql script is gonna look like:
SELECT *FROM AffiliatedRegister WHERE Username=InputUserName
So SQL is trying to compare the column Username to the column InputUsername.
Once you wrap the user name in quotes, it would be:
SELECT *FROM AffiliatedRegister WHERE Username='InputUserName'

Your statement erred because you did not wrap your string in quotes so Sql interpeted it as on object and not a string. That being said there you should use parameters and not string concatenation.
Use parameters
Wrap your SqlConnection in a using block
You should specify the column order in the SELECT statement, do not use *.
Do not swallow an Exception unless you know how to recover from it
Update code
private void btnSearch_Click(object sender, EventArgs e)
{
// use ConnectionString property
// wrap in using block
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ConnectionString))
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = cnn;
// use parameters
// avoid *, specify columns instead
string query = "SELECT * FROM AffiliatedRegister WHERE Username= #userName";
command.CommandText = query;
// use parameters, I assumed the parameter type and length - it should be updated to the type and length specified in your table schema
command.Parameters.Add(new SqlParameter("#userName", SqlDbType.VarChar, 200) {Value = txtUser.Text });
// open as late as possible
cnn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ---[Converting String from db / Insert to textboxes]-- -
}
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
// do not swallow the exception unless you know how to recover from it
throw;
}
}
}

Well first of all your query is very dangerous so please don't use it for production purpose.
Now what you need to do :-
In your query you need single quotes around the txtUser.Text.
Like this :-
"SELECT *FROM AffiliatedRegister WHERE Username='" + txtUser.Text
+ "'";
Resulting query : SELECT *FROM AffiliatedRegister WHERE Username = 'txtUser.Text';
You can also put double quotes like :-
...Username=\"" + txtUser.Text + "\"";
its complicated ;-) Earlier one is better for the reading purpose.
Why it did not run?
Because all values except integers must be passed inside single or double quotes in a query. Like :-
SELECT * FROM TABLE_NAME WHERE TABLE_NAME.COLUMN_NAME = "VALUE";
Now one very important thing please don't use these kinds of queries for production purpose. I guess you are in development phase so answering this question is not gonna ruin your life ...!!!

You can try to replace the your string: string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
to: string query = "SELECT <yourcolumn> FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
I believe it is necessary to specify the column name.
Best regards

Related

Else statement fails to work within a while loop

Below is my code to connect to the database using MySqlDataReader. Now the if statement is working fine but the else statement doesnt. When i use the debug function in VS it kept skipping the else statement and jump to the reader.Close();.
Any idea. Thanks
private void db()
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
MySqlConnection connection = new MySqlConnection(constr);
connection.Open();
MySqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM user Where user_id ='" + Userid.Text + "'" + "And password='" + Password.Text + "'";
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
{
Label1.Text = reader["user_id"].ToString();
}
else
{
Label1.Text = "nodata";
}
reader.Close();
}
}
First of all: Don't use string concatenation for building queries, but use parameterized queries!
As for your problem: I assume this query will only return either 1 or 0 rows, so you don't need the loop but just check
if (reader.Read()) {
//...
}
Using SELECT * with column indexes is potentially dangerous, because you may not know what the "first" column returned is. I would suggest name your desired columns in the query
SELECT user_id, user_name ... FROM ...
What is the value of the first column returned? I assume, it's the user_id. Thus, this can never fulfill the condition IsDBNull(0) because user_id is your matching criterion in the WHERE clause. If your WHERE clause does not match any record in the table, reader.Read() will already fail, so you'll never get to your else branch.
Furthermore, I would suggest a using clause, which will dispose the reader automatically, so you don't have to care about closing it.
command.CommandText = "SELECT user_id, foo, bar from user where user_id = #userid and password = #password";
command.Parameters.AddWithValue("#user_id", UserId.Text);
command.Parameters.AddWithValue("#password", Passowrd.Text);
using (MySqlDataReader reader = command.ExecuteReader()) {
if (reader.Read()) {
Label1.Text = reader["user_id"].ToString();
} else {
Label1.Text ="nodata";
}
}

Database values in textbox if select Combobox

I am trying to write code for a form that writes to a sql table. I use data form other tables to complete the form (along with user input). I have a checkbox that options the source of a combobox (ddDefect) - it is based on one of two sql LIKE queries - so, the combox will display the results of one LIKE query if the checkbox = true and the other LIKE query if it = false. This part works great. Problem is; I cannot seem to figure out how to take the selected item in the combobox and display text form another column in my textbox (txtNcm)
I have tried various ways and this seems to make the most sense to me (though I am only a beginner and clueless) but I get nothing in my text box.
here is the code that I have been trying:
private void ddDefect_SelectedIndexChanged(object sender, EventArgs e)
{
string constring = "Data Source=TS-ERP01;Initial Catalog=Touchstn02;Integrated Security=True";
string Query = "select * from Defect_Codes Where DESCP_91= ' " + ddDefect.Text + " ';";
SqlConnection conDataBase = new SqlConnection(constring);
SqlCommand cmdDataBase = new SqlCommand(Query, conDataBase);
SqlDataReader myReader;
try
{
conDataBase.Open();
myReader = cmdDataBase.ExecuteReader();
while (myReader.Read())
{
string sDEF = myReader["DEFECT_91"] as String;
txtNcm.Text = sDEF;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Your sql command text contains spaces before and after the value of ddDefect.
....DESCP_91= ' " + ddDefect.Text + " ';";
^ ^
These spaces will be passed as is to the database engine and, unless you have a very specific datatype in the database column (CHAR/NCHAR) with these exact spaces around the values in the column, the command will never find any data.
But this is not the end of your problems. Concatenating strings in this way is a well known source of problems. What if the ddDefect.Text contains a single quote? Another syntax error. Then there is the problem of Sql Injection vulnerability, a very serious security problem.
So you should use a parameterized query like this
string constring = "Data Source=TS-ERP01;Initial Catalog=Touchstn02;Integrated Security=True";
string Query = "select * from Defect_Codes Where DESCP_91= #ds91";
using(SqlConnection conDataBase = new SqlConnection(constring))
using(SqlCommand cmdDataBase = new SqlCommand(Query, conDataBase))
{
try
{
conDataBase.Open();
cmdDataBase.Parameters.Add("#ds91", SqlDbType.NVarChar).Value = ddDefect.Text;
using(SqlDataReader myReader = cmdDataBase.ExecuteReader())
{
while (myReader.Read())
{
string sDEF = myReader["DEFECT_91"].ToString();
txtNcm.Text = sDEF;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Notice also that SqlConnection, SqlCommand and SqlDataReader are disposable objects and thus you should try to always use the using statement to be certain that these objects free the unmanaged resources acquired during they work (particularly the SqlConnection object)

C# App SQL Query

Okay basically I have a SQL Server database that has details in it.
Column names: Student_Id, Student_name, Unit_number, Unit_grade
I would like to query this database using two textboxes where you enter the id and unit_number and it will return the results in a message box when a button is clicked.
Where the question marks in the code are is where I am unsure of how to display a message box with the result. Unless this is completely the wrong way of doing things, I am only starting out with SQL in C#
I shouldn't be prone to SQL Injection using parameters as far as I know?
try
{
string str = "SELECT * FROM Students WHERE (Student_Id, Unit_number LIKE '%' + #search + '%')";
SqlCommand command = new SqlCommand(str, connect);
command.Parameters.Add("#search", SqlDbType.NVarChar).Value = textBox1.Text;
command.Parameters.Add("#search", SqlDbType.NVarChar).Value = textBox2.Text;
connect.Open();
command.ExecuteNonQuery();
SqlDataAdapter dataAdapt = new SqlDataAdapter();
dataAdapt.SelectCommand = command;
DataSet dataSet = new DataSet();
dataAdapt.Fill(dataSet, "Student_Id, Unit_number");
//?
//?
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Your SQL is wrong in that your WHERE clause is syntactically incorrect. You probably want something like:
string str = "SELECT * FROM Students WHERE Student_ID = #id AND " +
"Unit_number LIKE #search";
This assumes that Student_ID is a text type. The syntax would be slightly different if it was a number.
You are trying to add the same parameter to the query twice, which you won't want. Instead you'd want two parameters to match with the new SQL definition:
command.Parameters.Add("id", SqlDbType.NVarChar).Value =
textBox1.Text;
command.Parameters.Add("search", SqlDbType.NVarChar).Value =
"%" + textBox2.Text + "%";
Running ExecuteNonQuery on the SqlCommand object doesn't do much for you as it is a query and you're not asking for the result back.
If you're only expecting one table back from your query, you'd probably be better off with a DataTable rather than a DataSet (the DataSet can contain many tables which is overkill for what you need).
try
{
string str = "SELECT * FROM Students WHERE Student_Id = #id AND " +
"Unit_number LIKE #search";
connect.Open();
SqlCommand command = new SqlCommand(str, connect);
command.Parameters.Add("id", SqlDbType.NVarChar).Value =
textBox1.Text;
command.Parameters.Add("search", SqlDbType.NVarChar).Value =
"%" + textBox2.Text + "%";
SqlDataAdapter dataAdapt = new SqlDataAdapter();
dataAdapt.SelectCommand = command;
DataTable dataTable = new DataTable();
dataAdapt.Fill(dataTable);
// At this point you should have a DataTable with some results in it.
// This is not going to be the best way of displaying data,
// but it should show you _something_
// It just iterates through the rows showing the columns
// which you've shown as being in your data.
foreach (DataRow dr in dataTable.Rows)
{
MessageBox.Show(String.Format("{0} - {1} - {2} - {3}",
dr["Student_Id"], dr["Student_name"],
dr["Unit_number"], dr["Unit_grade"]));
}
connect.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
EDITED to change the parameter handling as it didn't quite do what was needed. The % symbols are not part of the parameter rather than the SQL string.

SQL query from C#

I am trying to query SQL Server database from C#
I have class
Class_A
{
public fetch((string name, string last_name))
{
SqlConnection conn = null;
double val = 0;
string server = "123.444.22.sss";
string dbase = "xyz";
string userid = "cnsk";
string password = "xxxxxx";
string connection = "Data Source=" + server + ";Initial Catalog=" + dbase
+ ";User ID=" + userid + ";Password=" + password;
conn = new SqlConnection(connection);
try
{
conn.Open();
}
catch(Exception)
{
string e = "Database error contact administrator";
MessageBox.Show(e, "Error!");
}
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from table where NAME"
+ " = name and LAST_NAME = last_name", conn);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
//do something
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return (0);
}
}
There is a problem in my query.
When I give normal query "select * from table" --- this gives me perfect results.
But when I try to give where condition it gives me error. Any suggestions, to fix this?
Thanks.
Use a parameterised query, and more usings, and stop with the generic exceptions.
something like this where somName and SomeLastName are the values that you wan t to query for.
String sql = "Select * From SomeTable Where [Name] = #Name and [Last_Name] = #LastName";
try
{
using(SqlConnection conn = new SqlConnection(connection))
{
conn.Open();
using( SqlCommand command = new SqlCommand(sql,conn))
{
command.Parameters.Add(new SqlParameter("Name", DbType.String,someName));
command.Parameters.Add(new SqlParameter("LastName", DbType.String,someLastName));
using(IDataReader myReader = command.ExecuteReader())
{
while (myReader.Read())
{
//do something
}
}
}
}
return 0; // Huh?
}
catch(SqlException sex)
{
Console.Writeline(String.Format("Error - {0}\r\n{1}",sex.Message, sex.StackTace))
}
NB not checked might be a silly in it
⚠️ WARNING This answer contains a SQL injection security vulnerability. Do not use it. Consider using a parameterized query instead, as described in some of the other answers to this question (e.g. Tony Hopkinson's answer).
Try adding quotes around the values in the where clause like this:
select * from table where NAME = 'name' and LAST_NAME = 'last_name'
In your case where you are using variables you need to add the quotes and then concatenate the values of the variables into the string. Or you could use String.Format like this:
var sql = String.Format("select * from table where [NAME] = '{0}' and LAST_NAME = '{1}'", name, last_name);
SqlCommand myCommand = new SqlCommand(sql);
Try
select * from table where NAME = 'name' and LAST_NAME = 'last_name'
instead of
select * from table where NAME = name and LAST_NAME = last_name
Edit:
If name and last_name are your parameters then try this:
SqlCommand myCommand = new SqlCommand("select * from table where NAME = #name and LAST_NAME = #last_name", conn);
myCommand.Parameters.AddWithValue( "#name", name );
myCommand.Parameters.AddWithValue( "#last_name", last_name );
Using parameterized commands means that you are invulnerable to a potential huge security hole - sql injection which is possible when command text is manually concatenated.
The text needs to be quoted as others have said--but that's not really the right answer here. Even without malice you're going to run into trouble with the Irish here, look what happens when you try to look for Mr. O'Neill. Use parameters instead.

MySQL Query with MySQLParameters in C#

I am currently developing an Application for Windows using MySQL and C#. I have the following code:
private void cboCategories_SelectedIndexChanged(object sender, EventArgs e)
{
DatabaseWork dbase = new DatabaseWork();
try
{
dbase.openConnection();
string query = "SELECT * FROM budgetcategory WHERE budc_userID=#userID AND budc_category=#category";
MySqlCommand cmd = new MySqlCommand("", dbase.conn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#userID", userID);
cmd.Parameters.AddWithValue("#category", cboCategories.SelectedItem.ToString());
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
setCatId(reader.GetString("budc_category_id"));
Console.WriteLine("Category ID: " + getCatId());
}
}
catch (MySqlException ex)
{
Console.WriteLine("Cat Error: " + ex.Message);
}
finally
{
dbase.closeConnection();
}
}
For some reason when I debug the code it never goes into the while loop as if nothing was ever returned from the database. But I know there should be something in there.
Thanks for any help you can provide
Just trying to help you debug a little:
Try reducing these three lines:
string query = "SELECT * FROM budgetcategory WHERE budc_userID=#userID AND budc_category=#category";
MySqlCommand cmd = new MySqlCommand("", dbase.conn);
cmd.CommandText = query;
to just:
string query = "SELECT * FROM budgetcategory WHERE budc_userID=#userID AND budc_category=#category";
MySqlCommand cmd = new MySqlCommand(query, dbase.conn);
Now put a breakpoint on those lines that add the parameters, and make sure that userID and especially cboCategories.SelectedItem.ToString() have the values that you expect.
Also, can you confirm that no exception is thrown?
If this is not the case run the query, with those exact values directly against the database and confirm that something is returned.

Categories

Resources