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.
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.
I understand that using parameters with your queries prevents SQL injection (when obtaining values from user input). But if I wanted to construct a query that uses predefined values e.g.
MySqlCommand Command = Connection.CreateCommand();
Command.CommandText = "SELECT employee_address FROM employees WHERE employee_name = #employee_name";
Command.Parameters.AddWithValue("employee_name", "John");
Can I not use this instead?
MySqlCommand Command = Connection.CreateCommand();
Command.CommandText = "SELECT employee_address FROM employees WHERE employee_name = 'John'";
Is it necessary to use parameters in this scenario?
Can I also do it this way?
string employee_name = "John"; //value depends on some sort of selection (not user input)
MySqlCommand Command = Connection.CreateCommand();
Command.CommandText = "SELECT employee_address FROM employees WHERE employee_name = '" + employee_name + "'";
I recommend always using parameters. With a string it is simple, but guess you have a boolean, decimal or date. It helps not to think about the formatting.
With parameters your sql-statement can be shorter if you use #0, #1, #2. You could even write a function with a param-array which replaces according to the order of #0, #1, #2. This saves a lot of code. (e.g. ExecuteSql(sql as string, paramarray myParameters as object)
How do I make it so that my query only update the data I want?
Here's the current code
string query = string.Format("update Customer set title='{0}',[Name]='{1}'",titleComboBox2.Text,nameTextBox2.Text,"where ID="+idTextBox+"");
Apparently the last part of the query isn't working. Why it is that?
Because you didn't use any index argument as {2} for your third argument which is WHERE part.
That's why your query will be contain only update Customer set title='{0}',[Name]='{1}' part this will be update for your all rows since it doesn't have any filter.
Fun fact, you could see this as query if you would debug your code.
But more important
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Let's assume you use ADO.NET;
using(var con = new SqlConnection(conString))
using(var cmd = con.CreateCommand())
{
cmd.CommandText = #"update Customer set title = #title, [Name] = #name
where ID = #id";
cmd.Paramter.Add("#title", SqlDbType.NVarChar).Value = titleComboBox2.Text;
cmd.Paramter.Add("#name", SqlDbType.NVarChar).Value = nameTextBox2.Text;
cmd.Paramter.Add("#id", SqlDbType.Int).Value = int.Parse(idTextBox.Text);
// I assumed your column types.
con.Open();
cmd.ExecuteNonQuery();
}
Currently your query does not use WHERE clause, because it is ignored by string.Format. You have 3 placeholder parameters, and you are using only {0} and {1}, so WHERE part is never added to the SQL query. Change your query to include WHERE clause, e.g. like this:
string query = string.Format("update Customer set title='{0}',[Name]='{1}' {2}",titleComboBox2.Text,nameTextBox2.Text,"where ID="+idTextBox.Text+"");
However, there is one very serious flaw in your code - it is vulnerable to SQL injection attack. There are hundreds of articles about it online, make sure to read about what that is and how to update your code accordingly (hint - parametrize queries)
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();
well, the question is clear i hope, the code is this:
string sql = "delete from #tabelnaam";
SqlCommand sc = new SqlCommand();
sc.Connection = getConnection();
sc.CommandType = CommandType.Text;
sc.CommandText = sql;
SqlParameter param = new SqlParameter();
param.Direction = ParameterDirection.Input;
param.ParameterName = "#tabelnaam";
param.Value = tableName;
sc.Parameters.Add(param);
OpenConnection(sc);
sc.ExecuteScalar();
tableName is supplied to this function.
I get the exception:
Must declare the table variable #tabelnaam
IIRC, you cant use a substitute the table name for a parameter.
Rather build the SQL string containing the correct table name.
Make to changes
rather than using paramter use this
string sql = string.format( "delete from {0}",tableName);
make use of executenonquery intead of ExecuteScalar
sc.ExecuteNonQuery();
As mentioned by others, you can't parameterise the table name.
However, as you rightly mention in comments on other answers, using simple string manipulation potentialy introduces a SQL injection risk:
If your table name input is fro an untrusted source, such as user input, then using this:
string sql = string.format( "DELETE FROM {0}",tableName);
leaves you open to the table name "myTable; DROP DATABASE MyDb" being inserted, to give you:
DELETE FROM myDb; DROP DATABASE MyDB
The way round this is to delimit the table name doing something such as this:
string sql = string.format("DELETE FROM dbo.[{0}]", tableName);
in combination with checking that the input does not contain either '[' or ']'; you should probably check it also doesn't contain any other characters that can't be used as a table name, such as period and quotes.
I dont think you can parameterize the table name. From what I have read you can do it via Dynamic sql and calling sp_ExecuteSQL.
Your SQL is incorrect, you are deleting from a table variable yet you haven't defined that variable.
Update: as someone has pointed out, you are trying to dynamically build a query string but have inadvertantly used SQL parameters (these do not act as place holders for string literals).
More here:
Parameterise table name in .NET/SQL?
You cannot parameterise the table name, you have to inject it into the command text.
What you can and should do is protect yourself against SQL injection by delimiting the name thus:
public static string Delimit(string name) {
return "[" + name.Replace("]", "]]") + "]";
}
// Construct the command...
sc.CommandType = CommandType.Text;
sc.CommandText = "delete from " + Delimit(tableName);
sc.ExecuteNonQuery();
See here and here for more background info.