How to use OdbcParameter for MySQL?
This is my current attempt:
command.Parameters.Add(new OdbcParameter("#username", username.Text));
command.Parameters.Add(new OdbcParameter("#password", password.Text));
command.CommandText = "INSERT INTO test.test (`user`,`password`) VALUES (#username,#password);";
command.ExecuteNonQuery();
but it seems to be not working. The database does create a new row, but it's values are NULL.
This works: (but I really need the parameters for other stuff)
command.CommandText = "INSERT INTO test.test (`user`,`password`) VALUES (`" + username.Text + "`,`" + password.Text + "`);";
command.ExecuteNonQuery();
What am I doing wrong?
Change your CommandText to be a valid one for OdbcCommand:
command.CommandText = "INSERT INTO test.test (`user`,`password`) VALUES (? , ?);";
Instead of the parameter name as #paramname, it takes a ? in the CommandText - leave the name in the actual parameters.
See this blog post for an example.
Related
I have this INSERT statement,
"INSERT INTO [CustomerInfo] (CustomerName, CustomerEmail, CustomerAddress) " +
$"VALUES ('{name}','{email}','{address}')";
So as you can see on the 2nd line, i have added '$'. This version of the code works, but it's not supported in VS2012.
I'm trying to convert this into something like this but I'm having a lot of issues since it's so very complicated .
"INSERT INTO [CustomerInfo] (CustomerName, CustomerEmail, CustomerAddress) " +
"VALUES (''" + name + "', ''" + email + "', ''" + address + "')";
This version above doesn't work. Basically i'm trying to make a query without using the '$' Any ideas?
Don't do that at all, it exposes you to SQL injection attacks and converions issues. What would a date look like if you tried to pass it using string concatenation? A decimal?
It's actually easier to use parameterized queries :
//Create a SqlCommand that can be reused
SqlCommand _cmdInsert;
var sql="INSERT INTO [CustomerInfo] (CustomerName, CustomerEmail, CustomerAddress) " +
"VALUES (#name,#email,#address)";
var cmd=new SqlCommand(cmd);
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 30);
cmd.Parameters.Add("#email", SqlDbType.NVarChar, 20);
cmd.Parameters.Add("#address", SqlDbType.NVarChar, 50);
_cmdInsert=cmd;
Later, you can use the command directly by setting a connection and parameter values :
using(var connection=new SqlConnection(theConnectionString)
{
_cmdInsert.Connection=connection;
_cmdInsert.Parameters["#name"].Value=someName;
...
connection.Open();
_cmdInsert.ExecuteNonQuery();
}
Parameterized queries pass the strongly-typed values alongside the query in the RPC call. A DateTime is passed as a DateTime (or the binary equivalent) to the server, not as a string. This way, there are no conversion errors. No matter what the value contains, it's never mixed with the query itself so it isn't executed. Even if address contained '); drop table Users;-- it wouldn't be executed.
Another option is to use a microORM like Dapper. Dapper uses reflection to map parameter names and data properties to create and execute parameterized queries:
var insertStmt="INSERT INTO [CustomerInfo] (CustomerName, CustomerEmail, CustomerAddress) " +
"VALUES (#name,#email,#address)";
connection.Execute(insertStmt, new { name=someName,email=someEmail, address=someAddress});
As the project's page shows, you can execute the same query multiple times if you pass an array of parameters :
var myItems=new[]
{
new {name=someName,email=someEmail, address=someAddress}
};
connection.Execute(insertStmt, myItems);
You should use parameterized queries, for example if you are using ADO.NET, use this:
. . .
using(SqlConnection connection = new SqlConnection("yourConnectionString"))
{
SqlCommand cmd = connection.CreateCommand();
cmd.CommandText = #"INSERT INTO [CustomerInfo] (CustomerName, CustomerEmail, CustomerAddress)
VALUES (#Name, #Email, #Address)";
cmd.Parameters.AddRange(new SqlParameter[]
{
new SqlParameter("#Name", name),
new SqlParameter("#Email", email),
new SqlParameter("#Address", address)
});
connection.Open();
cmd.ExecuteNonQuery();
}
. . .
other sql provider type examples you can find here.
foreach (GridViewRow g1 in GridView1.Rows)
{
SqlCommand cmd = new SqlCommand("INSERT INTO Order VALUES(#buyersName, #deliveryAddress, #productID, #productName, #category, CONVERT(VARBINARY(MAX), #image), #price, #paymentMode, #holderName)", con);
cmd.Parameters.AddWithValue("#buyersName", Label2.Text);
cmd.Parameters.AddWithValue("#deliveryAddress", TextBox1.Text);
cmd.Parameters.AddWithValue("#productID", g1.Cells[0].Text);
cmd.Parameters.AddWithValue("#productName", g1.Cells[1].Text);
cmd.Parameters.AddWithValue("#category", g1.Cells[2].Text);
cmd.Parameters.AddWithValue("#image", g1.Cells[3].Text);
cmd.Parameters.AddWithValue("#price", g1.Cells[4].Text);
cmd.Parameters.AddWithValue("#paymentMode", checkRadioButton());
cmd.Parameters.AddWithValue("#holderName", TextBox2.Text);
int r = cmd.ExecuteNonQuery();
}
When I run this code, it is showing an error that there is a syntax error near "Order". checkRadioButton() is returning the label of the selected RadioButton.
you can't have expression like convert() within the VALUE ()
Change to use
INSERT INTO [Order] (column name, ...)
select #buyersName, convert() ,...
by the way you should explicitly specify the column name in the INSERT clause or in future when you add a column to the table, your query will break
also why are you using reserved name as table name ?
Contrary to the statement in the other answer, it should be possible to CONVERT within the VALUES-section.
But there are multiple flaws or things that could be improved:
ORDER is a reserved word in sql server, put it in square brackets: [Order]
Don't use AddWithValue otherwise sql server infers the datatype, which could be problematic. Use Add instead. See here for more information.
You can convert the value of g1.Cells[3].Text to a byte-array (byte[]) before setting the parameter value. For conversion to byte[] see here.
Specify the columns in your query, to not break it when table changes in future
Change your code like following (column-names and datatypes may vary):
SqlCommand cmd = new SqlCommand(#"INSERT INTO [Order] (buyersName, deliveryAddress, productID, productName, category, image, price, paymentMode, holderName)
VALUES(#buyersName, #deliveryAddress, #productID, #productName, #category, #image, #price, #paymentMode, #holderName)", con);
cmd.Parameters.Add("#buyersName", SqlDbType.VarChar).Value = Label2.Text;
cmd.Parameters.Add("#deliveryAddress", SqlDbType.VarChar).Value = TextBox1.Text;
cmd.Parameters.Add("#productID", SqlDbType.VarChar).Value = g1.Cells[0].Text;
cmd.Parameters.Add("#productName", SqlDbType.VarChar).Value = g1.Cells[1].Text;
cmd.Parameters.Add("#category", SqlDbType.VarChar).value = g1.Cells[2].Text;
cmd.Parameters.Add("#image", SqlDbType.VarBinary).Value = g1.Cells[3].Text; //convert g1.Cells[3].Text to a byte array
cmd.Parameters.Add("#price", SqlDbType.Money) = g1.Cells[4].Text;
cmd.Parameters.Add("#paymentMode", SqlDbType.VarChar).Value = checkRadioButton();
cmd.Parameters.Add("#holderName", SqlDbType.VarChar).Value = TextBox2.Text;
int r=cmd.ExecuteNonQuery();
Hello Everyone I'm new in here. I am currently making an asp.net project monitoring module. At this moment I am in the process of editing the project form and adding resources to the selected task in a project.
I'm having a problem in saving the record. Everytime I save the record it says
"Column name or number of supplied values does not match table
definition."
In my ProjectTasks Table I have RefNo(PK), TaskID(FK), Name and Description
Name - refers to the Task Name
Description - refers to the Task Description
What I want to happen is that my Resource Tables TaskID(FK) will be updated when I clicked the save button. As of now when I add a Resource from a task the TaskID = 0.
protected void btnSave_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "INSERT INTO ProjectTasks VALUES (#Name, #Description); " +
"SELECT TOP 1 TaskID FROM ProjectTasks ORDER BY TaskID DESC;";
cmd.Parameters.AddWithValue("#Name", txtName.Text);
cmd.Parameters.AddWithValue("#Description", txtDescription.Text);
int taskID = (int)cmd.ExecuteScalar();
con.Close();
con.Open();
cmd.CommandText = #"UPDATE Resource_Materials SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Equipments SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Vehicles SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Contractors SET TaskID=#TaskID WHERE TaskID=0;";
cmd.Parameters.AddWithValue("#TaskID", taskID);
cmd.ExecuteNonQuery();
con.Close();
Helper.AddLog("1", "Add", "Assigned Resources to Task");
Response.Redirect("~/Projects/Default.aspx");
}
Sorry about my grammar I'm just a student.
You said
ProjectTasks Table I have RefNo(PK), TaskID(FK), Name and Description
In such case, your INSERT query should look like below instead, specify the exact column name you are trying to insert values and as well you are missing TaskID(FK) column in your current insert query
INSERT INTO ProjectTasks(TaskID, Name, Description)
VALUES (#TaskID, #Name, #Description);
In an insert statement, we need to supply the column names when we don't want to specify values for all columns. If we don't do this we need so supply values for all columns.
In your case, you just want to provide values for Name and Description so you can do something like:
INSERT INTO ProjectTasks(Name, Description) VALUES (#Name, #Description);
Your logic is misleading..
Your ProjectTasks has 4 columns but you try to insert 2 column value in your insert statement without declaring them after your table name as ProjectTasks (Name, Description).
But this still generate a problem because your first column is PK and second one is FK. Since FK can be null but PK can't be null as far as I know, that's why you need to re-think your inserting logic.
But even if you fix it, your code still has a problem. Since you set a new string to your CommandText property, your #Name and #Description parameters were still belongs on your cmd object. That's why on ExecuteNonQuery line, your cmd will have 3 parameters as #Name, #Description and #TaskID but your command has only 1 parameter. As you can see, you will get an error such as; the parameter you supplied and command doesn't match or something. In such a case, you need to Clear() your parameters before you set new CommandText or generate a new SqlCommand object as cmd = new SqlCommand()
Also use using statement to dispose your connection and commands automatically instead of calling .Close() or .Dispose() methods manually.
And don't use AddWithValue method anymore. It may generate unexpected results sometimes. Use Add method overloads to specify your parameter type and it's size.
Solved it by removing ExecuteScalar and by replacing INSERT statement into UPDATE statement instead.
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "UPDATE ProjectTasks SET Name=#Name, Description=#Description " +
"WHERE TaskID=#TaskID; " +
"SELECT TOP 1 TaskID FROM ProjectTasks ORDER BY TaskID DESC;";
cmd.Parameters.AddWithValue("#Name", txtName.Text);
cmd.Parameters.AddWithValue("#Description", txtDescription.Text);
cmd.Parameters.AddWithValue("#TaskID", Request.QueryString["ID"].ToString());
cmd.CommandText = #"UPDATE Resource_Materials SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Equipments SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Vehicles SET TaskID=#TaskID WHERE TaskID=0; " +
"UPDATE Resource_Contractors SET TaskID=#TaskID WHERE TaskID=0;";
cmd.ExecuteNonQuery();
con.Close();
Helper.AddLog("1", "Add", "Assigned Resources to Task");
Response.Redirect("~/Projects/Default.aspx");
I have this piece of code:
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = connection;
cmd.CommandText = "UPDATE S " +
"SET S.WebId = S.WebId + 1 " +
"OUTPUT DELETED.WebId " +
"FROM jcdSetting S";
SqlParameter parameter = cmd.Parameters.Add("#id", SqlDbType.Int);
parameter.Direction = ParameterDirection.Output;
int i = cmd.ExecuteNonQuery();
webId = Convert.ToInt32(cmd.Parameters["#id"].Value);
}
For some reason, the last line fails, the parameter I'm trying to access is always DbNull. I've tried the query in Management Studio and it returns the value just fine.
I've checked the return value of ExecureNonQuery and that as well returns 1 as expected. I'm totally lost here.
Any help would be appreciated.
Using the output within a update statement, is equivalent to a select, whereas from the code you've posted you're expecting it to come out in an output parameter named #id.
Where does #id come from? you haven't defined it anywhere.
output in the method that you've used it would return a rowset, not a scalar value.
I know how to use Text Box value in Access query for string fields, but i am unable to understand how to use it for int fields.
I am writing the following query and receiving error messages.
ERROR MESSAGE: No value given for one or more required parameters.
OleDbCommand cmd = new OleDbCommand("Update Table1 Set Name= '" + textBox2.Text + "' where ID= " +textBox2.Text , conn);
conn.Open();
cmd.ExecuteNonQuery();
I also tried to convert textBox2 into int, but its also given me an error message.
Input string was not in a correct format.
int Id= Convert.ToInt16(textBox2.Text);
OleDbCommand cmd = new OleDbCommand("Update Table1 Set Name= '" + textBox2.Text + "' where ID= " + Id , conn);
conn.Open();
cmd.ExecuteNonQuery();
This answer corrects your problem
First, the TextBox for Name is not the same Textbox used for ID
Second, do not concatenate strings to build sql commands. It is very error prone and open to a well know sql vulnerability called Sql Injection
string queryText = Update Table1 Set Name= ? where ID= ?";
OleDbCommand cmd = new OleDbCommand(queryText, conn);
cmd.Parameters.AddWithValue("#p1", TextBox1.Text);
cmd.Parameters.AddWithValue("#p2", Convert.ToInt32(TextBox2.Text));
conn.Open();
cmd.ExecuteNonQuery();
Here I have removed the string concatenation and inserted two parameters placeholders (?),
then I have added to the OleDbCommand two parameters and their values.
When executing the query the OleDb code will replace the placeholders with the actual values checking for invalid characters and invalid sql statements