Parameter not changing in OleDbCommand - c#

This is a simple search page (search.aspx?title=Hello) and I want to query the db for like matches. According to the microsoft docs (http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbparameter.aspx see: Remarks) this is the correct way to do it, but the parameter (?) never gets set to the value of the query string.
string sqlcmd = "SELECT * FROM TableName WHERE Title LIKE ?";
OleDbCommand command = new OleDbCommand(sqlcmd, sqlcon);
OleDbParameter p1 = new OleDbParameter("#p1", OleDbType.WChar);
p1.Value = Request.QueryString["title"];
OleDbDataAdapter da = new OleDbDataAdapter(command);
da.SelectCommand.Parameters.Add(p1);
DataTable dt = new DataTable();
da.Fill(dt);
The parameter never changes to what the query string was, it just executes the query
SELECT * FROM Table WHERE Title LIKE ?

Could you try the following:
"SELECT * FROM Table WHERE Title LIKE #p1"
I think that is the convention when using parameters in ADO.Net command text.

Here is my solution, you need to have single quotes around the question mark for the SQL to work. Complete solution:
sqlcon.Open();
string sqlcmd = "SELECT * FROM TableName WHERE Title LIKE '%?%'";
OleDbCommand command = new OleDbCommand(sqlcmd, sqlcon);
command.Parameters.Add(new OleDbParameter("p1", Request.QueryString["Title"]));
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);

Related

How to query two access database(accdb) files that have different schema?

I need your help.
Suppose there are two access database(accdb) files which have some columns with same names but some are not. For example:
start
Then how to make a query to both database at the same time?
OleDbConnection Conn = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=..\\DATABASE_A.accdb;");
OleDbCommand command = new OleDbCommand();
OleDbDataAdapter adapter = new OleDbDataAdapter();
DataTable dt = new DataTable();
Con.Open();
string query = "Select [JOB],[DATE] From TABLE_A WHERE [NAME] = ?";
command.CommandText = query;
command.Parameters.AddWithValue("#NAME", $someDate);
command.Connection = Conn;
adapter.SelectCommand = command;
adapter.Fill(dt);
Conn.Close();
However, how about DATABASE_B.accdb to fill the same DataTable dt but TABLE_B's column has different name?I want to form a datatable like that:
result
Thanks for any suggestion.
In SQL you would use a union query.
In C# you could use LINQ Union.

C# - How to parametrize SQL query with MySqlAdapter

I'm trying to run a SQL query using MySqlAdapter so it returns the data in a DataTable.
I'm having troubles with the parametrization. Basically it doesn't return anything and it should be returning 2 rows.
I have this code:
using (MySqlConnection connection = new MySqlConnection(CONSTANTS.dbCONNECTSTRING))
{
string sqlQuery = $"SELECT * FROM tfg_bcovi.User where userName= '#userName'";
MySqlCommand command = new MySqlCommand(sqlQuery, connection);
command.Parameters.Add(new MySqlParameter("#userName", userCtrl.UserName));
MySqlDataAdapter dataAdapter = new MySqlDataAdapter(command);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
DataTable dtResults = dataSet.Tables[0];
}
I checked and userCtrl.UserName have the correct value so I'm asuming something is wrong with parametrization.
The problem as I said before, is that dtResults ends up empty when it whould have at least 2 rows. I checked running the query in SQL.
What am I doing wrong?
Thanks!
Just remove the single quotes around the parameter. Your drive handles that for you already.
This:
string sqlQuery = $"SELECT * FROM tfg_bcovi.User where userName= '#userName'";
Should be:
string sqlQuery = $"SELECT * FROM tfg_bcovi.User where userName= #userName";

Database update error with SQL Server 2012 and C#

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.

Dropdownbox.selectedvalue passing to sql comment

