Syntax error when running SQL command in C# - c#

cmd = new SqlCommand("Select Max(Date_Time) From Daily_Sale ", con); cmd.ExecuteNonQuery();
string date_tim = (string)cmd.ExecuteScalar();
MessageBox.Show("date time" + date_tim);
This shows date time in a message box, but when I call this query:
cmdc = new SqlCommand("Select Total_Sale from Daily_Sale Where Date_Time ="+ date_tim,con);
cmdc.ExecuteNonQuery();
I get a syntax error.
Date_Time is saved as nvarchar(50).

First, you need to use parameters to send data to SQL. Never concatenate strings of data to SQL statement. That's a security hole as it's an open door to SQL Injection attacks.
For more information, read How can prepared statements protect from SQL injection attacks? and Microsoft Docs - How to: Perform Parameterized Queries
Second, Never store dates as strings in your database. For date only values, use the Date data type. For time only values, use the Time data type. For date and time values, use the DateTime2 data type (why not use DateTime?).
For more information, read Aaron Bertrand's Bad habits to kick : choosing the wrong data type, and my answer on SO to this question.
Third, you don't need two queries to get the last value of total_sale from the database. You can do that in a single query, without any parameters at all:
SELECT TOP 1 Total_Sale
FROM Daily_Sale
ORDER BY Date_Time DESC
If you want the date time value as well, simply add that to the query:
SELECT TOP 1 Total_Sale, Date_Time
FROM Daily_Sale
ORDER BY Date_Time DESC

Related

How to set value from server side code to an asp.net TextBox with TextMode=“Time”? The time value comes from SQl Server database

SqlCommand comEData = new SqlCommand("SELECT * FROM election WHERE id=" + eid);
DataTable dtElection = edb.GetDataSetFromElectionDB(comEData);
TextBoxStartTime.Text = (TimeSpan.Parse(Convert.ToString(dtElection.Rows[0]["start_time"]))).ToString("hh:mm tt");
I would suggest;
Define your start_time column as time even if it is not.
You should always use parameterized queries when you generate your sql command. This kind of string concatenations are open for SQL Injection attacks.
If your column is time, you don't need to parse it to TimeSpan, you need just explicitly casting.
(TimeSpan)dtElection.Rows[0]["start_time"]
Also a TimeSpan can't be represented with am or pm designator. Those designators can be used with DateTime structure.

How do parameterized queries help against SQL injection?

