Getting an error when trying to compare two dates - sql

i have a select where i need to make sure that my adate varchar(8) is between two dates supplied.
sometimes the passed in values are NULL so i would then show everything.
select something from myTable where
convert(date, adate) >= ISNULL(convert(date,#beginDate), convert(date, adate))
works fine
but when i make it:
select something from myTable where
convert(date, adate) >= ISNULL(convert(date,#beginDate), convert(date, adate))
and convert(date, adate) <= ISNULL(convert(date,#endDate), convert(date, adate))
i get:
Conversion failed when converting date and/or time from character string.
or i can do the <= line without the >= without an error, but not both of them together, what's going on??
the two lines look identical, i can't figure out what i'm doing wrong here.....

Check your value for #endDate. That parameter is your only difference between the SELECT that works, and the one that doesn't. Chances are, it (sometimes) contains a value that cannot be converted to a date. Usual suspect is the empty string ('')

It looks both #startdate and #enddate are string types. Best thing is to have them in ISO format (yyyymmdd) and you should be fine.
For example try using these;
Select #startdate = '20130101', #enddate = '20130221'

I'm not sure on what you're trying to do but...
Since any of the values could come by NULIFIED, you said you would get every result in the table... so it might be easier just to set the query to filter it on the language you're using before the DB...
Or as I would put on a PHP sample...
IF ( !$beginDate || !$endDate )
{
$query = "SELECT * FROM myTable";
}
ELSE
{
$query = "SELECT * FROM myTable WHERE 'whatever clause'";
}

Related

Convert string to date SQL Server

I have a query when I need to convert a string to datetime, I use
CONVERT(DATETIME, '')
but it's still not working. My column fechac is of type Datetime.
If I pass in for example '2019-11-20 00:03:56.120', the query works but I don't need the time because is a parameter from an application web and I send the date example '2019-11-20'. Thanks!
This is my query:
SELECT *
FROM table
WHERE cb.fechac = CONVERT(DATETIME, '2019-11-20');
Use the format yyyyMMdd. With the datetime datatype yyyy-MM-dd is ambiguous. Otherwise, use a style code:
CONVERT(datetime,'2019-11-20',126);
CONVERT(datetime,'20191120')
Reading a lot through the lines in the comments here, however, are you actually after..?:
WHERE fechac >= '20191120'
AND fechac < '20191121'
Final reading through the lines. it appears the OP is actuaklly passing a parameter (I assume of the data type date), therefore...
WHERE fechac >= #fechac
AND fechac < DATEADD(DAY, 1, #fechac)
This should work on any system, regardless of internationalization settings:
WHERE cb.fechac=convert(DATE,'20191120');
SELECT *
FROM table cb
WHERE cast(cb.fechac as date) = convert(date, '2019-11-20', 23)

incorrect results while passing a datetime instead of getdate()

I am working on a SQL query which returns all records between two dates from a table as follows
select convert(varchar(2),TestDate,108) from dbo.Table
where TestDate between convert(datetime,convert(varchar,GETDATE(),101))
and dateadd(day,1,convert(datetime,convert(varchar,GETDATE(),101)))
The above query works fine and gives me the desired results but when I tried to use a normal date string instead of getdate(), the query returns and empty result as follows
select convert(varchar(2),TestDate,108) from dbo.Table
where TestDate between convert(datetime,convert(varchar,'2015-12-27 00:00:00.000',101)) and dateadd(day,1,convert(datetime,convert(varchar,2015-12-27 00:00:00.000',101)))
The above query returns an empty result set which is not what I wanted.
I tried passing date string in different formats but that didn't work.
May I know a correct way to do it?
Why would you convert dates to a string for comparisons? Just do the comparisons as dates.
In addition, you can use datepart() to extract the hour, rather than using some esoteric format to convert():
select datepart(hour, TestDate)
from dbo.Table
where TestDate between cast(GETDATE() as date) and
cast(dateadd(day, 1, getdate()) as date)
If you want the hour as a string instead of a number, then use datename() rather than datepart().
I guess that you are having an extra CONVERT.
Wherever you have this
convert(varchar,GETDATE(),101)
just replace with your date:
'2015-12-27 00:00:00.000'
because the purpose of the CONVERT function is to translate a Date into a Varchar
In addition to Gordon's answer, you can substitute string dates as so:
select datepart(hour, TestDate)
from dbo.Table
where TestDate between cast('2015-12-27 00:00:00.000' as date) and
cast(dateadd(day, 1, '2015-12-27 00:00:00.000') as date)
Assuming this is for a webapp, be sure to use placeholders instead of actual text to prevent SQL insertion attacks.

filter DateTime field with now as reference in WHERE clause

I am trying to build a vb.net application with a where clause to filter data using a DateTime field.
My table contains 5 fields and more than 10000 rows. I wanna use a DateTime field to find all the rows older than 7 years from now.
But this script will be re-used many times. So I don't wanna use this kind of where clause cause I don't wanna need to modify the where clause every time I wanna run the application :
select * from myTable WHERE myDateTimeField < '2006-09-07 00:00:00.000'
I'd like to find a way to write a where clause like this :
select * from myTable WHERE myDateTimeField "is older than 7 years from NOW"
I don't use VB.net very often (as you can see), so this thing is really bugging me
Just make use of DateTime:
Dim dateTime As DateTime
dateTime = DateTime.Now.AddYears(-7);
When you're building your SQL string just call ToString on your date (you can obviously format it however you need):
dateTime.ToString("MM/dd/yyyy");
SELECT * FROM myTable WHERE myDateTimeField < DATEADD(YEAR, -7, GETDATE())
That is if the data in the myDateTimeField is in the same local time zone of the sql server.
If your data is in UTC (which it often should be), then use:
SELECT * FROM myTable WHERE myDateTimeField < DATEADD(YEAR, -7, GETUTCDATE())
i think better would be provided you have SQL Server
strQuery = "select * from myTable WHERE myDateTimeField
<= DATEADD(YEAR, -7, GETDATE())"
What you are looking for is a DSL for datetime. Check out this blog post to get some ideas.
http://leecampbell.blogspot.com/2008/11/how-c-30-helps-you-with-creating-dsl.html
Good Luck
P.S.
If you need help translating it into vb.net just submit a comment.

Convert YYYYMMDD to DATE

I have a bunch of dates in varchar like this:
20080107
20090101
20100405
...
How do I convert them to a date format like this:
2008-01-07
2009-01-01
2010-04-05
I've tried using this:
SELECT [FIRST_NAME]
,[MIDDLE_NAME]
,[LAST_NAME]
,cast([GRADUATION_DATE] as date)
FROM mydb
But get this message:
Msg 241, Level 16, State 1, Line 2Conversion failed when converting date and/or time from character string.
The error is happening because you (or whoever designed this table) have a bunch of dates in VARCHAR. Why are you (or whoever designed this table) storing dates as strings? Do you (or whoever designed this table) also store salary and prices and distances as strings?
To find the values that are causing issues (so you (or whoever designed this table) can fix them):
SELECT GRADUATION_DATE FROM mydb
WHERE ISDATE(GRADUATION_DATE) = 0;
Bet you have at least one row. Fix those values, and then FIX THE TABLE. Or ask whoever designed the table to FIX THE TABLE. Really nicely.
ALTER TABLE mydb ALTER COLUMN GRADUATION_DATE DATE;
Now you don't have to worry about the formatting - you can always format as YYYYMMDD or YYYY-MM-DD on the client, or using CONVERT in SQL. When you have a valid date as a string literal, you can use:
SELECT CONVERT(CHAR(10), CONVERT(datetime, '20120101'), 120);
...but this is better done on the client (if at all).
There's a popular term - garbage in, garbage out. You're never going to be able to convert to a date (never mind convert to a string in a specific format) if your data type choice (or the data type choice of whoever designed the table) inherently allows garbage into your table. Please fix it. Or ask whoever designed the table (again, really nicely) to fix it.
Use SELECT CONVERT(date, '20140327')
In your case,
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
In your case it should be:
Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as
'GRADUATION_DATE' from mydb
I was also facing the same issue where I was receiving the Transaction_Date as YYYYMMDD in bigint format. So I converted it into Datetime format using below query and saved it in new column with datetime format. I hope this will help you as well.
SELECT
convert( Datetime, STUFF(STUFF(Transaction_Date, 5, 0, '-'), 8, 0, '-'), 120) As [Transaction_Date_New]
FROM mydb
Just to add more info about all solution above:
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
Assuming you don't have a WHERE clause, it is ok, the Convert will try to return all dates even if it is not a valid date like '00000000' (it was in my case).
But, if you need a WHERE clause, so you can see a message like this:
So I tested a mix of some approaches mentioned above like:
DECLARE #DateStart datetime = '2021-02-18'
DECLARE #DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
WHERE
--THIS LINE SHOULD BE ENOUGTH TO AVOID WRONG DATES, BUT IT IS NOT
ISDATE([GRADUATION_DATE]) = 1 AND
CONVERT(char(10), [GRADUATION_DATE], 120) BETWEEN #DateStart and #DateEnd
And Finally I used this way with success:
DECLARE #DateStart datetime = '2021-02-18'
DECLARE #DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
WHERE
CONVERT(char(10),
-- I ADDED THIS LINE TO IGNORE WRONG DATES
CASE WHEN ISDATE([GRADUATION_DATE]) = 1 THEN [GRADUATION_DATE] ELSE '1900-01-01' END, 120)
BETWEEN #DateStart and #DateEnd

How to filter only the date from a string stored in a varchar

Ii have values stored in the SQL Server in the following manner : 02-Jul-12 12:00:00 AM here the time and minutes, seconds can be anything like 02-Jul-12 12:15:52 PM ,02-Jul-12 6:02:12 AM so on.
I want to have a where condition which will omit the time and take the data based on the date like the following where some_Date='02-Jul-12'
How would I do this?
SELECT * FROM whatever WHERE some_Date LIKE '02-Jul-12%';
If you are on SQL2008 or later, you can cast your DATETIME to DATE.
See this post: http://blog.sqlauthority.com/2012/09/12/sql-server-get-date-and-time-from-current-datetime-sql-in-sixty-seconds-025-video/
But in a WHERE-clause it is better to search between dates, like this:
DECLARE #startDate DATETIME = '02-Jul-2012'
DECLARE #endDate DATETIME = DATEADD(DAY, 1, #startDate)
SELECT * FROM [table] WHERE [some_Date] BETWEEN #startDate AND #endDate
SELECT * FROM dbo.tbl_MyTable
WHERE
REPLACE(CONVERT(VARCHAR(9), DateTimeValueColumn, 6), ' ', '-')='02-Jul-12'
or
On chage in code is instead of using getdate function voncert you datestring in datetime format and do compare this follow query will work for you
SELECT * FROM dbo.tbl_MyTable
WHERE
CAST(CONVERT(CHAR(10), DateTimeValueColumn, 102) AS DATE) =
CAST(CONVERT(CHAR(10),GETDATE(),102) AS DATE)
If you are storing dates as characters -- which is not recommended -- you should at least use ISO format: YYYY-MM-DD hh:mm:ss. This makes the date useful for sorting and comparisons ("<" works, ">" works, "between" works as well as equals).
To extract the date, you can then use left(datestr, 10). In your format, you would use:
where left(datestr, 9) = '01-Jan-13'
If you are storing the fields as a datetime or smalldatetime, you may think they are stored as a string. They are not. They are stored as some number of days since some particular date, with day parts stored as fractional days. If you are using SQL Server 2005 or greater, then the best way is:
where cast(datetime as date) = '2013-01-01' -- I recommend ISO formats, even for constants. '20130101' is even better
To select rows with today's date (not time)
select * from myTable where datediff(dd, dateColumn, getdate()) = 0