SQL DATEDIFF Function returns wrong values - sql

Im executing following sql statement to get the sum values using date difference as a condition. "t_QueryDemand" is the table name and "DESIRED_SHIP_DATE" is the value I compare with current system date. But, I always get a date difference higher than 44100, even though the actual difference is between 0-60. DESIRED_SHIP_DATE data type is datetime2(7). I'm using MS SQL server database. What could be the issue.
Dim curDate As Date = Date.Today()
Dim strSql7DayDemand As date= "SELECT SUM(ORDER_QTY) AS ORDQTY, (TOTAL_SHIPPED_QTY) AS SHIPQTY, DATEDIFF(day," & curDate & ",DESIRED_SHIP_DATE),DESIRED_SHIP_DATE as DIFF from t_QueryDemand where ID='" & Trim(txtPartID.Text) & "' AND DATEDIFF(DAY," & curDate & ",DESIRED_SHIP_DATE) >" &

Instead of using a injection use the SQL function GETDATE()
DATEDIFF(day,GETDATE(),DESIRED_SHIP_DATE)
This will calculate the date on the server instead of locally like you are currently doing.
As has been pointed out you have a serious security vulnerability -- you need to use parameterized queries and not string concatenation or you are vulnerable to an SQL injection attack.
It will also make your code more robust -- right now you have txtPartID.Text and you are just putting that into your query but what if someone enters an non-number in this field -- you have no way of catching that now. With a parameterized query of a numeric type you would catch this problem when you converted the data entry to a number.

Related

Defining the result of a SQL Statement

I want to get the date from this SQL statement and use that as an ExpirationDate in asp classic so I can use that date in an if/then (conditional) statement. Lost on how to retrieve that. Appreciate the help.
strSQL = "SELECT SUM (Credits)[Amount] from TableName where id = '" & id & "' and date >= '4/1/2019' and date >= dateadd(day,-360,getdate())"
You can add another SQL query with dateadd(day,-360,getdate()) and get the expiration date. However, as you are getting the date based on your current date you can get it using ASP instead of SQL (i.e. DateAdd("d",1,Now())) assuming your ASP server and SQL server are in the same time zone.

Why do I sometimes see a date surrounded by #, as in #date#, in vba?

I came across this vba code recently that someone else had written
EffectiveDate >= "#" & datOnLevelDate & "# "
Can someone tell me the purpose of the "#" on either side of the date?
My guess is that the expression is constructing a dynamic SQL query for use in Microsoft Access, because in Access, date literals are enclosed in number signs:
SELECT * FROM Orders WHERE ShippedDate = #5/10/96#;
It is the vba delimiter to indicate that "date" is in a date format.

Rounding dates to the day in an SQL query

I am stuck with something. I am trying to take a long column of dates of which are formated to show also hours and minutes and run a Group query to paste values at the date level without acknowledging the differences in hours and minutes.. Unfortunately I have no clue how to start. The code i put together so far which returns each grouped date with the hour and minutes is as follows:
st_sql = "INSERT INTO [tblSearchEngine03] ([Date])" & _
"SELECT [tblSearchEngine02].[Date]" & _
"FROM [tblSearchEngine02]" & _
"GROUP BY [tblSearchEngine02].[Date]" & _
"ORDER BY [tblSearchEngine02].[Date]"
Application.DoCmd.RunSQL (st_sql)
Im not sure the best way to truncate the date on table "tblSearchEngine02"..
Focus on the SELECT piece first. You can use DateValue() for your Date field values. Start with this as a new query in the Access query designer:
SELECT DateValue(se02.Date)
FROM tblSearchEngine02 AS se02
GROUP BY se02.Date
ORDER BY se02.Date
Or you could use DISTINCT instead of GROUP BY:
SELECT DISTINCT DateValue(se02.Date)
FROM tblSearchEngine02 AS se02
ORDER BY se02.Date
After you have the SELECT working correctly, you can convert it to an INSERT query (the Access query designer calls it an "append" query).
And when you later build the same statement in your VBA code, include Debug.Print st_sql so that you can view the completed statement text in the Immediate window and make sure it is what you expected. (You can use Ctrl+g to go to the Immediate window.)
One way of doing this is to format the date/time as a date string. If you use YYYY/MM/DD it will sort properly. Otherwise you can convert the date/time to an int to trim off the time and then convert back to a date/time type.
Here is an example of formatting as string:
Format([tblSearchEngine02].[Date], "yyyy/mm/dd")
Here is an exmple of converting to get to a date (the end result will be a date/time data type so it might render as 03/16/2014 00:00 depending on your locale info)
CDate(CInt([tblSearchEngine02].[Date]))
Access stores its dates as floating point numbers where the integer part is the number of days since Jan 1, 1900 and the fractional part is the fraction of the day (time of day). Access is quite happy to treat these dates as numbers without doing any conversions, so:
fix([tblSearchEngine02].[Date])
will trim the fractional part of the day and set the time back to midnight and allow you to group by day.

