This is my code:
string query = "SELECT TEKN,KOMMENTAR FROM dbo.JOBBTEKN WHERE JOBBNR = " + jobId + ".00";
SqlDataReader reader = new SqlCommand(query, sqlConn).ExecuteReader();
This is my data:
I want to fetch multiple rows with the exact JOBBNR, but this returns nothing.
EDIT:
The query was working, it was just me being stupid and not searching in the right table. Sorry for wasting anyones time trying to help.
Include the jobId in single quotes. Modify your query to following:
"SELECT TEKN,KOMMENTAR FROM dbo.JOBBTEKN WHERE JOBBNR = '" + jobId + ".00'"
Observe the single quote around jobId.
Looking at the comments, I suspect the datatype of JOBBNR is float; NOT decimel. float datatype internally contains multiple precision, so when you try to match them in WHERE = clause, you may not get result due to mismatched precision.
There are multiple ways to handle this problem. Try something like following:
WHERE JOBBNR BETWEEN 1200.00 AND 1200.01
OR
"WHERE JOBBNR BETWEEN '" + jobId + ".00' AND '" + jobId + ".01'"
Related
I have been getting a syntax error in my UPDATE datagridview code which happens to work in another .cs file. My group has been looking at different solutions online but everything won't work.
My group has been looking at different solutions online but everything won't seem to work.
{
connection.Open();
OleDbCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Update Table1 set treatment = '" + treat.Text + "', remarks = '" + appRemarks.Text + "', cost = '" + treatCost.Text + "', Time = '" + textBox2.Text + "' where lastName = '" + Lastname.Text + "' ";
cmd.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Updated Successfully!");
}
The expected output should be Updated Successfully! and it should reflect in the database file after clicking the update button. Sometimes the output is "Microsoft Engine database" which does not save the changes.
The error says "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'" pointing to cmd.ExecuteNonQuery();
First, never use string concatenation to build a query. You're asking for a SQL Injection attack. The biggest thing I could see here is make sure that only columns that are string columns (varchar, char, text, etc..) have single-quoted values. Is cost a number? If so then it should be:
, cost=" + treatCost.Text + ",
If cost is a number, also make sure that there isn't a currency amount in the input field. If someone puts in 1,422.00 it's not a number and will fail since , is for decoration.
If someone puts in $1422.00 it's not a number as $ is for decoration.
Either of these would fail the query.
This would happen if someone types an apostrophe into the remarks field, which SQL server will interpret as the ending quote of the string. But much worse things can happen if the user knows a bit of sql and wants to cause trouble. For example, putting '-- in the remarks will result in
Update Table1 set treatment = 'blah', remarks = ''-- where lastName = 'foobar'
which will overwrite every row in the table, not only the one containing foobar.
Use query parameters so that user-provided values can't be interpreted as query keywords and structure.
Instead of remarks = '" + appRemarks.Text + "' you will have remarks = #Remarks as well as
cmd.Parameters.Add("#Remarks", SqlDbType.NText).Value = appRemarks.Text;
and all the other user inputs likewise.
Currently I am trying to retrieve the contents of all the entries between a specific date in a MySQL database named 'orders'. To achieve this I use the following code:
query = "SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between " + dateFrom + " and " + dateTill + " and print_location like 'antw'";
dateFrom and dateTill are both variables that contains timestamps.
Everything above works perfectly. The problem that I am facing right now is that I want to check on two print_locations instead of only one. As shown in the code above I only search on 'antw'. The code that I have right now to search on two print_locations is as follows:
query = "SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between " + dateFrom + " and " + dateTill + " and print_location like 'antw' or print_location like 'helm'";
But somehow this doesn't work. I don't get an error the form just freezes and making it unaccessible.
This is probably a simple issue to resolve but I can't seem to solve it. The reason why I am only showing the value of the query variable and not the rest of my code is because everything has worked fine for weeks.
you forgot brackets and you should use parameters to avoid injection attack
string Command = "SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between #dateFrom and #dateTill and (print_location like 'antw' or print_location like 'helm')";
using (MySqlConnection myConnection = new MySqlConnection(ConnectionString))
{
using (MySqlDataAdapter myDataAdapter = new MySqlDataAdapter(Command, myConnection))
{
myDataAdapter.SelectCommand.Parameters.Add(new MySqlParameter("#dateFrom", yourDateFrom));
myDataAdapter.SelectCommand.Parameters.Add(new MySqlParameter("#dateTill", yourdateTill));
DataTable dtResult = new DataTable();
myDataAdapter.Fill(dtResult);
}
}
Add brackets to your logic:
query = "SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between " + dateFrom + " and " + dateTill + " and (print_location like 'antw' or print_location like 'helm')";
Be careful though... this smells like a potential case of SQL injection!
Never worked with MySQL, but maybe you're forgetting %% on your LIKE clauses. The way it is, it will work like =.
SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between " + dateFrom + " and " + dateTill + " and (print_location like '%antw%' or print_location like '%helm%')
You need parentheses on your second set "OR" of conditions:
query = "SELECT id, date, contactinfo, orderinfo, contents, print_location, order_id, file_size FROM orders where date between " + dateFrom + " and " + dateTill + " and (print_location like 'antw' or print_location like 'helm')";
Otherwise, your statement reads like this:
Get me all this stuff, where date between this date and this date, and print_location like 'antw'...
Or get me all this stuff where print_location like 'helm'.
Since you're using a like, it's probably just freezing while executing your query. It would eventually finish, and you'd have way more results than you were expecting.
Also, because of injection concerns, and data modeling, you should really use a data access object model (DAO). I suggest researching it!
string queryString4 = "UPDATE Table1 SET currentMoney =currentMoney + '" + money + "'WHERE accountNo='" + recipientNo + "';";
user1 & user2 have $100
user1 transfer $5 to user2.
user1 now have $95 & user2 now have $1005
Somehow it did not calculate properly. Im suspecting the code above because I did a querystring3 which is minus instead of a plus and it works. However querystring4 is a bit of a problem.
You're appending a string here:
currentMoney =currentMoney + '" + money + "'
Let's assume that money is 5, this becomes:
currentMoney =currentMoney + '5'
In many languages this will result in an implicit conversion of the numeric value to a string value, so:
100 + '5' = '1005'
Then when you store it, I guess it was implicitly converted back to a numeric value? It's odd to me that you didn't receive an error message during any of this.
In any event, you're looking at two fixes:
For now, get rid of those single-quotes and treat the numeric value as a numeric value instead of a string value.
Don't build your queries by concatenating strings. The problem you're facing now is one of the lesser problems you'll encounter by doing this. Exposing yourself to SQL injection attacks is another, more significant problem. Use query parameters instead of string concatenation.
This is a textbook case. You need a transaction to encapsulate the two commands.
You also need to use a parameterized query and not a string concatenation.
decimal sumOfTransaction = 5m;
string creditAccount = "123456ABC";
string debitAccount = "ABC9876543";
using(TransactionScope scope = new TransactionScope())
using(SqlConnection cn = new SqlConnection(connectionString))
{
string upd1 = #"UPDATE Table1 SET currentMoney = currentMoney + #amount
WHERE accountNo=#account";
string upd2 = #"UPDATE Table1 SET currentMoney = currentMoney - #amount
WHERE accountNo=#account";
cn.Open();
using(SqlCommand cmd = new SqlCommand(upd1, cn);
{
cmd.Parameters.AddWithValue("#amount", sumOfTransaction);
cmd.Parameters.AddWithValue("#account", creditAccount);
cmd.ExecuteNonQuery();
cmd.CommandText = upd2;
cmd.Parameters["#account"].Value = debitAccount);
cmd.ExecuteNonQuery();
}
scope.Complete();
}
The use of a transaction is mandatory here, because you don't want, for ANY reason to credit some amout of money to one account and for whatever reason miss to debit the other account.
(In real cases you need a lot more than this. For example, this code lacks of any checks against the amount available in the debit account).
Of course your initial error is due to the fact that you are treating your amount as it was a string but this is plainly wrong. When dealing with money values you should not rely on implicit conversions of any kind.
compose sql string in this way is a very bad practice. You should use Sql Parameters instead.
Anyway, try this way:
string queryString4 = "UPDATE Table1 SET currentMoney =currentMoney + (" + money + ") WHERE accountNo='" + recipientNo + "';";
But i strongly advise you to use parameters.
string queryString = "SELECT SUM(skupaj_kalorij)as Skupaj_Kalorij "
+ "FROM (obroki_save LEFT JOIN users ON obroki_save.ID_uporabnika=users.ID)"
+ "WHERE (users.ID= " + a.ToString() + ") AND (obroki_save.datum= #datum)";
using (OleDbCommand cmd = new OleDbCommand(queryString,database))
{
DateTime datum = DateTime.Today;
cmd.Parameters.AddWithValue("#datum", datum);
}
loadDataGrid2(queryString);
I tried now with parameters. But i don't really know how to do it correctly. I tried like this, but the parameter datum doesn't get any value(according to c#).
please try this :
database = new OleDbConnection(connectionString);
database.Open();
date = DateTime.Now.ToShortDateString();
string queryString = "SELECT SUM(skupaj_kalorij)as Skupaj_Kalorij "
+ "FROM (obroki_save LEFT JOIN users ON obroki_save.ID_uporabnika=users.ID)"
+ "WHERE users.ID= " + a.ToString()+" AND obroki_save.datum= '" +DateTime.Today.ToShortDateString() + "'";
loadDataGrid2(queryString);
when you use with Date, you must write like this
select * from table where date = '#date'
not like
select * from table where date = #date
While it's usually useful to post the error, I'd hazard a guess and say that you're getting a conversion error with your date.
You should really look at parameterising your queries...
You should read this: http://www.aspnet101.com/2007/03/parameterized-queries-in-asp-net/
And if you can't be bothered reading that, then try changing your 'a' variable to '1; DROP TABLE obroki; --' (but only after you back up your database).
Perhaps you need to write your SQL string in the SQL dialect of the database you're using. In Jet/ACE SQL (what's used by Access), the delimiter for date values is #, so you'd need this:
obroki_save.datum= #" +DateTime.Today.ToShortDateString() + "#"
Of course, some data interface libraries translate these things for you, so that may not be the problem here.
Ok, I have a list that consists of a bunch of values from a sql query, that part works fine. What I want to do is use the items in that list to tell another query what to look for. So, what it is saying is that, it should return all columns from CMMReports where PartNumber is like %listItem1..2...3%, Any advice?
List<string> ImportedParts = GetImportedPartNumbers();
string query = "SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') AND (FilePath NOT LIKE '%js91162%') AND PartNumber LIKE %" + ImportedParts + "% ORDER BY CreatedOn DESC;";
Not that I condone this as you should be using parameterized queries. However, this should work:
StringBuilder partNumbers = new StringBuilder();
foreach (string queryValue in ImportedParts)
{
string q = "PartNumber LIKE '%" + queryValue + "%'";
if (string.IsNullOrEmpty(partNumbers.ToString())
{
partNumbers.Append(q);
}
else
{
partNumbers.Append(" OR " + q);
}
}
string query = string.Format("SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') " +
"AND (FilePath NOT LIKE '%js91162%') AND ({0}) " +
"ORDER BY CreatedOn DESC;", partNumbers.ToString());
You might look up the IN clouse for SQL that way you get the answer for the parts that SQL Server can find in the database. Using WHERE x = y for all the items means that if one item can't be found the whole query returns nothing.
I would consider doing this in a stored procedure and passing in your list as an Xml parameter.
See the following article for more info on using Xml parameters in a stored proc:
Passing lists to SQL Server 2005 with XML Parameters - By Jon Galloway
Form there you can easily use your list data inside your stored proc using the Xml syntax and treat it almost as another table of data.
Untested, but you should get the idea:
List<string> ImportedParts = GetImportedPartNumbers();
SqlCommand cmd = myConnection.CreateCommand();
cmd.CommandText = "SELECT * FROM CMMReports WHERE (RacfId IS NULL OR RacfId = '') AND (FilePath NOT LIKE '%js91162%') AND (";
int i = 0;
foreach (string part in ImportedParts) {
cmd.AddParameterWithValue("#param" + i.ToString(), "%" + part + "%");
if (i != 0) cmd.CommandText += " OR"
cmd.CommandText += " PartNumber LIKE #param" + i.ToString();
i++;
}
cmd.CommandText += ") ORDER BY CreatedOn DESC;";
This solution uses a parameterized query instead of just appending strings in the SQL, which is considered a potential security risk.