In both queries 1 and 2, the text from the textbox is inserted into the database. What's the significance of the parameterized query here?
Passing txtTagNumber as a query parameter
SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(#TagNbr);" , conn);
cmd.Parameters.Add("#TagNbr", SqlDbType.Int);
cmd.Parameters["#TagNbr"].Value = txtTagNumber.Text;
Converting txtTagNumber to an integer before constructing the query
int tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */
INSERT into Cars values(tagnumber.Text); /* then is it the same? */
Also, here I would use Regular Expression validation to stop insertion of illegal characters.
Parameterized queries do proper substitution of arguments prior to running the SQL query. It completely removes the possibility of "dirty" input changing the meaning of your query. That is, if the input contains SQL, it can't become part of what is executed because the SQL is never injected into the resulting statement.
Imagine a dynamic SQL query
sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND
Pass=' + password
so a simple sql injection would be just to put the Username in as ' OR
1=1-- This would effectively make the sql query:
sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS='
+ password
This says select all customers where they're username is blank ('') or
1=1, which is a boolean, equating to true. Then it uses -- to comment
out the rest of the query. So this will just print out all the
customer table, or do whatever you want with it, if logging in, it
will log in with the first user's privileges, which can often be the
administrator.
Now parameterized queries do it differently, with code like:
sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'
parameters.add("User", username) parameters.add("Pass", password)
where username and password are variables pointing to the associated
inputted username and password
Now at this point, you may be thinking, this doesn't change anything
at all. Surely you could still just put into the username field
something like Nobody OR 1=1'--, effectively making the query:
sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND
Pass=?'
And this would seem like a valid argument. But, you would be wrong.
The way parameterized queries work, is that the sqlQuery is sent as a
query, and the database knows exactly what this query will do, and
only then will it insert the username and passwords merely as values.
This means they cannot effect the query, because the database already
knows what the query will do. So in this case it would look for a
username of "Nobody OR 1=1'--" and a blank password, which should come
up false.
Source: lavamunky.com; Nov 2011
SQL injection happens when a possible parameter has SQL within it and the strings are not handled as it should be
eg:
var sqlquerywithoutcommand = "select * from mytable where rowname = '" + condition+''";
and the condition is a string coming from the user in the request. If condition is malicious
say eg:
var sqlquerywithoutcommand = "select * from mytable where rowname = '" + "a' ;drop table mytable where '1=1"+"'";
you could end up running malicious scripts.
However, using parameters the input will be cleaned of any characters which might escape string characters, which means you can be ensured no matter what comes in it will not be able to run inject scripts.
Using the command object with parameters the SQL actually executed would look like this:
select * from mytable where rowname = 'a'';drop table mytable where 1=1'''
in essence it will be looking for a row with rowname = a';drop table mytable where 1=1'
and not running the remaining script.
Parameterized queries handles everything - why go to the trouble?
With parametrized queries, in addition to general injection, you get all the data types handled, numbers (int and float), strings (with embedded quotes), dates and times (no formatting problems or localization issues when .ToString() is not called with the invariant culture and your client moves to a machine with and unexpected date format).
Parameterized queries allow the client to pass the data separately form the query text.
Where on most free from text you would do validation + escaping.
Of course Parameterization don't help against other kind of injection, but as the parameter are passed separately, they are not use as execution text query.
A good analogy would be the "recent" execution bit used with most of the modern processor and Operating system to protect from buffer overflow. It still allows the buffer overflow but prevent the execution of the injected data.
It is quite understandable why one would feel so.
sqlQuery = "select * from users where username='+username+';"
vs
sqlQuery = "select * from users where username=#username;"
Both the above queries seem to do the same thing.But they actually don't.
The former uses input to for a query, the latter decides on the query but only substitutes the inputs as it is during the execution of the query.
To be more clear, the parameters' values are located some where on the stack where the variables' memory is stored and is used for search when needed.
So if we were to give ' OR '1'='1 as the input in username, the former would dynamically construct a new queries or queries as part of the sql query string sqlQuery which is then executed.
While on the same input, latter would search for ' OR '1'=' in the username field of the users table with the statically specified query in the query string sqlQuery
Just to consolidate it, this is how you use parameters to make query:
SqlCommand command = new SqlCommand(sqlQuery,yourSqlConnection);
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#username";
parameter.Value = "xyz";
command.Parameters.Add(parameter);

Insert and select date from SQL Server database

I have got the following exception when try to select data from SQL Server or inserting data in in with a C# windows application. I am passing the date in where clause of select query in single quotes like this '16/03/2011' The exception message is shown below:
The conversion of a char data type to
a datetime data type resulted in an
out-of-range datetime value.
Is there any perfect solution for inserting and selecting date from sqlserver database irrelevant to the operating system. i.e. that works on both Italian and English OS.
If you can't use stored procs, or parameterized queries, you might want to format the date in a yyyy-mm-dd format. Ex. '2011-03-16'
T-SQL SAMPLE
INSERT INTO MyTable (SomeDate) VALUES ('2011-03-16')
or
SELECT * FROM MyTable WHERE SomeDate <= '2011-03-16'
Also, keep in mind the time portion of the date. If time is not important, then make sure you don't store it, because it could impact your SELECT queries down the road.
Use stored procedures, or parameterized queries. These will let you pass in a C# datetime object, and the conversion will be handled automatically for you.
I would suggest starting with the SQLDataAdapter class. A simple example of this would be:
using (SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM MyTable WHERE myDate = #myDate", someSqlConnection)
{
da.SelectCommand.Paramaters.Add("#myDate", new DateTime());
DataTable dt = new DataTable();
da.Fill(dt);
}
However, be aware that there are many different ways of achieving your goal. From your question, I would imagine you are creating SQL strings and executing them against your database. This is considered a Bad Practice for lots of reasons (including the one you describe). Read up about ORMs such as Entity Framework or NHibernate.

date time now format

Hi I try to insert into DB date time and the Column is date type what I need to do?
this is the code
string query = "INSERT INTO Feedback (user_Name, date_of_, Praise) VALUES ('"+TextBox1.Text+"',"+DateTime.Now+",'"+TextBox2.Text+"')";
SqlCommand cmd = new SqlCommand(query, con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
I would advise against using time from the application server to insert values into the database. The most basic example how that can go wrong is that you could have two servers set to different time zones, that use the same database. What server's time is the right time?
Other thing is the neccessary transformation of a datetime to string when you are using inline SQL statements. If the application server and the database server are set to different cultures, you need to be extremely careful not to insert May 2nd (02.05), when you want to insert Feb 5th (02.05).
Sure, all these issues are avoidable, but why bother with them at all, when the RDBMS can do all that for us?
BTW, even if you don't want to use stored procedures, use parameters.
This code should be reformated like:
string query = "INSERT INTO Feedback (user_Name, date_of_, Praise) VALUES (#username, getdate(), #praise)";
SqlCommand cmd = new SqlCommand(query, con);
SqlParameter param = new SqlParameter("#username", SqlDbType.Text);
param.Value = text1;
cmd.Parameters.Add(param);
param = new SqlParameter("#praise", SqlDbType.Text);
param.Value = text2;
cmd.Parameters.Add(param);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Don't include the value directly in your SQL.
Use a parameterized query instead. There's no point in messing around with string formatting when the database is quite capable of accepting a prepared statement with a DateTime parameter.
You should get in the habit of using query parameters for all values which can't be simply hard-coded into the SQL to start with. For example, your query is currently just blithely taking the contents of TextBox1.Text and inserting that into the SQL. That's a recipe for a SQL injection attack.
You should separate the code (the SQL) from the data (the values). Parameterized queries are the way to do that.
EDIT: Using a built-in function in the SQL is fine, of course, if you're happy to use the database's idea of "now" instead of your client's idea of "now". Work out which is more appropriate for your situation.
Why don't you use a TIMESTAMP column in your database ? Seems like overhead by inserting it through your code.
The following link provides more info:
http://msdn.microsoft.com/en-us/library/aa260631(SQL.80).aspx
edit: Set the default value of your database column as CURRENT_TIMESTAMP (Transact-SQL), and leave the column name out of your insert statement. The current date and time will be inserted by your database automatically. No problem with conversions anymore!
Replace DateTime.Now with DateTime.Now.ToString("yyyy-MM-dd");
Also, you should really parameterize your insert statement so that you cannot fall victim of a SQL injection attack.
There is a NOW() function in most SQL implementations.
You have to convert your DateTime to an Sql DateTime literal. The easiest way to do it is this:
DateTime.Now.ToString(System.Globalisation.CultureInfo.InvariantCulture)
Yet, especially for DateTime.Now, you may use some Sql function, such as GetDate() but that often depends on your database server.
You can use the Date property:
DataTime.Now.Date

c# query is not returning anything

here is my query:
select reporttime, datapath, finalconc, instrument from batchinfo
join qvalues on batchinfo.rowid=qvalues.rowid where qvalues.rowid
in (select rowid from batchinfo where instrument LIKE '%TF1%' and reporttime
like '10/%/2010%') and compound='ETG' and name='QC1'
i am running it like this:
// Create a database connection object using the connection string
OleDbConnection myConnection = new OleDbConnection(myConnectionString);
// Create a database command on the connection using query
OleDbCommand myCommand = new OleDbCommand(mySelectQuery, myConnection);
it does not return any results.
when i try this same query in sql server GUI it returns lots of rows
is there a problem specifically with the syntax of the query for c#?
please note that if i simplify the query like select * from table, there is no issue
Can you try using SqlCommand instead of OleDbCommand?
According to MSDN it: Represents a Transact-SQL statement or stored procedure to execute against a SQL Server database.
So if you really are using SQL Server 2008 you should probably use this. Any reason you are not?
How are you setting up the mySelectQuery string?
Could this be a problem with an escape character?
If you're not doing it already,
string mySelectQuery = #"query text here";
Personally I would run query profiler to see what query (if any) is being run, and then go from there.
Are you sure you are connecting to the same database in your code?
On a side note do you need the inner select? Couldn't you write this query as follows.
select reporttime,
datapath,
finalconc,
instrument
from batchinfo
join qvalues on batchinfo.rowid = qvalues.rowid
where compound = 'ETG'
and name = 'QC1'
and batchinfo.instrument like '%TF1%'
and batchinfo.reporttime like '10/%/2010%'
Edit - Never mind, just read the comment that your date is in a varchar field. Will leave this here since it may still be useful information.
Try this:
reporttime like 'Oct%2010%'
I have a test table here and when I query it using
where LastModified like '11/%/2010%'
no rows are returned, although all of the rows in the table have dates in November 2010. When I run the same query using like 'Nov%2010%', it returns all rows.
Details can be found here:
The LIKE clause can also be used to search for particular dates, as well. You need to remember that the LIKE clause is used to search character strings. Because of this the value which you are searching for will need to be represented in the format of an alphabetic date. The correct format to use is: MON DD YYYY HH:MM:SS.MMMAM, where MON is the month abbreviation, DD is the day, YYYY is the year, HH is hours, MM is minutes, SS is seconds, and MMM is milliseconds, and AM designates either AM or PM.

Categories