So I've got this code:
query2 = "SELECT * from Clicking WHERE ID = '" + ID + "'";
And it seems to make problems with the script, probably I'm mistaken with something here.
For instance, when I write this:
query2 = "SELECT * from Clicking WHERE ID = 3";
..this works just fine, and the script continue with no problems. But with my original code it shows me this error:
OleDbException was unhandled by user code
An exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll but was not handled in user code
Any suggestions how to make this work?
When you use single quotes the 3 is treated as string, and probably your ID column is an int, that's why you are getting the exception .
Also do not use string concatenation, use parameterized queries to prevent SQL injection attacks
query2 = "SELECT * from Clicking WHERE ID = #id";
using(var cmd = new SqlCommand(query2, connection))
{
cmd.Parameters.AddWithValue("#id", ID);
...
}
The way you have the query written it will be like this:
SELECT * from Clicking WHERE ID = '3'
The '' around a number means it will look for an ID as a string that is equal to 3. So you want to remove the single quotes around the number, so it will search for a number that is equal to 3, or whatever number you use. This is what you want:
query2 = "SELECT * from Clicking WHERE ID = " + ID;
Related
I'm having problems with some code I'm trying to write. I'm doing something for suppliers orders, so I have a table which is named "encomendas_fornecedores" with a autoincrement field before the key that is the code of sale which consists in a EF before the number(which is a text field).
Here is the code:
connection.Open();
OleDbCommand comando1 = new OleDbCommand();
OleDbCommand comando2 = new OleDbCommand();
OleDbCommand comando3 = new OleDbCommand();
comando1.Connection = connection;
comando2.Connection = connection;
comando3.Connection = connection;
comando1.CommandText = "INSERT INTO encomendas_fornecedores (cod_encomenda_forn, cod_metodo, cod_forn, total_pagar_forn) VALUES('FO', '" + txtcodmetodo.Text + "', '" + txtcodforn.Text + "', '" + lbltotalapagar.Text + "'); ";// insert into table the values with a FO to cod
comando1.ExecuteNonQuery();
comando2.CommandText = "Select MAX(num_encomenda) From encomendas_fornecedores;";// selecting maximum num encomenda so I can isolate it and add to a text before(btw I do this in php/sql no problems
int numero = Convert.ToInt32(comando2.ExecuteScalar());//max num_encomenda
string codencomendaforn= "EF"+Convert.ToString(numero);// sales code completed
comando3.CommandText = "UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = '"+ numero +"';";//query that is giving me the problems, it says something like "type of data incorrect in data expression"
comando3.ExecuteScalar();//giving me error this line
connection.Close();
But now here's the catch the cod_encomenda_forn is text and the num_encomenda auto increment as it is in the sql, and I tried to show the query in a textbox to see if its anything is wrong but nothing seems wrong.
"UPDATE encomendas_fornecedores SET cod_encomenda_forn = '"+codencomendaforn+"' WHERE num_encomenda = **'**"+ **numero** +"**'**;";//query that is giving me the problems,it says something like "type of data incorrect in data expression"
You are passing a string numero to a where statement that seems like it is expecting a number. As long as it is numeric it should work, but definitely not gauranteed to work. Second you are passing anothercodencomendaforn string to encomenda what is encomenda 's data type?
It appears that you are not handling potential datatype differences between your c# code and your SQL query. In addition single quoting '' around a value in a SQL statement tells the database engines that it is a string even if that is '1234'. While SQL will automatically convert some values it doesn't always. In addition c# .net library also looks for some conversion etc. before sending the SQL statement. To fix appropriately use parameters that are data typed to the database type in the SQL table. To fix it simply in the statement figure out your data types and fix the '' single quotes appropriately.
PS the people trying to help you in the comments were being nice and telling you the professional way of keeping your job in the future when you graduate after fixing this issue.
I have a slight issue, I have a ASP.NET Webforms application. I'm sending over a url?id=X were X is my database index or id.
I have a C# class file to run my SQL connection and query. Here is the code:
public DataTable ViewProduct(string id)
{
try
{
string cmdStr = "SELECT * Products WHERE Idx_ProductId = " + id;
DBOps dbops = new DBOps();
DataTable vpTbl = dbops.RetrieveTable(cmdStr, ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
return vpTbl;
}
catch (Exception e)
{
return null;
}
}
So as you can see my problem lies within string cmdStr = "SQL Query" + variable;
I'm passing over my index or id through the URL then requesting it and turning it into a string then using ViewProduct(productId).
I don't know what syntax or how to add the id into my C# string sql query. I've tried:
string cmdStr = "SELECT * Products WHERE Idx_ProductId = #0" + id;
string cmdStr = "SELECT * Products WHERE Idx_ProductId = {0}" + id;
also what I have currently to no avail.
I was so sure this would be a duplicate of some canonical question about parameterized queries in C#, but apparently there isn't one (see this)!
You should parameterize your query - if you don't, you run the risk of a malicious piece of code injecting itself into your query. For example, if your current code could run against the database, it would be trivial to make that code do something like this:
// string id = "1 OR 1=1"
"SELECT * Products WHERE Idx_ProductId = 1 OR 1=1" // will return all product rows
// string id = "NULL; SELECT * FROM UserPasswords" - return contents of another table
// string id = "NULL; DROP TABLE Products" - uh oh
// etc....
ADO.NET provides very simple functionality to parameterize your queries, and your DBOps class most assuredly is not using it (you're passing in a built up command string). Instead you should do something like this:
public DataTable ViewProduct(string id)
{
try
{
string connStr = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
// #id is very important here!
// this should really be refactored - SELECT * is a bad idea
// someone might add or remove a column you expect, or change the order of columns at some point
cmd.CommandText = "SELECT * Products WHERE Idx_ProductId = #id";
// this will properly escape/prevent malicious versions of id
// use the correct type - if it's int, SqlDbType.Int, etc.
cmd.Parameters.Add("#id", SqlDbType.Varchar).Value = id;
using (SqlDataReader reader = cmd.ExecuteReader())
{
DataTable vpTbl = new DataTable();
vpTbl.Load(reader);
return vpTbl;
}
}
}
}
catch (Exception e)
{
// do some meaningful logging, possibly "throw;" exception - don't just return null!
// callers won't know why null got returned - because there are no rows? because the connection couldn't be made to the database? because of something else?
}
}
Now, if someone tries to pass "NULL; SELECT * FROM SensitiveData", it will be properly parameterized. ADO.NET/Sql Server will convert this to:
DECLARE #id VARCHAR(100) = 'NULL; SELECT * FROM SensitiveData';
SELECT * FROM PRoducts WHERE Idx_ProductId = #id;
which will return no results (unless you have a Idx_ProductId that actually is that string) instead of returning the results of the second SELECT.
Some additional reading:
https://security.stackexchange.com/questions/25684/how-can-i-explain-sql-injection-without-technical-jargon
Difference between Parameters.Add and Parameters.AddWithValue
SQL injection on INSERT
Avoiding SQL injection without parameters
How do I create a parameterized SQL query? Why Should I? (VB.NET)
How can I prevent SQL injection in PHP? (PHP specific, but many helpful points)
Is there a canonical question telling people why they should use SQL parameters?
What type Products.Idx_ProductId is?
Probably it is string, than you need to use quotes: "... = '" + id.Trim() + "'";
I have a button which adds products to the invoice, I want it to delete products off the database as well, how can I edit this query so it deletes from the database?
I think my error is because of the way I am converting cmbQuantity.Text, can someone help me with a fix?
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - '" + Convert.ToInt32(cmbQuantity.Text) + "' WHERE productName='" + cmbProdName.Text + "'", con);
Without the error message, it's hard to guess.
But at first sight, you have a typo here : quantityAvailable=quantityAvailabe - should be quantityAvailable=quantityAvailab**l**e -.
Moreover, you must not quote the integer part, so '" + quantityToRemove + "' becomes " + quantityToRemove + ". But the best is to use parametrization, which will simplify your code. See Why do we always prefer using parameters in SQL statements?
Try to separate access to your UI and building your SQL:
int quantityToRemove = Convert.ToInt32(cmbQuantity.Text);
string productName = cmbProdName.Text;
string sqlUpdate = #"UPDATE Product
SET quantityAvailable = quantityAvailable - #quantityToRemove
WHERE productName= #productName";
SqlCommand inventorycontrol = new SqlCommand(sqlUpdate, con);
inventorycontrol .Parameters.AddWithValue("quantityToRemove", quantityToRemove);
inventorycontrol .Parameters.AddWithValue("productName", productName);
In the question you have not specify the error, but there may be chances of getting error in your code. that i will clarify you.
When it failed to convert the cmbQuantity.Text to int, you need not to pass an integer within double quotes :- Here my suggested answer will help you to handle this error by showing error message if the quantity is invalid.
The query you are using opens a wide range to SQL Injection. I suggest you to use parameterized query to avoid injection, As a whole you can use like the following:
int quantity;
if (int.TryParse(cmbQuantity.Text, out quantity))
{
SqlCommand inventorycontrol = new SqlCommand("Update Product SET quantityAvailable=quantityAvailabe - #Quantity WHERE productName=#prodName", con);
inventorycontrol.Parameters.AddWithValue("#Quantity",quantity);
inventorycontrol.Parameters.AddWithValue("#prodName", cmbProdName.Text);
//Execue command here
}
else
{
// show message invalid quantity
}
This question already has answers here:
SqlCommand with Parameters
(3 answers)
Closed 8 years ago.
Hi this is my query
SELECT StraightDist FROM StraightLineDistances
WHERE (FirstCity='007' AND SecondCity='017');
How can I pass this in to sql statement?
I want to replace the city numbers '007' and '017' with variables
string destcity;
string tempcityholder1;
What I tried is this
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='" + tempcityholder1 + "' AND SecondCity='" + destcity + "');", mybtnconn2);
it didn't give me the expected output.
But when i tried with the original sql as given below it worked.
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='007' AND SecondCity='017');", mybtnconn2);
Can anyone point me the error here?
or a better solution.
This is for a personal application, security is not a must, so no need of parametrized queries. And I don't know how to implement parametrized queries with multiple parameters. If anyone can explain how to use a parametrized query it's great and I would really appreciate that. But just for the time being I need to correct this.
Any help would be great..
OK if with parametrized query
MY Work looks like this
SqlConnection mybtnconn2 = null;
SqlDataReader mybtnreader2 = null;
mybtnconn2 = new SqlConnection("");
mybtnconn2.Open();
SqlCommand mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity='007' AND SecondCity='017');", mybtnconn2);
mybtnreader2 = mybtncmd2.ExecuteReader();
while (mybtnreader2.Read())
{
MessageBox.Show(mybtnreader2.GetValue(0) + "My btn readre 2 value");
}
Can anyone give me a solution which doesn't complicate this structure.
If I use a parametrized query how can I edit
mybtnreader2 = mybtncmd2.ExecuteReader();
This statement?
This is the way to use parametrized queries:
string sqlQuery="SELECT StraightDist FROM StraightLineDistances WHERE (FirstCity= #tempcityholder1 AND SecondCity=#destcity);"
SqlCommand mybtncmd2 = new SqlCommand(sqlQuery, mybtnconn2);
mybtncmd2.Parameters.AddWithValue("tempcityholder1", tempcityholder1 );
mybtncmd2.Parameters.AddWithValue("destcity", destcity);
It's always good practice to use parameters, for both speed and security. A slight change to the code is all you need:
var mybtncmd2 = new SqlCommand("SELECT StraightDist FROM StraightLineDistances WHERE FirstCity=#City1 AND SecondCity=#City2;", mybtnconn2);
mybtncmd2.Parameters.AddWithValue("#City1", "007");
mybtncmd2.Parameters.AddWithValue("#City2", "017");
Use prepared statements: it's both easy and secure.
command.CommandText =
"INSERT INTO Region (RegionID, RegionDescription) " +
"VALUES (#id, #desc)";
SqlParameter idParam = new SqlParameter("#id", SqlDbType.Int, 0);
SqlParameter descParam =
new SqlParameter("#desc", SqlDbType.Text, 100);
You really won't do this, because this is an open door to SQL injection.
Instead you should use Stored Procedures for that approach.
In case your not familiar with SQL injection, let's make it clear:
Assume that you have a database with a table called 'T_USER' with 10 records in it.
A user object has an Id, a Name and a Firstname.
Now, let's write a query that select a user based on it's name.
SELECT * FROM T_USER WHERE Name= 'Name 1'
If we take that value from C#, this can really take unexpected behaviour.
So, in C# code we will have a query:
string queryVal;
var command = "SELECT * FROM T_USER WHERE Name = '" + queryVal + "'";
As long as the user is nice to your application, there's not a problem.
But there's an easy way to retrieve all records in this table.
If our user passes the following string in QueryVal:
demo' OR 'a' = 'a
Then our query would become:
SELECT * FROM T_USER WHERE Name = 'demo' OR 'a' = 'a'
Since the second condition is always true, all the records are retrieved from this table.
But we can even go further:
If the same user uses the following value in queryVal:
demo'; DELETE FROM T_USER--
The full query becomes:
SELECT * FROM T_USER WHERE Name = 'demo'; DELETE FROM T_USER--'
And all our records our gone.
And we can even go further by dropping the table:
queryVal needs to be:
demo'; DROP TABLE T_USER--
I think you get it. For more information google on Sql Injection:
I have the following problem trying to insert the following SQL server query into a C# method:
select *
from VulnerabilityReference
where Title = 'Message'
and convert(nvarchar(MAX), Description2) = N'http://www.securityfocus.com/archive/1/1201040152.5924.44.camel#laptop'
As you can see the Description2 field is casted
In Microsoft SQL Server Managment Studio the previous query work well and give me the following output:
Id Title Description2
52794 Message http://www.securityfocus.com/archive/1/1201040152.5924.44.camel#laptop
55340 Message http://www.securityfocus.com/archive/1/1201040152.5924.44.camel#laptop
55341 Message http://www.securityfocus.com/archive/1/1201040152.5924.44.camel#laptop
55342 Message http://www.securityfocus.com/archive/1/1201040152.5924.44.camel#laptop
Now I creat the following exist() method in C#
public long existReference(DataModel.Vulnerability.Reference reference)
{
long id = -1;
_strSQL = "SELECT * FROM VulnerabilityReference"
+ " WHERE Title = #REFERENCETITLE and convert(nvarchar(MAX), Description2) = N'#DESCRIPTION2' ";
System.Data.Common.DbCommand command;
command = _connection.CreateCommand();
_addParameter(command, "#REFERENCETITLE", reference.Title);
_addParameter(command, "#DESCRIPTION2", reference.Description2);
command.CommandText = _strSQL;
_dt = _fillDataTable(command);
if (_dt.Rows.Count == 0)
{
return -1;
}
id = _dt.Rows[0].Field<int>("Id");
return id;
}
The two field of the reference object contains the same values of the previous example but it don't work fine and found 0 records for this query.
Why? What could be the problem? How can I solve it?
Tnx
N'#DESCRIPTION2' is looking for the literal text #DESCRIPTION2 (not the value of the parameter by that name). If you want the parameter value, just use #DESCRIPTION2:
WHERE ...(blah)... = #DESCRIPTION2
Drop all things around variables that tell the parser what type of variable it is. That's already known:
N'#DESCRIPTION2'
in your statement needs to be
#DESCRIPTION2
your query should look like
_strSQL = "SELECT * FROM VulnerabilityReference"
+ " WHERE Title = #REFERENCETITLE and convert(nvarchar(MAX), Description2) = #DESCRIPTION2 ";