Change date format in SQL for ASP

I have the following code:
"SELECT top 1 * FROM CensusFacility_Records WHERE Division_Program = 'Division 1' AND JMS_UpdateDateTime = '" & date & "'"
The date format in column JMS_UpdateDateTime is:
8/22/2013 12:00:07 AM
How can I make sure that my "date" in the query is converted to the correct time format?
My date variable in my SQL query is a real/date time. I would like for it to match the format within the JMS_UpdateDateTime field.
If your database table is small enough, you can cast the value to an actual datetime inside your query, and pass the value in as a datetime parameter, so you're comparing dates instead of comparing strings.
If your table has a decent amount of records, don't do this, because it will be a performance hog.
SELECT top 1 *
FROM CensusFacility_Records
WHERE Division_Program = 'Division 1'
AND cast(JMS_UpdateDateTime as datetime) = #dateParam
I believe SQL Server will be able to read the string that's in your database and automatically cast it properly, assuming your server settings are standard.
But in any case, use parameterized SQL instead of passing in a string like you've got.
The format of your SQL DateTime is actually a bit of a red herring here - it can be displayed in any way the front end (e.g. Management Studio) chooses. The important thing here is that your date variable is in an unambiguous format. With this in mind I'd recommend using the ISO 8601 date/time format, e.g. date.ToString("o") (assuming date is a DateTime).

Comparing two strings using SQL

I have the following command, used in a C# WinForms app that uses OleDb to connect to a Access 2010 database:
oc_payslips = new OleDbCommand("SELECT <fields> FROM Payslips WHERE LicenseID = \"" + IDs[cb_Employees.SelectedIndex] + "\" AND DateOfPayment >= \"" + startDate + "\" AND DateOfPayment <= \"" + endDate + "\"", DB_Connection.con);
This doesn't work. My best guess is that I cannot compare two strings like that using SQL.
The idea is to get the records that have a date between two dates, all of which have the "dd/MM/yyyy" format. The date is stored as a string in the database.
I couldn't find the answer to this on the internet, so here is my question:
Is there a way to compare two strings using SQL and determine which is alphabetically first?
P.S.: I know I can get all the dates first, compare them and then search for the IDs which have a correct date but my question is related to doing this in a single SQL query.
You have several problems
You should used parametrized commands instead of using string concatenation.
You are using double quotes instead of single quotes as string delimiters in SQL.
You are comparing dates as strings. If the table field if of type Date/Time, you would have to use a date litterals (if you persist in using string concatenation). If the dates are stored as strings formatted like "dd/MM/yyyy" the comparison will not work.
Same thing with LicenseID. If it is a numeric type compare LicenseID = 123 not LicenseID = "123".
The three last problems automatically disappear, if you use parametrized queries.
See: How to: Execute a Parameterized Query on MSDN.
oc_payslips = new OleDbCommand(
#"SELECT <fields> FROM Payslips
WHERE LicenseID = #lid AND
DateOfPayment >= #start AND DateOfPayment <= #end", DB_Connection.con);
oc_payslips.Parameters.AddWithValue("#lid", IDs[cb_Employees.SelectedIndex]);
oc_payslips.Parameters.AddWithValue("#start", startDate);
oc_payslips.Parameters.AddWithValue("#end", endDate);
...
It is a bad idea to store the dates as string in the database. If you want to compare dates stored as strings, it will only work if the strings are formatted as "yyyy/MM/dd" as Vlad Schnakovszki has pointed out in his comment. However, you could try to use
"... CDate(DateOfPayment) BETWEEN #start AND #end"
and make sure that you pass parameters of type DateTime.
http://www.tutorialspoint.com/sql/sql-string-functions.htm#function_strcmp
afaik if it returns -1 than the first string would be before the second using english alphabet