I have tables with this type of datetime: 2010-09-16 00:32:41.960' CreatedDate column.
I need to perform a query ... where [CreatedDate] >= '2010-09-16 00:32:41.960'
but that just gives me
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
What is the correct syntax, it's been a while since I've done SQL the last time.
Thanks in advance.
Use an unambiguous datetime format so SQL Server doesn't have to guess how to convert it:
where [CreatedDate] >= '2010-09-16T00:32:41.960'
It's a shame that, depending on your regional settings, it may interpret the form with a space separator (rather than T) as YYYY-DD-MM hh:mm:ss. Which gives an out of range month with your example (and wrong results for dates early in the month, except when day=month)
I'd normally list the safe formats as:
YYYYMMDD
YYYY-MM-DD'T'hh:mm:ss
YYYY-MM-DD'T'hh:mm:ss.mil
There are some other formats that are now safe if converting to datetime2 or date, but I can't remember them, and the above usually suffice.
Another alternative would be to run a set dateformat statement before using these date literals:
set dateformat mdy
select MONTH('2010-09-16 00:32:41.960')
Gives 9 as the result, whereas what you're experiencing can be reproduced with:
set dateformat dmy
select MONTH('2010-09-16 00:32:41.960')
Try:
where [CreatedDate] >= CONVERT(datetime,'2010-09-16 00:32:41.960');
Related
I am using this
CAST(NotifDate as date) between #FromNotifDate AND #ToNotifDate
but NotifDate is saved as varchar in table but FromNotifDate AND ToNotifDate are of Date type.
When I pass these parameters 08/06/2014 and 20/04/2020 09:40:17 it doesn't work and throws error i.e.
Conversion failed when converting date and/or time from character string.
but if I pass 08/06/2014 and 10/04/2020 09:40:17 it works.
Your current database locale settings are probably set to en-US or another where the date format is MM/dd/yyyy.
That makes 08/06/2014 and 10/04/2014 valid dates (but they are 6th of August and 4th of October, not 8th of June and 10th of April!), but not 20/04/2020.
To use a different date format, you can use CONVERT, with the proper style code (I believe it's 103 for dd/MM/yyyy (see documentation)
So, this should work for you : CONVERT(date, NotifDate, 103)
Note that, as a general recommendation, it would be beneficial that you input NotifDate as a proper SQL Date in your DB in the first place, if possible, to avoid having to do conversion like this in your queries.
Also, there the unambiguous and international standard ISO-8601 format yyyy-MM-dd which should be always parsed correctly by CAST, I recommend using it over any localized format where you can in your code infrastructure.
System having default date format is "MM/dd/yyyy" so while you set "10/04/2020 09:40:17" value so system throm an Error- out of range Error,
-- The conversion of a varchar data type
-- to a datetime data type resulted in an out-of-range value.
select cast('20/04/2020 09:40:17' as datetime)
-- get the current session date_format
select date_format
from sys.dm_exec_sessions
where session_id = ##spid
-- set the dateformat for the current session
set dateformat dmy
-- this should work
select cast('20/04/2020 09:40:17' as datetime)
I think I've read just about every thread on this topic and none of them are solving my problem.
First of all, the database I'm working with has all date fields set to a varchar data type, which drives me insane because I constantly have to cast or convert whenever I'm working with any queries involving dates.
The query I'm working with at the moment is supposed to pull a list of medical patients who all have a certain diagnosis, but that diagnosis has to have been given before a certain date. Here's what I've got.
SELECT DISTINCT
pd.PatientID,
pd.PatientName,
pmh.DateOfOnset
pmh.DiagnosisCode
FROM PatientDemographic pd JOIN PatientMedicalHistory pmh ON pd.PatientID = pmh.PatientID
WHERE pmh.DiagnosisCode = '401.1'
AND CAST(pmh.DateOfOnset as Date) > CAST('12/31/2014' as Date)
I'm getting an error that says "Conversion failed when converting date and/or time from character string." It's telling me the error is on Line 1 though (the SELECT DISTINCT line) so that's not really helpful and I'm not sure what I need to fix.
As I mentioned, the DateOfOnset field has a varchar data type, and I need to find any of those dates that came before the end of December, 2014. I've tried to remedy this error by trying different combinations of the CAST statements -- I even tried including a cast on the date field in the SELECT statement, and I'm still getting the same error.
I was working on another query earlier that required me to find all patient appointments from within a certain time frame, and for that query, I had my WHERE clause set up like:
WHERE Cast(VisitDate as Date) BETWEEN CAST('01/01/2014' as Date) AND CAST('12/01/2014' as Date)
...and it worked perfectly fine. Since I've got my current query set up virtually the same way, I'm not sure why I'm getting that conversion error.
You have wrong dateformat:
SET DATEFORMAT dmy;
SELECT CAST('12/31/2014' as Date);
--Conversion failed when converting date and/or time from character string.
You could set it to mdy before executing your query.
SET DATEFORMAT mdy;
SELECT CAST('12/31/2014' as Date);
LiveDemo
or use CONVERT with style 101:
SET DATEFORMAT dmy;
SELECT CONVERT(DATE,'12/31/2014',101)
If you really need to store DATE as VARCHAR use at least culture independent type like ISO-8601.
SET DATEFORMAT dmy;
SELECT CAST('20140201' as Date);
-- 01.02.2014
SET DATEFORMAT mdy;
SELECT CAST('20140201' as Date)
-- 01.02.2014
It sounds like SQL is not able to convert the stored strings into dates. This would explain why CAST(pmh.DateOfOnset as Date) fails where Cast(VisitDate as Date) does not--the latter might not have any mis-formatted dates.
Best-case solution is to convert your table columns to the proper datatypes. Second-best case, add columns containing the proper datatypes, and convert the data over; you'd have to fix any existing bad data, as well as convert data on the fly as it's loaded (yuck). Another option, add a calculated column, though you'll have problems with the afore-mentioned invalid dates. (What version of SQL do you have? Later versions have the isdate function, which might help here.)
If modifying tables is not an option, you're probably stuck writing queries that have to assume some of the data is invalid (bad format).
I can't make out from the documentation why SQL Server parses a text in a format other than the specified style.
Regardless of whether I provide text in the expected format:
SELECT CONVERT(DATETIME, N'20150601', 112)
or incorrect format (for style 113):
SELECT CONVERT(DATETIME, N'20150601', 113)
The results are the same: 2015-06-01 00:00:00.000 I would expect the latter to fail to convert the date (correctly).
What rules does it employ when trying to convert a VARCHAR to DATETIME? I.e. why does the latter (incorrect format style) still correctly parse the date?
EDIT: It seems I've not been clear enough. Style 113 should expect dd mon yyyy hh:mi:ss:mmm(24h) but it happily converts values in the format yyyymmdd for some reason.
Because the date is in a canonical format ie(20150101). The database engine falls over it implicitly. This is a compatibility feature.
If you swapped these around to UK or US date formats, you would receive conversion errors, because they cannot be implicitly converted.
EDIT: You could actually tell it to convert it to a pig, and it would still implicitly convert it to date time:
select convert(datetime,'20150425',99999999)
select convert(datetime,'20150425',100)
select convert(datetime,'20150425',113)
select convert(datetime,'20150425',010)
select convert(datetime,'20150425',8008135)
select convert(datetime,'20150425',000)
And proof of concept that this is a compatibility feature:
select convert(datetime2,'20150425',99999999)
Although you can still implicitly convert datetime2 objects, but the style must be in the scope of the conversion chart.
Reason why is the date N'20150601' converted to valid datetime is because of fact that literal N'20150601' is universal notation of datetime in SQL Server. That means, if you state datetime value in format N'yyyymmdd', SQL Server know that it is universal datetime format and know how to read it, in which order.
You should convert to varchar type in order to apply those formats:
SELECT CONVERT(varchar(100), CAST('20150601' as date), 113)
OK, you are converting datetime to datetime. What did you expect? In order to apply formats you should convert to varchar and you have to have date or time type as second parameter.
I was having problem in retrieving from SQL Server so I posted this [question][1]
I did not get any suitable answers. So I have changed the column datatype from datetime to varchar and now it works fine.
SELECT *
FROM test
WHERE (timeStamp BETWEEN '05-09-2013 18:23:57' AND '05-09-2013 18:23:59')
But my query if varchar datatype can play the role of datetime and in varchar we can also store the string then why sql provides datetime datatype? I know varchar occupies more space than datetime. I would like to know other reasons.
Change datatype of your column to datetime. You can do your query IF you'll use datetime instead of varchar in where clause:
select *
from test
where timeStamp between convert(datetime, '2013-09-05 18:23:57', 120) and convert(datetime, '2013-09-05 18:23:59', 120)
I'm pretty sure it would work even with implicit cast if you use ISO format of date:
select *
from test
where timeStamp between '2013-09-05 18:23:57' and '2013-09-05 18:23:59'
Here's more info about cast and convert.
Another reason apart from space is this:
Datetime has other functions like picking up the day, year, month,hours,minutes,seconds etc so that you don't have to write it for yourself. If you use varchar then it will be your responsibility to provide functions for future use. You should use split function to retrive the part of date you want.
Another is that a query on a varchar works slower when compared to Datetime when you use to conditions to compare month / day/ year
Always use proper DATETIME datatype to store date and time values. Refer this for more information
http://beyondrelational.com/modules/2/blogs/70/posts/10902/understanding-datetime-column-part-iv.aspx
We've recently migrated our database to a different server and since this I think the date format querying has changed somehow.
Previously we could use the following..
SELECT * FROM table WHERE date > 'YYYY-MM-DD'
However now we have to use..
SELECT * FROM table WHERE date > 'YYYY-DD-MM'
Can someone tell me what I need to change to get back to the previous version?
Try this one -
Query:
SET DATEFORMAT ymd
Read current settings:
DBCC USEROPTIONS
Output:
Set Option Value
-------------------------- -----------------
...
language us_english
dateformat ymd
...
You are right, the date format is different between the servers.
Lots of people fall into the trap of assuming that if you specify a date literal as 'YYYY-MM-DD', it will be interpreted as that regardless of the current date format. This is incorrect. SQL Server sees the 4 digits at the start of the string and correctly deduces that they represent the year. However, it then uses the current date format to tell which way round the month and day are. If you are in the UK, for example, this puts you in an awkward situation because you need a date format of DMY to interpret a date literal like 'DD-MM-YYYY', but a date format of MDY to interpret a date literal like 'YYYY-MM-DD'.
You have several options:
SET DATEFORMAT YMD, and don't let users enter dates any other way.
Use the ODBC date literal syntax {d'YYYY-MM-DD'}. This will be parsed correctly regardless of the current date format. CONVERT(DATE, 'YYYY-MM-DD', 120) has the same effect.
Remove all literal values from your queries and use parameters instead. This is by far the best alternative, and I strongly recommend it.
is you use different formats for the string then you can avoid this behaviour.
There are 2 iso formats that are always specific -- sql server will always parse them in the same way regardless of the server date format setting.
These are:
1) Short form : YYYYMMDD. Example '20120301' -- 1st March 2012
2) Long Form : YYYY-MM-DDTHH:MM:SS.msms'. Example '2012-03-01T12:13:00.000Z' -- 1st March 2012 at 13 minutes past 12 (PM)
In the long form the miliseconds is optional -- this is a perfectly acceptable ISO datetime '2012-03-01T12:13:00Z'
The Z at the end is time zone information. SQL Server doesn't actually require this. (though other products are a bit more exacting)
Try this for example:
DECLARE #foo DATETIME
SET DATEFORMAT DMY
-- this will be the 3rd of january in DMY
SET #foo = '2012-03-01'
SELECT 'DMY: Not ISO', #foo
SET #foo = '20120301'
SELECT 'DMY: ISO', #foo
SET DATEFORMAT MDY
-- this will be the 1st of March in MDY
SET #foo = '2012-03-01'
SELECT 'MDY: not ISO', #foo
SET #foo = '20120301'
SELECT 'MDY: ISO', #foo
When you use text to enter dates you should always try to use one of the two ISO standards. It just makes things much more deterministic.
Short format (SQL Server)
http://msdn.microsoft.com/en-US/library/ms187085(v=sql.90).aspx
ISO 8601 Format (SQL Server)
http://msdn.microsoft.com/en-us/library/ms190977(v=sql.90).aspx
It's a matter of language/culture
Set Language 'us_english'