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
Related
I am trying to get a specific single value from an Access Database using C#.
For some reason what I am asking for is giving me an exception of
Syntax error in FROM clause
and I cant work out why.
I have tried running the SQL directly in Access itself and it works fine and gives me back the results I want, but I have no idea why its not working in my program.
ProbID is a number field as far as Access describes it and CorrDetails is a memo field.
For simplicity i have set the SQL to look for a specific value (137) but once i have the code working i will make it paramiterised.
Any ideas?
string corrAct;
OleDbConnection dbConnection;
dbConnection = new OleDbConnection(vDbString);
string sqlString = "SELECT CorrDetails FROM Action WHERE ProbID=137";
OleDbCommand command = new OleDbCommand(sqlString, dbConnection);
using (dbConnection)
{
MessageBox.Show(sqlString);
dbConnection.Open();
corrAct = (String)command.ExecuteScalar();
rtfCorrectiveAction.Text = Convert.ToString(corrAct);
dbConnection.Close();
}
Action is a reserved word in MS Access.
Wrap it with []:
string sqlString = "SELECT CorrDetails FROM [Action] WHERE ProbID=137";
The problem is you havent taken into account keywords in SQL. https://learn.microsoft.com/en-us/sql/odbc/reference/appendixes/reserved-keywords?view=sql-server-ver15
Action is a keyword so should not be used really in another context, to use them put [] round them some it becomes
select stuff from [Action] where stuff=true
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.
I am posting a query first time here, So, Please ignore my formatting.
I am trying to update my .accdb file using update command, but result of oledbcommand.executeNonQuery() is 0 hence result is not updating in the database.
Though I am receiving no errors.
Here is what I am doing.
string vsql = string.Format("UPDATE DefTask_List SET [Action]=#Action WHERE [SNo]=#SNo");
vcom.Parameters.AddWithValue("#SNo", row.Cells[0].Value.ToString());
vcom.Parameters.AddWithValue("#Action", comboBox1.Text);
OleDbCommand vcom = new OleDbCommand(vsql, vcon);
vcon.Open();
int k = vcom.ExecuteNonQuery();
vcom.Dispose();
vcon.Close();
Please note that SNo is an autonumber in my .accdb file also with the same way I am inserting and deleting data but that is working fine.
OleDbCommand doesn't support named parameters. The only matter is their orders.
From OleDbCommand.Parameters property
The OLE DB .NET Provider does not support named parameters for passing
parameters...
Therefore, the order in which OleDbParameter objects are added to the
OleDbParameterCollection must directly correspond to the position of
the question mark placeholder for the parameter in the command text.
That's why your first #Action in OleDbCommand matches with #SNo in your AddWithValue and #SNo matches with your #Action in your AddWithValue.
Since probably you don't have a data like this, there will be no update operation.
Switch your parameter orders and use .Add method which is recommended instead of AddWithValue. It may generate unexpected results. Read;
Can we stop using AddWithValue() already?
Also use using statement to dispose your OleDbConnection and OleDbCommand instead of calling .Dispose() and .Close() methods manually.
using(OleDbConnection vcon = new OleDbConnection(conString))
using(OleDbCommand vcom = vcon.CreateCommand())
{
vcom.CommandText = "UPDATE DefTask_List SET [Action]=#Action WHERE [SNo]=#SNo";
vcom.Parameters.Add("?", OleDbType.VarChar).Value = comboBox1.Text;
vcom.Parameters.Add("?", OleDbType.Integer).Value = (int)row.Cells[0].Value;
// I assume your column types are NVarchar2 and Int32
vcon.Open();
int k = vcom.ExecuteNonQuery();
}
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);
OK, nobody seems to know how to solve the problem I'm having looping through a cursor/result set for storage into a List, so I'm going to break it down into pieces and try to slog through it that way. So, first of all:
I add SQL Parameters to an OracleCommand object this way (works fine):
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
IOW, when I add the param, I pass the name of the parameterized portion of the SQL ("ABCID" above) and a value to give it (_ABCID is a variable that has been assigned, let's say, "42").
However, when adding a Cursor (output) param, it seems to want, not a value (such as an initialized cursor object), but simply the data type:
cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
(I tried both ways, and neither one works, so...?)
Verily/thus, my question is: Is this really the correct way of declaring a Cursor parameter to be outputted back for traversal/access?
I'm using the brand new version of DevArt DotConnect components (6.80.332), VS 2010, .NET 4
Updated:
Here's the code in more context:
public void PopulateCurrentUserRoles(String AUserName, List<String> ACurrentUserRoles) {
_UserName = AUserName;
String query = "select roleid from ABCrole where ABCid = :ABCID";
Devart.Data.Oracle.OracleCommand cmd = new Devart.Data.Oracle.OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
int _ABCID = GetABCIDForUserName();
cmd.Parameters.Add("cur", Devart.Data.Oracle.OracleDbType.Cursor);
cmd.Parameters["cur"].Direction = ParameterDirection.Output;
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
//cmd.ExecuteNonQuery(); blows up: "illegal variable name/number"
//cmd.ExecuteCursor(); " "
//cmd.ExecuteReader(); " "
Devart.Data.Oracle.OracleCursor oraCursor =
(Devart.Data.Oracle.OracleCursor)cmd.Parameters["cur"].Value;
Devart.Data.Oracle.OracleDataReader odr = oraCursor.GetDataReader(); // "Object reference not set to an instance of an object"
while (odr.Read()) {
ACurrentUserRoles.Add(odr.GetString(0));
}
}
the following is from the Oracle Data Provider for .NET Developer's Guide. yes, I know, "Devart". Nonetheless, It suggests the following:
Be careful with your parameter typing declaration.
add that cursor/output parameter to the Parameters collection before
any others.
As a long shot... my guide shows a OracleDbType.RefCursor but not a OracleDbType.Cursor. If DevArt has RefCursor, try that. In visual studio, what type does .NET think that parameter is? This question is not as dumb as I used to think.
... On the other hand, if the parameter is set as an OracleDbType.Char type by setting the OracleDbType property, the output data is returned
as an OracleString type. If both DbType and OracleDbType properties
are set before the command execution, the last setting takes affect.
. . .
"An application should not bind a value for output parameters; it is
the responsibility of ODP.NET to create the value object and populate
the OracleParameter Value property with the object. When binding by
position (default) to a function, ODP.NET expects the return value to
be bound first, before any other parameters."
EDIT:
Based on #Clay's self-answer... so there is no parameter specified for the output, rather one simply does this: OracleDataReader odr = cmd.ExecuteReader();
Straight from the horse's mouth (the DevArt folks):
_UserName = AUserName;
// From the DevArtisans:
String query = "select roleid from ABCrole where ABCid = :ABCID";
Devart.Data.Oracle.OracleCommand cmd = new Devart.Data.Oracle.OracleCommand(query, con);
cmd.CommandType = CommandType.Text;
int _ABCID = GetABCIDForUserName();
cmd.Parameters.Add("ABCID", _ABCID);
cmd.Parameters["ABCID"].Direction = ParameterDirection.Input;
cmd.Parameters["ABCID"].DbType = DbType.String;
Devart.Data.Oracle.OracleDataReader odr = cmd.ExecuteReader();
while (odr.Read()) {
ACurrentUserRoles.Add(odr.GetString(0));
}
To quote Casey and the Sonshine Banned, "That's the way, Uh huh Uh huh, I like it, Uh huh Uh huh"; actually, I can't stand that crap, but I do kind of relate to that sentiment right about now.