Here is the structure of my DB:
CREATE TABLE [dbo].[P](
[O] [nchar](50) NULL,
[C] [datetime] NULL,
[S] [nchar](50) NULL,
[M] [datetime] NULL
) ON [PRIMARY]
GO
I'm really not getting this DateTime malarky with SQL :(
Whenever I run this:
INSERT INTO P (O, C, S, M)
VALUES ('32','17/04/2014 16:50:37','Complete','21/08/2006 22:50:41')
All I get is this error:
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
I have tried cast as datetime and convert using various styles but every time I get the same error.
Can someone please tell me where I am going wrong?
Thanks
There are many string formats for a date supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
So in your concrete case, try to use this INSERT:
INSERT INTO P (O, C, S, M)
VALUES ('32', '2014-04-17T16:50:37', 'Complete', '2006-08-21T22:50:41')
(with dashes, and with a "T" delimiter between date and time)
or
INSERT INTO P (O, C, S, M)
VALUES ('32', '20140417 16:50:37', 'Complete', '20060821 22:50:41')
(no dashes, no "T" delimiter between date and time)
By default, SQL server prefers the YYYYMMDD format.
You can override the format to make your query work without using the convert function by doing the following:
SET DATEFORMAT DMY
Note that this setting does not affect the underlying storage format, and only changes the way dates are interpreted as input, by default, for the context of the current connection.
This will work:
CREATE TABLE #test ( D DATETIME )
SET DATEFORMAT DMY
INSERT INTO #test
( D )
VALUES ( '21/12/2001 18:05:56' )
DROP TABLE #test
Related
Is it possible to convert 'OCT-20' to '2020/10/01' in sql server. I tried the following cases without any luck.
select convert(date, 'OCT-20',103)
----Conversion failed when converting date and/or time from character string.
alter table MyTable alter column [period] date
----Conversion failed when converting date and/or time from character string.
I am using sql server 2016.
If we assume that the value is always in the format MMM-yy then you could do this:
SELECT CONVERT(date,'01-' + StringDate,106)
FROM dbo.YourTable;
Of course, this has 2 flaws.
The date uses a 2 digit year, so SQL Server could assume the wrong century
It'll only work if the LOGIN is using an English based language, otherwise it'll fail.
The real solution is to fix your design; never store date (and time) values in a varchar, and when ever you do use a varchar for a date (such as a literal in a WHERE) use an unambiguous format such as yyyyMMdd or yyyy-MM-ddThh:mm:ss.nnnnnnn.
I am trying to convert a varchar(255) to datetime in SQL. I found this example:
DECLARE #IsoDate nvarchar(255)
SET #IsoDate = '2010-03-16T19:20:30.45123+01:00'
-- CONVERT TO DATETIME in SQL 2008
SELECT CAST(CONVERT(datetimeoffset, #IsoDate) AS datetime) as SQL2008
and it works perfectly. As I want to change the column format of a whole column, I tried
SELECT CAST(CONVERT(datetimeoffset, [col1]) AS datetime)
from [table]
but it gives me an error: Conversion failed when converting date and/or time from character string.
I don't get what the problem is, the only way it worked using the column is
SELECT CAST(Left([col1]),18) AS datetime)
from [table]
but I would prefer not to cut the string.
You can use
SELECT *
from [table]
WHERE TRY_CONVERT(datetimeoffset, [col1]) IS NULL
to see which values are causing issues.
If your version (since you have a comment with SQL Server 2008) is not supporting TRY_CONVERT and TRY_CAST you can select part of the records to find the issues using a loop/where clause.
but I would prefer not to cut the string.
Why? When converting DateTimeOffset to DateTime, the time zone information gets truncated anyway (see documentation), and since you've stated this solves your problem, it means that the only places where your string content is problematic is somewhere in that part of the string.
Also, since your string is ISO8601, you can safely use cast instead of convert (what's the point of using convert if you're not going to use the style parameter anyway?) - or better yet, use try_cast (unless you're working with a version lower than 2012, which in that case you should consider upgrading since it's the oldest version still supported) - so:
SELECT CAST(TRY_CAST([col1] AS datetimeoffset) AS datetime2(7))
FROM [table]
That being said, it would be better store time-zone aware datetime values in a DateTimeOffset data type - and other datetime values in DateTime2 data type (which is better than DateTime in every way).
Your code is failing because you have bad values. You can ignore them using try_convert():
SELECT CAST(TRY_CONVERT(datetimeoffset, [col1]) AS datetime)
FROM [table]
This is supported in all supported versions of SQL Server.
Because the timezone is ignored in this process, you might as well simply use:
select try_convert(datetime, left(col1, 23))
If I run the query:
select startdate, count(*)
from tablename
where startdate > '2020-04-06'
It only returns value where the startdate is after 4th June 2020. However the dates in the table are in the format YYYY-MM-DD HH:mm:ss.sss.
If I run a getdate() or sysdatetime() it returns 2020-06-16 14:29:29.157 in the correct format.
So why is the query using YYYY-DD-MM? And how do I get it to change by default?
P.S. I'm aware that I could use CONVERT or FORMAT in the query, but as all dates will be in the YYYY-MM-DD format I'd like that to be the default, and not have to write extra code each time.
EDIT: I'm using Microsoft SQL Server Management Studio
EDIT2: I checked with a colleague and the same thing happens to them.
That depends on various settings. You can get around this by removing the hyphens:
startdate > '20200406'
In SQL Server, this format is always unambiguous, YYYYMMDD. I prefer the version with the hyphens, because it is more standard. But if you are dealing with this as an issue I would suggest using the SQL Server unambiguous format.
You can handle it in two ways:
At the session level. you can set format and issue query
Use ISO 8601 format (Recommended)
DECLARE #table table(a datetime)
INSERT INTO #table values('2020-04-06')
SELECT * FROM #table WHERE A = '2020-04-06' -- ISO 8601
set dateformat ymd
SELECT * FROM #table WHERE A = '2020-04-06' -- Format change
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');
According to the documentation I've found from AR Systems on BMC Remedy, timestamps in an MSSQL Server environment (we're using SQL Server 2005 here) are stored as an int datatype in UNIX timestamp format.
I cannot for the life of me get custom SQL in Business Objects Web Intelligence to let me convert this timestamp into mm/dd/yyyy format, which I need to be able to group records by a date (without the timestamp, obviously). Anything I try to do involving math or datatype conversion throws an "invalid type" error. I can't convert the field to an int, varchar, datetime, or anything else. The only function that works is DATEADD, which still returns the full timestamp.
How can I get this converted? I'm going nuts here!
to convert GMT/UTC/Zulu to Local time Zone(EDT/New York):
DATEADD(hour,-5,DATEADD(s,Last_Modified_Date,'1/1/1970 00:00:00'))
Example of use to display Remedy work info entries (Transact-SQL):
SELECT Work_Log_ID, DATEADD(hour, +12, DATEADD(s, Last_Modified_Date, '1/1/1970 00:00:00')) as Last_Modified_Date , Description, Detailed_Description, Infrastructure_change_ID, Number_of_Attachments
FROM dbo.CHG_WorkLog
WHERE Infrastructure_Change_ID = 'CRQ001261'
ORDER BY Work_Log_ID desc
Why doesn't this work?
DECLARE #timestamp INT
SELECT #timestamp = DATEDIFF(s,'1/1/1970 00:00:00',GETDATE())
SELECT DATEADD(s,#timestamp,'1/1/1970 00:00:00')
Substitute the #Timestamp with the value from your table.
You may need to multiply the int timestamp by 1000. The AR System stores the date as the number of 'seconds' where as most other languages store the unix timestamp as milliseconds (and as a long data type)
Hope that helps!
Go to
user tool -> Tools -> Options -> Locale tab -> Date/Time Style -> Custom Format -> mm/dd/yyyy