I am trying to pull data from my table based on the button a user clicks, so if they click the 1940's button it will pull all products from that decade but I cant get the query to work. It has to do with the #decade parameter because that is where I am getting the user input from but it doesnt like it when I am trying to choose a column using that parameter
ImageButton decadeBtn = (ImageButton)sender;
var decade = decadeBtn.CommandArgument;
yearHead.InnerText = decade.ToString();
string cmd="";
DataSet ds;
if (typeOfArchive == "On Hand")
{
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#decade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
}
else if(typeOfArchive == "All Other"){
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#decade AND PRODUCT_LINE=#Line AND LOCATION is null";
}
using (OleDbConnection dbConn = new OleDbConnection(connectionString))
using (OleDbDataAdapter dbCmdDecade = new OleDbDataAdapter(cmd, dbConn))
{
dbConn.Open();
dbCmdDecade.SelectCommand.Parameters.Add("#decade", OleDbType.Integer).Value = decade;
dbCmdDecade.SelectCommand.Parameters.Add("#line", OleDbType.VarChar).Value = productLine;
ds = new DataSet();
dbCmdDecade.Fill(ds, "products");
}
No you can't use a parameter in that way. As a rule, you cannot use a parameter to define a column name or a table name (or concatenating it to form a column name). A parameter could only be used to define a value used in the query. (or with a stored procedure to create an SQL Text inside the sp to be executed but that is another more complex story),
However, assuming that you are not allowing your users to type directly the decade value (Sql Injection vulnerability), then it is pretty simple to create a string with the column name desidered and use it in your query.
Add a method that just concatenate together you decade string with your prefix for the DECADE column
private string GetDecadeColumn(string decade)
{
return "DECADE_" + decade;
}
and in you query
if (typeOfArchive == "On Hand")
{
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE " +
GetDecadeColumn(decade) +
" AND PRODUCT_LINE=#Line AND LOCATION is not null;";
}
else if(typeOfArchive == "All Other"){
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE " +
GetDecadeColumn(decade) +
" AND PRODUCT_LINE=#Line AND LOCATION is null";
}
So ARCHIVE_DECADE_TBL has columns that are named something like DECADE_1990 with a value of 1990, DECADE_2000 with a value of 2000, etc?
It really should be designed to just be called "DECADE" with the value being 1990/2000/etc, but if that's not possible, you'll have to build your query dynamically. I don't believe those parameters will work to set the column name. They can set a value to check for, but not the column names.
You'll have to build the query out manually in c#, so something like:
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_" + decade + #" = #decade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
Now, if I misunderstood and your column is actually named DECADE_#decade, then I think you'll just need to change your variable so it's not #decade, so something like #mydecade. The conflict there will confuse it.
Sooooo like...
cmd = #"Select * From ARCHIVE_DECADE_TBL WHERE DECADE_#decade=#mydecade AND PRODUCT_LINE=#Line AND LOCATION is not null;";
And then down below:
dbCmdDecade.SelectCommand.Parameters.Add("#mydecade", OleDbType.Integer).Value = decade;
That probably shouldn't have an # in the column name though. :)
Related
I was wondering why this SQL Query doesn't return anything:
mySqlCommand.CommandText = "SELECT * FROM `users` WHERE Username LIKE %#Username% ORDER BY Id DESC";
mySqlCommand.Parameters.AddWithValue("#Username", this.search.Text);
IT's not a reader problem or anything like this, if i remove "WHERE Username LIKE %#Username% ", it works fine.
I call this whole MySQL-Query in a KeyPress-Event of a Textbox.
this.search is the Textbox. I want to search for rows where the Username Column contains the Characters i entered in the Textbox.
Try to use
//For LIKE query
SqlParameter parameter = new SqlParameter("#query", SqlDbType.NVarChar);
parameter.Value = string.Format("%{0}%", this.search.Text);
IList<Users> results = ctx.Database.SqlQuery<Users>("SELECT * FROM Users WHERE Username LIKE #query", parameter).ToList();
I solved it using this:
mySqlCommand.CommandText = "SELECT * FROM `users` WHERE Username LIKE #Username ORDER BY Id DESC";
mySqlCommand.Parameters.AddWithValue("#Username", "%" + this.search.Text + "%");
I would strongly recommend using a stored procedure, will help against SQL Injection attacks, and you want to disallow your app to use insert, update and delete scripts and only allow it to use execute statements for stored procedures.
But you want to change this line from
mySqlCommand.CommandText = "SELECT * FROMusersWHERE Username LIKE %#Username% ORDER BY Id DESC";
to
mySqlCommand.CommandText = "SELECT * FROMusersWHERE Username LIKE '%#Username%' ORDER BY Id DESC";
I know its probably something simple but its been driving me nuts for 2 days now
In short, what I want to do is return all of the entries from a specific table based on a value fed into the sql string from a label that holds the appropriate value
This is what I have currently, and it works, but I don't want it to be hardcoded to 'admin':
sqlString = "SELECT * FROM mail WHERE fromuser = 'admin'";
The above returns the entries in the table where the fromuser value is 'admin'
Like I said it works fine. What I want to do is something more like this:
sqlString = "SELECT * FROM mail WHERE fromuser = " + lblUsername.Text;
Where the lblUsername.Text is the value of the currently logged in user (in this case its admin just like before)
So my question is how to I feed the label value into the sql string so that I don't need to hardcode it as 'admin' so that what is returned changes with the value of lblUsername.Text?
I think your first issue is you are missing the quotes when you are building the sql. So your query should look like
sqlString = "SELECT * FROM mail WHERE fromuser = '" + lblUsername.Text + "'";
But the that would be a horrible query to run against your database, because you would be very vulnerable for sql injection. Try parameterized query instead.
I'm assuming your connection string is set in connectionString variable
MySqlConnection connection = new MySqlConnection(connectionString);
connection.Open();
MySqlCommand command = new MySqlCommand("SELECT * FROM mail WHERE fromuser = #fromUser", connection);
cmd.Parameters.Add(new MySqlParameter("fromUser", lblUsername.Text));
MySqlDataReader dataReader = cmd.ExecuteReader();
if (dataReader.HasRows){
//do all your reading.
}
connection.Close();
Also, I would suggest you to look into Dapper dot net, which is an excellent ORM to use rather than this naive ADO.NET code
try
var textInLabel = lblUsername.Text;
sqlString = "SELECT * FROM mail WHERE fromuser ='" + textInLabel + " '";
TRY THIS
sqlString = "SELECT * FROM mail WHERE fromuser = '"+ lblUsername.Text+"'";
I am trying to use a parametrized query which takes 2 column names and a table name and retrieves the data from a sql server DB.
The problem is it is not possible to parametrize the table name so i found a solution using a sqlcommandbuilder.quoteIdentifer(tablename) and this bit works...but apparently they don't play nice together.
I get exception containing a single word which is the column name
If i put the column name by hand it works.
What is wrong here?
public List<ItemsWithDescription> GetItemsFromDB(string name, string desc, string tableName)
{
List<ItemsWithDescription> items = new List<ItemsWithDescription>();
try
{
Status = 1;
SqlCommandBuilder builder = new SqlCommandBuilder();
cmd = new SqlCommand("Select #Name, #Desc from "+ builder.QuoteIdentifier(tableName), conn);
cmd.Parameters.AddWithValue("#Name", name);
cmd.Parameters.AddWithValue("#Desc", desc);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
items.Add(new ItemsWithDescription(dr[name].ToString(), dr[name].ToString() + " | " + dr[desc].ToString()));
}
}
items.Sort((x, y) => string.Compare(x.Item, y.Item));
}
catch
{
Status = -1;
}
return items;
}
Edit:
This works but I would prefer to know why both can't be used together:
cmd = new SqlCommand("Select" +
builder.QuoteIdentifier(name) + "," +
builder.QuoteIdentifier(desc) + "from " +
builder.QuoteIdentifier(tableName), conn);
You can't parameterize column names. You can't do that in regular SQL actually.
What you need is Dynamic SQL.
If you follow the various newsgroups on Microsoft SQL Server, you
often see people asking why they can't do:
SELECT * FROM #tablename
SELECT #colname FROM tbl
SELECT * FROM tbl WHERE x IN (#list)
For all three examples you can expect someone to answer Use dynamic
SQL and give a quick example on how to do it. Unfortunately, for all
three examples above, dynamic SQL is a poor solution. On the other
hand, there are situations where dynamic SQL is the best or only way
to go.
Also take a look Table-Valued Parameters if you use SQL Server 2008 and above.
I have the following update query in C# using a JET OLEDB connection, connecting to a ms access DB file. The query fails to change the fields, it runs correctly but just 0 rows changed.
I think the problem is how parameters are processed and compared against the DB but have no idea how to fix it.
The "User" column is set as text. I have an insert statement that works perfectly set up in the same fashion with the parameters.
com.CommandText = "UPDATE [ExamMaster] SET [User] = (DLookup('LName', 'Users', 'ID' = '#correctUser') WHERE [User] = '#user'";
com.Parameters.AddWithValue("#correctUser", correctUser);
com.Parameters.AddWithValue("#user", userName);
If I do not use a parameter for the where clause and just insert it into the command string like so:
WHERE [User] = '"+userName+"'";</code>
it will update the DB just fine. What am I missing here?
UPDATE:
With or with single quotes makes no difference and rearranging the order of the parameters does not work either.
The order matters. I "think" in your query user is being called first before the correctUser due to the DLOOKUP function.
com.Parameters.AddWithValue("#user", userName);
com.Parameters.AddWithValue("#correctUser", correctUser);
You don't need to single quote parameters:
WHERE [User] = #user";
and I'll guess that the DLOOKUP doesn't need the single quotes either, just [brackets] if the field name has a space or is a reserved word (which [User] might be).
You will need to change that a bit, try:
OleDbConnection cn = new OleDbConnection(aconnectionstring);
cn.Open();
//testing
int correctUser = 1;
string userName = "1";
OleDbCommand com = new OleDbCommand();
com.Connection = cn;
//You cannot have a parameter in DLookUp
com.CommandText = "UPDATE [ExamMaster] SET [User] = " +
"DLookup('LName', 'Users', 'ID = " + correctUser + "') WHERE [User] = #user";
com.Parameters.AddWithValue("#user", userName);
//You must execute the query
com.ExecuteNonQuery();
I am using VS2005 C# ASP.NET and SQL Server 2005.
I have a search function on my asp page and I feel that my SELECT query is vulnerable to SQL injection.
This is my current SELECT statement:
string LoggedInUser = (User.Identity.Name);
SqlDataSource1.SelectCommand = "SELECT * FROM [TABLE1] where [" + DropDownList1.Text + "] like '%" + searchTB.Text + "%' AND [empUser] LIKE '%"+LoggedInUser+"%'";
SqlDataSource1.DataBind();
*where searchTB is my search text box; DropDownList1 is my search category; and LoggedInUser is the username of the logged in user.
I have implemented parameter instead of concatenation in one of my INSERT statement:
string sql = string.Format("INSERT INTO [TABLE2] (Username) VALUES (#Username)");
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("Username", usernameTB.Text);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
I would like to change my SELECT statement like my INSERT statement, using parameter instead. May I know how should I change it?
Thank you
You can add parameters to your selectcommand using
SqlDataSource s = new SqlDataSource();
s.SelectParameters.Add("paramName", "paramValue");
There are other parameter collections for delete, update and insert too.
s.DeleteParameters
s.UpdateParameters
s.InsertParameters
More Information:
MSDN: SqlDataSource.SelectParameters Property
Programmatically Using SqlDataSource
hope this helps
See Using Parameters with the SqlDataSource Control
And SqlDataSource.SelectParameters Property
You can specify SelectParameters Property for SqlDataSource to use parameterized SQL query
Write a method that gets the data sourse and use sql parameters for the query. Here is a good example how to add parameters in a command object
SqlCommand command = new SqlCommand(commandText, connection);
command.Parameters.Add("#ID", SqlDbType.Int);
command.Parameters["#ID"].Value = customerID;
I would use a method for the query so that I separate the Database Access from the UI functionality. Also, this allows to reuse the query.
It's not a straightforward task to dynamically specify a fieldname in query, so I'd suggest just doing switch/case validation for field name, like this:
switch (DropDownList1.Text)
{
case "ValidField1":
case "ValidField2":
...
break;
default:
throw new ArgumentException(...); // or prevent query execution with some other statement
}
SqlDataSource1.SelectCommand = "SELECT * FROM [TABLE1] where [" + DropDownList1.Text + "] like #value AND [empUser] LIKE #user";
SqlDataSource1.SelectParameters.Add("value", "%" + searchTB.Text + "%");
SqlDataSource1.SelectParameters.Add("user", "%"+LoggedInUser+"%");
SqlDataSource1.DataBind();
You can simply use a filter expression for the SQL datasource SQL Datasource filter expression
You can write your own select function method with object datasource/datatable