I am trying to pass both Column name and the Value to be checked in the code at runtime. However I am getting an "Invalid Column Name " exception.
The code is as follows :
string temp = TextBox1.Text.ToString();
SqlConnection con = new SqlConnection("data source=.\\SQLEXPRESS;AttachDbFilename=C:\\Users\\Sagar\\Documents\\Test.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
SqlCommand com = new SqlCommand("Select * from Employee Where #field = Sagar", con);
com.Parameters.AddWithValue("#field", DropDownList1.SelectedValue.ToString());
//com.Parameters.AddWithValue("#value", temp);
SqlDataAdapter da = new SqlDataAdapter(com);
con.Open();
SqlDataReader reader = com.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
The message says that there is no column named 'Sagar' in the table. Is there such a column? Things would be easier if you showed us the table schema instead of having us guess from the error message.
It is not possible to parameterize column names using SqlParameter in C#. This has been discussed here multiple times.
What's happening with the query the way Vidhya Sagar Reddy is doing it, is the following. He assumes that the following query
Select * from Employee Where #field = 'Sagar'
is replaced by this query when setting "Name" as the value for the #field parameter:
Select * from Employee Where Name = 'Sagar'
This, however, is wrong! What's happening is that the #field parameter is replaced as follows:
Select * from Employee Where 'Name' = 'Sagar'
This returns no results, as the WHERE clause is always false. Of course, if you use the field name Sagar, this akways returns true, as the statement then reads:
Select * from Employee Where 'Sagar' = 'Sagar'
Here's an easy test to prove what I've said above. Use the following statement to set the #field parameter (supposed, there's no column named eirghoerihgoh in the table):
com.Parameters.AddWithValue("#field", "eirghoerihgoh");
If the query executes correctly (maybe not returning any results), the above is correct. If it was not correct, an exception should be thrown about the eirghoerihgoh column not being present.
Thank you Vidhya Sagar Reddy for proving my point. By using this line
com.Parameters.AddWithValue("#field", "eirghoerihgoh");
you say you didn't get any results, but you also didn't get an exception. However, if the statement really had been changed to
Select * from Employee Where eirghoerihgoh = 'Sagar'
there had to be an exception saying that there was no column named eirghoerihgoh. As you didn't get that exception, there's only one possible explanation: The statement was changed to
Select * from Employee Where 'eirghoerihgoh' = 'Sagar'
and this executes, but doesn't return results, as the condition is always false.
Instead you can make your code this way, which works perfectly:
"Select * from Employee Where "+DropDownList1.SelectedValue.ToString()+" =
'Sagar'" – Vidhya Sagar Reddy
The reason for that is quite simple, the value that are to be specified in SQL should be in single quotes and this is a simple mistake by the way..!!!!
SqlCommand com = new SqlCommand("Select * from Employee Where #field = 'Sagar'", con);
And even change the parameter to "field" in the following line and not "#field"..!!
com.Parameters.AddWithValue("field", DropDownList1.SelectedValue.ToString());
This is working..>!!!!
Related
I have this code:
SqlConnection Connection = new SqlConnection("data source=.;initial catalog=testdb;integrated security=sspi");
SqlCommand Command = new SqlCommand("select * from (select count(studentid) from student) as student", Connection);
Connection.Open();
Command.ExecuteNonQuery();
I expect the query comes from the user, so I need to filter it after the the select is written my way:
select * from (user query) as table
but it throws an error:
No column name was specified for column 1 of 'student'.
because some times columns must be aliased if it a function like count or avg
I need to use this way to filter the query after the user write it. Also I know where will not work after grouping and having must have an aggregation method at the SQL query...
Any ideas?
This should probably be a comment but I think the formatting here makes it clearer.
Logically there is no difference between
SELECT *
FROM ({query}) AS STUDENT
and
{query}
So what are you actually trying to do?
You just missing alias for count of students
select * from (select count(studentid) as CountOfStudents from student) as student
You have made some mistakes both in code and SQL syntax. The Error you receive is due to the fact that you have a confused query asking the count of the studednts without giving it the name, then you select this single value and try to give a name to a table... Besides, you use an ExecuteNonQuery that as its name tells executes some SQL on SQL server and does not retrieve anything, this kind of command is usually used to Execute statements to Insert or update data. The Correct code, is the following:
SqlConnection Connection = new SqlConnection("data source=.;initial
catalog=testdb;integrated security=sspi;persist security info=true");
SqlCommand Command = new SqlCommand("select count(studentid) AS StudentsNumber from student", Connection);
Connection.Open();
object result = Command.ExecuteScalar();
MessageBox.Show(result.ToString());
So I am trying to fetch a value from the database, selecting the row using WHERE INT.
conn = new MySqlConnection(DBdetails.connStr);
conn.Open();
query = "SELECT * FROM tables WHERE table=#tafel";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("#tafel", tafel);
cmd.ExecuteNonQuery();
However it wont pass 'cmd.ExecuteNonQuery()', it throws a error saying the syntax isnt right like: "near table=1", "near table=2"
I tried fetching a other one in the same table that is a var char and it worked perfectly.
Don't really see what I am doing wrong. The 'table' column is a int and 'tafel' is a int to.
Thanks!
Put your field name table in backticks (table is a reserved word in MySQL) :
query = "SELECT * FROM `tables` WHERE `table` = #tafel";
As others said, table is a reserved word in MySQL. You need to use quote with it like
query = "SELECT * FROM tables WHERE `table` = #tafel";
However, the best solution is to change the name to a nonreserved word.
Also use using statement to dispose your MySqlConnection and MySqlCommand like;
using(MySqlConnection conn = new MySqlConnection(DBdetails.connStr))
using(MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT * FROM tables WHERE `table` = #tafel";
cmd.Parameters.AddWithValue("#tafel", tafel);
conn.Open();
cmd.ExecuteNonQuery();
}
By the way, I don't understand why you use ExecuteNonQuery with SELECT statement. It just executes your query. It doesn't even return any value.
If you want to get the result of your query, you can use ExecuteReader method which returns SqlDataReader as your result rows.
Below is the code I have, I can't for the life of me work out what is wrong with the query.
I originally had the error "no value given for 1 or more parameters", which seems to have gone away (although again I don't even know why I was getting it).
The connection is opened prior to this code.
The parameter GVars.thisFY is a string = "FY13" - this table definitely exists.
The parameter GVars.currentDate is a DateTime = today.
Records definitely exist for this [Destination] and [Next Collection] range:
string sql;
OleDbDataAdapter adapter;
sql = "SELECT * FROM #CurFY WHERE [Destination] = #Destination AND [Next Collection] BETWEEN #NextCollectionA AND #NextCollectionB;";
// Create the command object
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
// Add values to the fields
cmd.Parameters.AddWithValue("#CurFY", GVars.thisFY);
cmd.Parameters.AddWithValue("#Destination", "Henwood");
cmd.Parameters.AddWithValue("#NextCollectionA", GVars.currentDate);
cmd.Parameters.AddWithValue("#NextCollectionB", GVars.currentDate.AddDays(1));
adapter = new OleDbDataAdapter(cmd.CommandText, conn);
try
{
adapter.Fill(ds);
GVars.bLblLastUpdate = DateTime.Now.ToString("HH:mm:ss");
}
catch (Exception ex)
{
}
EDIT:
I have changed the code to remove the table parameter as below, still getting the "no value given for 1 or more parameters" though which I can't pin down..
EDIT2: I removed the extra stuff so the post relates only to the original question, which has been answered. I will make a new question for my strange "no value given" error
You cannot parameterize queries with names of tables, views, or columns. Only data members can be parameterized.
You need to make your SQL dynamically, e.g. like this:
sql = string.Format(
"SELECT * FROM {0} WHERE [Destination] = #Destination AND [Next Collection] BETWEEN #NextCollectionA AND #NextCollectionB;"
, GVars.thisFY
);
This should be done only if GVars.thisFY is controlled by your code, e.g. comes from a pre-defined list or checked for absence of non-alphanumeric characters to avoid SQL injection attacks.
Try this one -
sql = Sring.Format(
"SELECT * FROM {0} WHERE [Destination] = #Destination AND [Next Collection] BETWEEN #NextCollectionA AND #NextCollectionB;",
GVars.thisFY
)
cmd.Parameters.AddWithValue("#Destination", "Henwood");
cmd.Parameters.AddWithValue("#NextCollectionA", GVars.currentDate);
cmd.Parameters.AddWithValue("#NextCollectionB", GVars.currentDate.AddDays(1));
I've got a function that stores temporary information generated for every user authenticated in the system. This 'session ID' is a string stored in a Sessions table, along the original ID of the user which authenticated and was given said session identifier.
The function to remove/deauthenticate/invalidate an existing session first checks if the user exists through another method implemented as follows:
int userId = 0;
SqlCeCommand cmd = new SqlCeCommand();
SqlCeParameterCollection sqlParams = cmd.Parameters;
sqlParams.AddWithValue("#User", userName);
cmd.Connection = this.conn;
cmd.CommandText = "SELECT Id FROM Users WHERE (Username = #User)";
userId = (int) cmd.ExecuteScalar()
cmd.Dispose();
Afterwards it tries to find an existing session for that user, which is to be removed (via a different method again):
SqlCeCommand cmd = new SqlCeCommand();
SqlCeParameterCollection sqlParams = cmd.Parameters;
sqlParams.AddWithValue("#SID", mysession);
sqlParams.AddWithValue("#UID", myuserid);
cmd.Connection = this.Connection;
cmd.CommandText = "SELECT Id FROM UserSessions WHERE (SessionID = #SID) AND (User_Id = #UID)";
int foo = cmd.ExecuteNonQuery();
...which fails. No exception is raised unfortunately. So I added an insecure equivalent using a non parametrized query string:
cmd.CommandText = String.Format("SELECT Id FROM UserSessions WHERE (SessionID = '{0}') AND (User_Id = {1})", mysession, myuserid);
cmd.Prepare();
int bar = cmd.ExecuteNonQuery();
Added a breakpoint, paused, copy pasted the query into the Visual Studio Query tool and voila, it indeed worked. But after continuing, that query in the code failed as well. I'm unable to find the culprit of this annoying issue since no exception is raised and everything seems correct. The data exists, the parameters are provided in proper types (string and int) and I'm out of things to check. The connection is open and so forth.
Any clues from anyone around? Thanks!
Update: Mea culpa, missed the fact that the function used ExecuteScalar until I modified it for testing. It does use ExecuteScalar and returns null, just in case.
You're using ExecuteNonQuery:
int foo = cmd.ExecuteNonQuery();
... but you're clearly trying to execute a query (a SELECT)! Use ExecuteScalar again, as you did in the first code, or ExecuteReader and look through the results appropriately. If you stick with ExecuteScalar, you should first check whether the result is null to indicate no results.
ExecuteNonQuery returns the number of rows affected by an UPDATE/INSERT/DELETE command - which is what it's intended for. I suspect it's returning -1 for you, as documented:
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers. For all other types of statements, the return value is -1. If a rollback occurs, the return value is also -1.
(Emphasis mine.)
Use set [] to avoid ambiguity with database keyword.
cmd.CommandText = "SELECT [Id] FROM [Users] WHERE ([Username] = #User)";
and use ExecuteScalar() or ExecureReader() method when working with SELECT statements.
I am trying to find the MAX number from a database field,The query below returns me the maximum value if i run it in SQL Enterprise Manager but i am not able to print the value in numbwe. Please help me to print the MAX value obtained from the database.
SqlConnection MyConnection = new SqlConnection("Data Source=localhost;Initial Catalog=hcgoa;User Id=sa;Password=;");
SqlCommand MyCmd = new SqlCommand("SELECT MAX([no]) AS Expr1 FROM jmain", MyConnection);
MyConnection.Open();
SqlDataReader myReader = MyCmd.ExecuteReader();
if (myReader.Read())
{
string numbwe = myReader["no"].ToString();
Response.Write("Max no. is : " + numbwe);
}
You need to use Expr1 as the key, not no.
That's because you're doing:
SqlCommand MyCmd = new SqlCommand("SELECT MAX([no]) AS Expr1 ...
(note the AS clause) so the column is named Expr1. Hence:
string numbwe = myReader["Expr1"].ToString();
should do it.
Although, in fairness to those who come after you, Expr1 is not a very descriptive identifier. Consider the possibility of changing it to something like MaxNum (both in the select and the key, of course).
You should look at the ExecuteScalar() instead if you are going to return a single value.
MSDN: Use the ExecuteScalar method to
retrieve a single value (for example,
an aggregate value) from a database.
This requires less code than using the
ExecuteReader method, and then
performing the operations that you
need to generate the single value
using the data returned by a
SqlDataReader.
You're trying to print the value of a column that doesn't exist in the query result. Your query returns a column named Expr1, not a column named "no"
Change
string numbwe = myReader["no"].ToString();
to
string numbwe = myReader["Expr1"].ToString();
should be string numbwe = myReader["Expr1"].ToString();
as you are specifying your column name in sql statement Expr1
SELECT MAX([no]) AS Expr1