I am tryng to use Parameterised queries with MySQL. The theory seems pretty straight forward, you create a new instance of the MySqlCommand class like so:
MySqlCommand command = new MySqlCommand();
Set the CommandText property of this object to a MySQL query with placeholders like so:
command.CommandText = "INSERT INTO `myTable` (`myField`) VALUES('#bar');
Use the AddWithValue method to replace my placeholder text with an actual value:
command.Parameters.AddWithValue("#bar", "HelloWorld");
This is how I thought it worked, but in reality the word "#bar" ends up being appended, as opposed to "HelloWorld".
What am I doing wrong?
try without wrapping in single quote
command.CommandText = "INSERT INTO `myTable` (`myField`) VALUES(#bar);
Related
FbCommand fbCmm =
new FbCommand("INSERT INTO PRODUTO
(CODIGO,EAN,DESCRICAO,VAL_PRODUTO,VAL_CUSTO,CAT_PRECO)"
+ "Values (#txt_codigo.Text, #txt_ean, #txt_descricao,
#txt_valPro, #txt_valCus, #txt_catPre)", ConexaoFirebird.Conexao);
What's wrong with that sentence?
I did a open connection in other class - ConexaoFirebird.Conexao();
You're executing a parameterized query without providing values for those parameters. See the documentation:
FbCommand cmd = new FbCommand("insert into t1(id, text) values (#id, #text);");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#id", 123);
cmd.Parameters.Add("#text", "my string");
cmd.ExecuteNonQuery();
Here they bind the values 123 and "my string" to the parameters named id and text respectively.
Also note that parameter names are generally rescticted to alphanumeric, so txt_codigo.Text isn't likely going to work.
You should use quote for decimal, string field types, your statement is correct but not clear, you can create clear sql text with sql command builder or you can use Command object of your connection.
THIS works:
OracleCommand cm = con.CreateCommand();
cmd.CommandText = String.Format("select s,e from {0}" + ".DTREE where DATAID=:pDataId", credentialsthing.dbschema");
cmd.Parameters.Add("pDataId", objectx.theid);
However... I also want to put the first one in the parametr command:
cmd.CommandText = "select s,e from :pPar1" + ".DTREE where DATAID=:pDataId");
cmd.Parameters.Add("pPar1", credentialsthing.dbschema);
cmd.Parameters.Add("pDataId", objectx.theid);
And this fails. Why, what should the syntax be?
Your can't parameterize your table name, column name or any other database objects.
You can only parameterize your values. That's why you need to use string concatenation for your table name.
But you should be very careful doing that, you need to supply strong validation for your table name or should use a whitelist of some form.
I have the statement in c# :
String sql = String.Format("UPDATE Table SET FIRST_NAME='{0}',LAST_NAME='{1}',BIRTH_DATE='{2}' where CUSTOMER_NUMBER ='{3}'",FirstName, LastName,DateOfBirth,Number);
The above statement doesn't execute if the first name,last name etc have apostrophe like O'Hare,O'Callahagan because of this the update statement gets the wrong syntax.
How to escape the apostrophe in string.format?
How to escape the apostrophe in string.format?
Don't escape it, use parameterized query instead.
Imagine a user with a really unconventional name strongly resembling SQL statements for dropping a table or doing something equally malicious. Escaping quotes is not going to be of much help.
Use this query instead:
String sql = #"UPDATE Table
SET FIRST_NAME=#FirstName
, LAST_NAME=#LastName
, BIRTH_DATE=#BirthDate
WHERE CUSTOMER_NUMBER =#CustomerNumber";
After that, set values of FirstName, LastName, DateOfBirth, and Number on the corresponding parameters:
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("#FirstName", FirstName);
command.Parameters.AddWithValue("#LastName", LastName);
command.Parameters.AddWithValue("#BirthDate", BirthDate);
command.Parameters.AddWithValue("#CustomerNumber", CustomerNumber);
Your RDMBS driver will do everything else for you, protecting you from malicious exploits. As an added benefit, it would let you avoid issues when the date format of your RDBMS is different from your computer: since your date would no longer be passed as a string representation, there would be no issues understanding which part of the formatted date represents a day, and which one represents a month.
You should use parameterized queries:
using (SqlCommand cmd = new SqlCommand("UPDATE Table SET FIRST_NAME= #FirstName, LAST_NAME= #LastName, BIRTH_DATE=#BirthDate where CUSTOMER_NUMBER = #CustomerNumber"))
{
cmd.Parameters.Add(new SqlParameter("FirstName", FirstName));
cmd.Parameters.Add(new SqlParameter("LastName", LastName));
cmd.Parameters.Add(new SqlParameter("BirthDate", DateOfBirth));
cmd.Parameters.Add(new SqlParameter("CustomerNumber", Number));
// Now, update your database
} // the SqlCommand gets disposed, because you use the 'using' statement
By using parameterized queries, you solve your problem. Using parameterized queries has two other advantages:
Protection against SQL Injection
Readability
Use parameterized query.
string commandString = "insert into MyTable values (#val1, #val2)";
SqlCommand command = new SqlCommand(commandString, connection);
command.Parameters.AddWithValue("val1", "O'Hare");
command.Parameters.AddWithValue("val2", "O'Callahagan");
command.ExecuteNonQuery();
I'm making an C# windows Form Application in visual studio 2010.
That application is connecting to an mysql database, and I want to insert data in it.
Now do I have this part of code:
MySqlConnection connection;
string cs = #"server=server ip;userid=username;password=userpass;database=databse";
connection = new MySqlConnection(cs);
connection.Open();
MySqlCommand command = new MySqlCommand();
string SQL = "INSERT INTO `twMCUserDB` (`mc_userName`, `mc_userPass`, `tw_userName`, `tw_userPass`) VALUES ('#mcUserName', '#mcUserPass', '#twUserName', '#twUserPass')";
command.CommandText = SQL;
command.Parameters.Add("#mcUserName", mcUserNameNew);
command.Parameters.Add("#mcUserPass", mcUserPassNew);
command.Parameters.Add("#twUserName", twUserNameNew);
command.Parameters.Add("#twUserPass", twUserPassNew);
command.Connection = connection;
command.ExecuteNonQuery();
connection.Close();
The connection is fine. That works.
I readed here that the way that I have now, is an save way to do query's. Is that still right?
And now to the real question. With that code above, I get the following warning in visual studio:
'MySql.Data.MySqlClient.MySqlParameterCollection.Add(string, object)' is obsolete: '"Add(String parameterName, Object value) has been deprecated. Use AddWithValue(String parameterName, Object value)"'
That warning is for every parameters.add
And it isn't even working, because the values that are inserted are #mcUserName, #mcUserPass and so on, instead of the values that the variables mcUserNameNew and so on are holding...
So my question is, am I doing something wrong, and what is the new way to sql injection save do an query?
try AddWithValue
command.Parameters.AddWithValue("#mcUserName", mcUserNameNew);
command.Parameters.AddWithValue("#mcUserPass", mcUserPassNew);
command.Parameters.AddWithValue("#twUserName", twUserNameNew);
command.Parameters.AddWithValue("#twUserPass", twUserPassNew);
and don't wrap the placeholders with single quotes.
string SQL = "INSERT INTO `twMCUserDB` (`mc_userName`, `mc_userPass`, `tw_userName`, `tw_userPass`) VALUES (#mcUserName, #mcUserPass, #twUserName, #twUserPass)";
Edit:
As Bradley Grainger pointed out, in MySQL is safe to use AddWithValue.
I'm keeping my answer if you get here by chance and use Microsoft SQL.
Please read this article, advising you against using AddWithValue:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
It says basically that AddWithValue could sometimes incorrectly infer the correct type. Use Add instead.
Just edit/remove some code in this part
('#mcUserName', '#mcUserPass', '#twUserName', '#twUserPass')
to
(#mcUserName, #mcUserPass, #twUserName, #twUserPass)
and Add( to AddWithValue(
#mcUserName has to match the mc_userName in the query ..
so your parm should be #mc_userName
This is VB code...
cmd.Parameters.AddWithValue("#number", 1) 'set #number as numeric
cmd.Parameters.AddWithValue("#text", "this will be a text variable")
cmd.Parameters("#number").Value = 321 'now #number has a value
cmd.Parameters("#text").Value = "A string value" 'now #text has a value
cmd.ExecuteNonQuery()
should be used as such to prevent any errors set the dbtype correctly then assign
cmd.Parameters.Add("#ID", MySqlDbType.Int32);
correct way to set a MySqlDBType
cmd.Parameters["#ID"].Value = 1;
now set the value
I am trying to insert string as "baby's world" into the column of type varchar through query but shows me error.
Is there anything else i need to put to the query so that it accept that symbol
put a backslash in front of it like so:
"Baby\'s world"
You can find and replace them in your string using the following:
str.Replace('\'', '\\\'')
I'm not 100% sure about this last part, but you need to 'escape' the ' and \ by adding a \ in front of it. So it would seem alright (can't test as i'm not a C# programmer.
Since you are asking about Visual Studio (.NET), you need to use parameterized query. Don't use concatenation when constructing query
private void PrepareExample()
{
string s = Console.ReadLine();
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
cmd.Parameters.AddWithValue( "?title", "baby's world" );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Or
private void PrepareExample()
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO movie(title) VALUES (?title)", myConnection);
// try to input: baby's world. or try: baby"s world. everything are ok :-)
cmd.Parameters.AddWithValue( "?title", Console.ReadLine() );
cmd.Prepare();
cmd.ExecuteNonQuery();
}
Though this is not exactly concatenation, don't use this:
qry = string.Format("INSERT INTO movie(title) VALUES("{0}", Console.ReadLine());
Though if you really found a need to run SQL that way, replace single quote with backslash
qry = string.Format("INSERT INTO movie(title) VALUES("{0}",
Console.ReadLine().Replace("'", "\'");
But do consider using parameterized query instead of concatenation or string.Format, as parameterized query automatically take care of those delimeter nuances.
http://dev.mysql.com/doc/refman/5.0/es/connector-net-examples-mysqlcommand.html
Just use mysql_real_escape_string(). There is no need to do anything else.
For example:
mysql_real_escape_string($user),
mysql_real_escape_string($password));
INSERT INTO table (field) VALUES ('baby's world') will fail because the string is truncated to INSERT INTO table (field) VALUES ('baby' and the rest is seen as invalid code.
There are two ways to stop this, the second being advisable for good practice coding:
INSERT INTO table (field) VALUES ("baby's world")
INSERT INTO table (field) VAUES ('baby\'s world')