Date Interval for Expiry Purpose - sql

I am trying to list all medicines which are going be expiry within 90 days, but I am getting syntax error, could anyone let me know about.
Try
If (Me.conn.State = ConnectionState.Closed) Then
Me.conn.Open()
End If
Dim da As New SqlDataAdapter(("
select
ItemNo,Name,ManufacturerName,MedicineName,BatchNo,MedicineLocation,
CostPrice,SellPrice,QtyAvailable,ExpiryDate,StockValue
from ItemTypes,Items
where ItemTypes.ItemTypesId=Items.ItemTypesId
and ExpiryDate> '" & Strings.Format(DateAndTime.Now) & "' + INTERVAL 90 DAY "), conn)
Dim dataSet As New DataSet
Dim dt As New DataTable
da.Fill(dataSet, "dt")
Me.dgrdItems.DataSource = dataSet.Tables.Item(0)
Catch exception1 As Exception
ProjectData.SetProjectError(exception1)
Dim exception As Exception = exception1
Interaction.MsgBox(exception.Message, MsgBoxStyle.Critical, Nothing)
ProjectData.ClearProjectError()
End Try

My guess is that you are using a data base that doesn't understand interval. Here is how you would express this query in SQL Server:
select ItemNo, Name, ManufacturerName, MedicineName, BatchNo, MedicineLocation,
CostPrice, SellPrice, QtyAvailable, ExpiryDate, StockValue
from ItemTypes join
Items
on ItemTypes.ItemTypesId = Items.ItemTypesId
where ExpiryDate > getdate() + 90;
This makes two changes. First it uses explicit join syntax rather than the archaic syntax of implicit joins in the where clause. Second, it does the date comparison in the database.
Here is the where logic for some other databases:
MySQL:
where ExpiryDate > now() + interval 90 day
Oracle:
where ExpiryDate > sysdate + 90
Postgres:
where ExpiryDate > now() + interval '90 days'
Note that these also have time components, but those are usually easy to get rid of (in a database specific way).

Related

Date and Time Formatting in VB.net and SQL Server

I have a table in which data is been logged in 'yy/MM/dd HH:mm:ss' format and my regional setting is '2016-04-02 14:25:15' type. I want to get details in a following query but it is not populating any results
The query I used is
select
Date_time, alarm_id, alarm_message
from
table01
where
Date_time between '" & DateTimePicker5.Value & "' and '" & DateTimePicker6.Value & "'
I also tried using one function which I had written is
Private Function FormatDate(ByVal dat As String) As String
Dim FTDate As Date
FTDate = FormatDateTime(Convert.ToDateTime(dat), DateFormat.ShortDate)
FormatDate = Format(FTDate, "yy/MM/dd HH:mm:ss")
End Function
And used the same again in query as
select
Date_time, alarm_id, alarm_message
from
table01
where
Date_time between '" & formatdate(DateTimePicker5.Value) & "' and '" & formatdate(DateTimePicker6.Value) & "'
Please suggest appropriate answer make sure that I don't want to change my regional setting and on form load event. I've written the following code
DateTimePicker5.Format = DateTimePickerFormat.Custom
DateTimePicker5.CustomFormat = "yy/MM/dd HH:mm:ss"
DateTimePicker6.Format = DateTimePickerFormat.Custom
DateTimePicker6.CustomFormat = "yy/MM/dd HH:mm:ss"
The Table Is In Below Mentioned Format
**Datetime V1 P1**
16/08/29 19:12:24 10 STB-1
16/08/29 19:12:19 20 STB-1
16/08/29 19:12:18 30 STB-1
16/08/29 19:09:50 40 STB-1
Never ever ever EVER use string concatenation to put values into a query like that! It's practically begging to wake up one morning and find out your site was hacked six months ago.
The first thing you need to do is fix the schema, so that your date values are actually stored as DateTime columns. There are so many reasons for this, I can't even begin to describe them all. Just do it!
Once that's done, you build the query like this:
Const SQL As String = _
"SELECT Date_time, alarm_id, alarm_message
FROM table01
WHERE Date_time between #StartTime AND #EndTime"
Hey, look: it's a constant. Now that's not strictly necessary; I usually just use a normal Dim'd String value. However, I wanted to prove a point here: your SQL statement is set to use specific place holders that will never at any point have data in them. The values you provide for those #StartTime and #EndTime values will be completely separated and quarantined from your SQL command, such that no possibility for injection ever exists.
Once you have the SQL command string, you can use it like this (repeating the string definition so everything is in one place):
Const SQL As String = _
"SELECT Date_time, alarm_id, alarm_message
FROM table01
WHERE Date_time between #StartTime AND #EndTime"
Using cn As New SqlConnection("connection string here"), _
cmd As New SqlCommand(SQL, cn)
cmd.Parameters.Add("#StartTime", SqlDbType.DateTime).Value = DateTimePicker5.Value
cmd.Parameters.Add("#EndTime", SqlDbType.DateTime).Value = DateTimePicker6.Value
cn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
' ...
End While
End Using
End Using
Or if you're filling a DataTable:
Dim result As New DataTable()
Const SQL As String = _
"SELECT Date_time, alarm_id, alarm_message
FROM table01
WHERE Date_time between #StartTime AND #EndTime"
Using cn As New SqlConnection("connection string here"), _
cmd As New SqlCommand(SQL, cn), _
ad As New SqlDataAdapter(cmd)
cmd.Parameters.Add("#StartTime", SqlDbType.DateTime).Value = DateTimePicker5.Value
cmd.Parameters.Add("#EndTime", SqlDbType.DateTime).Value = DateTimePicker6.Value
ad.Fill(result)
End Using
Note that using this method, you never have to worry about your DateTime format. ADO.Net figures it out for you. It knows about .Net DateTime objects, and it knows about Sql Server DateTime columns, and it handles conversions between the two types naturally.
This is some what a tricky solution.
Since year kept as 'yy' in the backend,following are the assumptions.
if the year part of the database field is between 00 to 16 ,need to consider this as 2000 to 2016. for the remaining values script will consider year as 1917 to 1999 .
Can you try with the below script.
SELECT Date_time, alarm_id, alarm_message
FROM table01
WHERE
CASE WHEN LEFT(Date_time,2) between 00 and RIGHT(year(getdate()),2) THEN CONVERT(DATETIME,'20'+Date_time)
ELSE CONVERT(DATETIME,'19'+Date_time) END between '" & DateTimePicker5.Value & "' and '" & DateTimePicker6.Value & "'
You can use Convert function.
select
Date_time, alarm_id, alarm_message
from
table01
where
Convert(Datetime,Date_time) between Convert(Datetime,'" & DateTimePicker5.Value & "') and Convert(Datetime,'" & DateTimePicker6.Value & "')
Since:
Console.WriteLine(#1/31/2016 10:23:22 AM#.ToString("yy/MM/dd HH:mm:ss"))
returns 16/01/31 10:23:22
I guess that:
select
Date_time, alarm_id, alarm_message
from
table01
where
(Date_time >= '" & DateTimePicker5.Value.ToString("yy/MM/dd HH:mm:ss") & "' )
and (Date_time < '" & DateTimePicker6.Value.ToString("yy/MM/dd HH:mm:ss") & "')
will do the trick.
Notice that I've changed the between with simple compare conditions
Run this in SQL Server and check the results:
create table #dateTest (
testDate datetime
)
insert into #dateTest values ('2016-03-01')
select * from #dateTest
declare #fromDate datetime
set #fromDate = '2016-01-01'
declare #toDate datetime
set #toDate = '2016-03-01'
select
testDate
from
#dateTest
where
( testDate between #fromDate and #toDate )
-- 2016-03-01 00:00:00.000
select
testDate
from
#dateTest
where
( testDate <= #fromDate )
and ( testDate < #toDate )
-- No rows selected
drop table #dateTest

VB.NET Access Datetime Querying Issue

I have a bunch of records in an Access db table with a datetime fields
e.g of records (2/2/2015 3:34:21 PM,2/2/2015 8:29:13 AM )
Problem is I need to run a query where I need all records for displayed to be ones that occurred on the same day regardless of the time. How to best structure this query?
I used 'Select * from table where thetime = 2/2/2015' and there was no result returned. I switched the date format to start with the year, no luck.
Any tips as to sql query syntax for Access will be appreciated. Thanks.
Date/Time values in Access always have both a date and time component, so a date literal like 2015-02-02 is equivalent to 2015-02-02 00:00:00. If you want all rows for that date, regardless of the time, you need to use a WHERE clause like
... WHERE thetime >= {that date} AND thetime < {the following day}
The proper way to do that in VB.NET is to use a parameterized query like this:
Using cmd As New OleDbCommand()
cmd.Connection = con ' an open OleDbConnection
cmd.CommandText =
"SELECT * FROM thetable " &
"WHERE thetime >= ? AND thetime < ?"
Dim targetDate As New DateTime(2015, 2, 2) ' example data
cmd.Parameters.Add("?", OleDbType.DBTimeStamp).Value = targetDate
cmd.Parameters.Add("?", OleDbType.DBTimeStamp).Value = targetDate.AddDays(1)
Using rdr As OleDbDataReader = cmd.ExecuteReader
Do While rdr.Read()
Console.WriteLine(rdr("thetime"))
Loop
End Using
End Using

Populate Date Column in Access with dates from 1980-01-01 to today with sql query

I have an Access Table which is named dates and has one single column named Date ( formatted as date ). I would need to have the dates from 1980-01-01 up until today incremented by 1 day at a time in the column. 1980-01-01 would be at the first row.
How can this be done with a sql query?
You could add those dates with Access SQL if you have a suitable table of numbers.
INSERT INTO dates ([Date])
SELECT CDate(n.the_number)
FROM tblNumbers AS n
WHERE n.the_number BETWEEN 29221 AND 42037;
Or start from 1 in tblNumbers and add an offset ...
INSERT INTO dates ([Date])
SELECT CDate(n.the_number + 29220)
FROM tblNumbers AS n
WHERE n.the_number BETWEEN 1 AND 12817;
But if you don't have a suitable numbers table, you would need to create one and populate it. And that is similar to the problem you started with, only loading plain numbers instead of dates.
The original task is simple enough that I would use a throwaway VBA procedure instead of Access SQL. This one took less than 2 seconds to load my dates table with the required 12,817 date values:
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim dte As Date
Set db = CurrentDb
Set rs = db.OpenRecordset("dates", dbOpenTable, dbAppendOnly)
With rs
For dte = #1/1/1980# To Date
.AddNew
![Date].Value = dte
.Update
Next
.Close
End With
First, rename your column to something else then Date, as it is a reserved word and it would cause you much trouble. In my example I named the column DateField.
I assume when you said sql query, you meant access sql, in which case it cannot be done, as access sql doesn't support cycles.
However, you can do it easily by VBA, please see below:
Sub Main()
Dim myDate As Date
Dim myDateString As String
Dim strSQL As String
myDate = #1/1/1980#
Do While myDate < Now
myDateString = Format(myDate, "yyyy-mm-dd")
strSQL = "INSERT INTO DateTable (DateField) VALUES(#" & myDate & "#)"
CurrentDb.Execute strSQL
myDate = myDate + 1
Loop
End Sub

BETWEEN clause in SQL

I have a SQL statement to display data between two dates. I almost got it but there's a problem.
If I input March 1,2012 to March 7, 2012.. it should show data with dates between the two.. but it also show all of the dates under March 2012.. but whenever I input March 10, 2012 to March 30, 2012 the SQL works perfectly.. any help will be appreciated. thanks
SELECT
agentname, noofcalls, qualified, booking, resched,
actualbooking, sales, remarks,
concat(month,' ',day,',',year) as 'date'
FROM
tblagents
WHERE
(month between '" & cbosmonth.Text & "' AND '" & cboemonth.Text & "')
AND (day between '" & cbosday.Text & "' AND '" & cboeday.Text & "')
AND (year between '" & cbosyear.Text & "' AND '" & cboeyear.Text & "')"
you are doing string comparisons in each of your 'between'. Every number starting with a 1, a 2 or a 3, regardless of what follows it, i.e. 21, or 26, or 31, they are all lower than 7 if you look at them as strings. 1 to 30 works because you're only leaving 31 behind, and 30 < 31 as a String as well.
Do the concatenation first and then the between:
WHERE concat(month,' ',day,',',year)
BETWEEN concat(cbosmonth.Text,' ', cbosday.Text,' ',cbosyear.Text)
AND concat(cboemonth.Text,' ', cboeday.Text,' ',cboeyear.Text)
(check out for correct syntax, I'm just copy pasting from your question, not tried it)
BTW, unless you have a reason to, you probably should be storing the entire date in a single column with the right data time (datetime, timestamp, ...) and not three separated columns.
That is the incorrect way to store a date in database.
Change the date column to datatype date.
You could then do:
SELECT *
FROM table
WHERE bookingDate between to_date ('2012/03/01', 'yyyy/mm/dd')
AND to_date ('2012/03/07', 'yyyy/mm/dd');
This approach is wrong.
In order for a date to be between two interval dates it does not have to have a day number between the two dates, e.g. (pseudocode)
date = May-25-2012; startDate = March-15-2012, endDate = June-01-2012
date is clearly between startDate and endDate, yet
day(date) is 25, which is not between day(startDate) = 15 and day(endDate) = 1
more, as 15 is larger than 1, there are no numbers between them, so that condition will always be false
Similar example can be made for the month part of the date (e.g. date = May-25-2012; startDate = September-15-2010, endDate = Match-01-2015)
You need to take the values for day, month, year, and construct a Date either in the application or on the server and use that to compare the values against.
To make a date from text fields in VB
Dim startDate = new DateTime(
Convert.ToInt32(cbosyear.Text),
Convert.ToInt32(cbosmonth.Text),
Convert.ToInt32(cbosday.Text))
Note that this will fail if the user enters, e.g. "some text" for the year value. You'll need to add some data validations to achieve that.
To make a datetime from parts in SQL Server, take a look here, there are quite a few techniques explained.
Also, you should always avoid just pasting values into the sql string, that's asking for sql injection problems. You should do something like this:
Dim command = new SqlCommand()
command.CommandText = "SELECT .... FROM tblagents where DATEFROMPARTS(year, month, day) between #startDate AND #endDate"
command.Parameters.AddWithValue("#startDate", startDate)
command.Parameters.AddWithValue("#endDate", endDate)

Date range in vb.net

I have following code and I can filter data on grid but when I pick same date in 2 datepicker it shows nothing. How can I fix the problem. Any help will be appreciated.
con = New SqlCeConnection(constring)
con.Open()
cmd = New SqlCeCommand("SELECT * FROM tblMeter WHERE (Date >= #startDate) AND (Date < #endDate)", con)
Dim param1, param2 As SqlCeParameter
param1 = New SqlCeParameter("#startDate", DateTimePicker1.Value)
param2 = New SqlCeParameter("#endDate", DateTimePicker2.Value)
cmd.Parameters.Add(param1)
cmd.Parameters.Add(param2)
Dim da As New SqlCeDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
con.Close()
DataGridView1.DataSource = dt
Thanks
param2 = New SqlCeParameter("#endDate", DateTimePicker2.Value.AddDays(1))
Remember that Sql Server interprets a date like this: 2010-06-23
as a date like this: 2010-06-23 00:00:00.000.
In other words, even if you use >= and <= to check the range at both ends you're still only giving yourself a one millisecond timespan. Sometimes you get away with that if all the dates in the column have no time component, but it's rarely what you really want. Instead, you need to add one day to the end of your range so that your filter includes the entire day, and not just the first millisecond.
That's because #endDate implies the time 00:00, to include the whole day add the time 23:59:59. Or add 1 to #endDate.
Change your query to less-than or equal-to your end date.
SELECT * FROM tblMeter WHERE (Date >= #startDate) AND (Date <= #endDate)
It's your logic:
If date is 2001 and you input 2001:
2001 >= 2001 - check
2001 < 2001 - Nope
Try changing the exclusive
(Date < #endDate)
to the inclusive
(Date <= #endDate)
You may use:
param1 = New SqlCeParameter("#startDate", DateTimePicker1.Value.ToShortDateString)
param2 = New SqlCeParameter("#endDate", DateTimePicker2.Value.AddMinutes(1))