string ddorder = DropDownList2.SelectedValue; // column
string ddtype = DropDownList3.SelectedValue; //asc or desc
String str1 = "Select * from table1 order by("+ddorder+" "+ddtype+")";
//there is an error beacuse of ddtype, what am I doing wrong?
SqlCommand cmd = new SqlCommand(str1, con);
con.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter da1 = new SqlDataAdapter();
da1.SelectCommand = cmd;
DataSet ds1 = new DataSet();
da1.Fill(ds1, DropDownList2.SelectedValue);
GridView2.DataSource = ds1;
GridView2.DataBind();
con.Close();
As far as I can see, you don't need to use ( and ) in order by clause. It's syntax doesn't have any usage for ( or ).
For example;
order by id desc
will work but
order by (id desc)
won't work.
By the way, use using statement to dispose your SqlConnection, SqlCommand and SqlDataAdapter automatically instead of calling Close method manually.
Also you don't need cmd.ExecuteNonQuery(); part for a SELECT statement. It is unnecessary since it's just execute your select query. It doesn't do or return something.
A few things more;
Change your table1 to something meaningful.
Don't use SELECT *. It's quite bad.
Use Dynamic Query:
Change Here:
string ddorder = DropDownList2.SelectedValue; // column
string ddtype = DropDownList3.SelectedValue; //asc or desc
String str1 = "exec(Select * from table1 order by "+ddorder+" "+ddtype+")";
and
SqlCommand cmd = new SqlCommand(str1, con);
con.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter da1 = new SqlDataAdapter();
da1.SelectCommand = cmd;
DataSet ds1 = new DataSet();
da1.Fill(ds1);
GridView2.DataSource = ds1;
GridView2.DataBind();
con.Close();
Remove the parenthesis in the "order by" clause:
String str1 = "Select * from table1 order by "+ddorder+" "+ddtype;

how can i put # in select sql statement?

I have to use the "#"(I don't know it's name). I can use it in update delete or insert statements but I cannot use it in there it gives URL MUST BE DECLARED
//SQL string to count the amount of rows within the OSDE_Users table
string sql = "SELECT * FROM RSSFeeds where URL = #URL";
SqlCommand cmd = new SqlCommand(sql, Connect());
cmd.Parameters.Add("#URL", SqlDbType.VarChar, 500).Value = url;
closeConnection();
SqlDataAdapter adapt = new SqlDataAdapter(sql, Connect());
DataSet ds = new DataSet();
adapt.Fill(ds);
// result of query filled into datasource
adapt.Dispose();
closeConnection();
return ds;
I can only suppose that this line is not correct:
cmd.Parameters.Add("#URL", SqlDbType.Int).Value = url;
Probably URL is not an Int but a NVarChar or other character type
If this is the case then change your line in this way
(255 is the supposed length of your field URL)
cmd.Parameters.Add("#URL", SqlDbType.NVarChar, 255).Value = url;
And, by the way, '#' is called "Parameter Prefix"
EDIT: Seeing the last edit from the OP I update my answer to show what I think is the correct way to go.
//SQL string to count the amount of rows within the OSDE_Users table
string sql = "SELECT * FROM RSSFeeds where URL = #URL";
DataSet ds = new DataSet();
using(SqlConnection cnn = Connect())
using(SqlCommand cmd = new SqlCommand(sql, cnn))
{
cmd.Parameters.Add("#URL", SqlDbType.VarChar, 500).Value = url;
using(SqlDataAdapter adapt = new SqlDataAdapter(cmd))
{
adapt.Fill(ds);
}
}
return ds;
What I have changed:
Encapsulated every disposable object inside an using statement that
is guaranteed to close/dispose objects
Called Connect() just one time and captured the SqlConnection returned to
reuse without creating another one
Created the SqlDataAdapter using the SqlCommand created before (so
the #URL parameter reaches the Sql)
The OP used a closeConnection() and we don't see the internal of this method, but I think that using is enough to close and dispose the connection.
EDIT: The line that creates SqlDataAdapter should be
using(SqlDataAdapter adapt = new SqlDataAdapter(cmd))
cmd.Parameters.AddWithValue("#URL", url);
should work

Categories