Specifying style on T-SQL convert function causes error - sql-server

I have a stored procedure which takes in dates in a variety of formats and converts them to datetimes. The following line works just as expected:
RETURN CONVERT(datetime,#vMonth+'/'+#vDay+'/'+#vYear)
However, I want to specify that the date should always be treated as being in US format, as this will return the wrong result if T-SQL is set to use British. If I do this:
RETURN CONVERT(datetime,#vMonth+'/'+#vDay+'/'+#vYear, 101)
Then I start getting the following error (on all values I've tried):
Conversion failed when converting date and/or time from character string.
I've done a search and none of the threads that mention this error seem to be the same problem. I'm confused as to why specifying us_english (101) for a string that's already being converted as us_english causes the procedure to break.
Edit: I've boiled this down to a minimum case that shows where I'm not understanding.
This works:
select CONVERT(datetime,'01/02/03')
This does not:
select CONVERT(datetime,'01/02/03',101)

This works fine for me. No errors.
declare #mydate datetime = getdate()
declare #vMonth varchar(10), #vDay varchar(10), #vYear varchar(10)
set #vMonth = cast(DATEPART(mm, #mydate) as varchar(10))
set #vDay = cast(DATEPART(dd, #mydate) as varchar(10))
set #vYear = cast(DATEPART(YYYY, #mydate) as varchar(10))
select CONVERT(datetime, #vMonth+'/'+#vDay+'/'+#vYear, 101)
Result:
2015-01-09 00:00:00.000

It turns out that when using 101 as the language, SQL Server expects the century to be in XXXX format. To handle 2-digit years correctly, you must use 1 as the language instead.

Related

How to convert a datetime to string in T-SQL

I'm surprised not to be able to find this question here already.
I have a date time var and I want to convert it to a string so that I can append it to another string. I want it in a format that can be converted easily back to a date time.
How can I do this?
(I want the date part and the time part.)
The following query will get the current datetime and convert into string. with the following format yyyy-mm-dd hh:mm:ss(24h)
SELECT convert(varchar(25), getdate(), 120)
SQLFiddle Demo
SQL Server Date Formats
There are many different ways to convert a datetime to a string. Here is one way:
SELECT convert(varchar(25), getdate(), 121) – yyyy-mm-dd hh:mm:ss.mmm
See Demo
Here is a website that has a list of all of the conversions:
How to Format datetime & date in SQL Server
In addition to the CAST and CONVERT functions in the previous answers, if you are using SQL Server 2012 and above you use the FORMAT function to convert a DATETIME based type to a string.
To convert back, use the opposite PARSE or TRYPARSE functions.
The formatting styles are based on .NET (similar to the string formatting options of the ToString() method) and has the advantage of being culture aware. eg.
DECLARE #DateTime DATETIME2 = SYSDATETIME();
DECLARE #StringResult1 NVARCHAR(100) = FORMAT(#DateTime, 'g') --without culture
DECLARE #StringResult2 NVARCHAR(100) = FORMAT(#DateTime, 'g', 'en-gb')
SELECT #DateTime
SELECT #StringResult1, #StringResult2
SELECT PARSE(#StringResult1 AS DATETIME2)
SELECT PARSE(#StringResult2 AS DATETIME2 USING 'en-gb')
Results:
2015-06-17 06:20:09.1320951
6/17/2015 6:20 AM
17/06/2015 06:20
2015-06-17 06:20:00.0000000
2015-06-17 06:20:00.0000000
SELECT CONVERT(varchar, #datetime, 103) --for UK Date format 'DD/MM/YYYY'
101 - US - MM/DD/YYYY
108 - Time - HH:MI:SS
112 - Date - YYYYMMDD
121 - ODBC - YYYY-MM-DD HH:MI:SS.FFF
20 - ODBC - YYYY-MM-DD HH:MI:SS
There are 3 different methods depending on what I is my requirement and which version I am using.
Here are the methods..
1) Using Convert
DECLARE #DateTime DATETIME = GETDATE();
--Using Convert
SELECT
CONVERT(NVARCHAR, #DateTime,120) AS 'myDateTime'
,CONVERT(NVARCHAR(10), #DateTime, 120) AS 'myDate'
,RIGHT(CONVERT(NVARCHAR, #DateTime, 120),8) AS 'myTime'
2) Using Cast (SQL Server 2008 and beyond)
SELECT
CAST(#DateTime AS DATETIME2) AS 'myDateTime'
,CAST(#DateTime AS DATETIME2(3)) AS 'myDateTimeWithPrecision'
,CAST(#DateTime AS DATE) AS 'myDate'
,CAST(#DateTime AS TIME) AS 'myTime'
,CAST(#DateTime AS TIME(3)) AS 'myTimeWithPrecision'
3) Using Fixed-length character data type
DECLARE #myDateTime NVARCHAR(20) = CONVERT(NVARCHAR, #DateTime, 120);
DECLARE #myDate NVARCHAR(10) = CONVERT(NVARCHAR, #DateTime, 120);
SELECT
#myDateTime AS 'myDateTime'
,#myDate AS 'myDate'
You can use the convert statement in Microsoft SQL Server to convert a date to a string. An example of the syntax used would be:
SELECT convert(varchar(20), getdate(), 120)
The above would return the current date and time in a string with the format of YYYY-MM-DD HH:MM:SS in 24 hour clock.
You can change the number at the end of the statement to one of many which will change the returned strings format. A list of these codes can be found on the MSDN in the CAST and CONVERT reference section.
Check CAST and CONVERT syntax of t-sql:
http://msdn.microsoft.com/en-us/library/ms187928.aspx
Try below :
DECLARE #myDateTime DATETIME
SET #myDateTime = '2013-02-02'
-- Convert to string now
SELECT LEFT(CONVERT(VARCHAR, #myDateTime, 120), 10)
This has been answered by a lot of people, but I feel like the simplest solution has been left out.
SQL SERVER (I believe its 2012+) has implicit string equivalents for DATETIME2 as shown here
Look at the section on "Supported string literal formats for datetime2"
To answer the OPs question explicitly:
DECLARE #myVar NCHAR(32)
DECLARE #myDt DATETIME2
SELECT #myVar = #GETDATE()
SELECT #myDt = #myVar
PRINT(#myVar)
PRINT(#myDt)
output:
Jan 23 2019 12:24PM
2019-01-23 12:24:00.0000000
Note:
The first variable (myVar) is actually holding the value '2019-01-23 12:24:00.0000000' as well. It just gets formatted to Jan 23 2019 12:24PM due to default formatting set for SQL SERVER that gets called on when you use PRINT. Don't get tripped up here by that, the actual string in (myVer) = '2019-01-23 12:24:00.0000000'
In the stored procedure for me works something like this.
convert(varchar(10), StartingDate) AS 'StartingDate'

Need help on DateTime Conversion in Sql Server 2005

I am facing problem in DateTime converstion.
My input is 09/22/2011, I need to convert into 20110922.
I tried the below one, but failed.
Select CONVERT(VARCHAR(8),'09/22/2011' , 112) as DateConv
Here you go:
SET DATEFORMAT mdy
SELECT CONVERT(VARCHAR(8), CAST('09/22/2011' as DATETIME) , 112) AS DateConv
If your input is actually a dateTime variable like you said (but didn't show in your code example), you can simplify this down to:
SELECT CONVERT(VARCHAR(8), #myDate , 112) AS DateConv
This will do the trick:
select year('09/22/2011') * 10000 + month('09/22/2011') * 100 + day('09/22/2011')
Without any other information, SQL is interpreting the '09/22/2011' as a varchar already, and just passes the data through (ignoring CONVERT's style argument). If you use the following line:
SELECT CONVERT (VARCHAR (8), CAST ('09/22/2011' as DATETIME), 112) as DateConv
it should work as expected since it will then view the '09/22/2011' as a date value. If you were getting the date from a column in a table, it would already know the type and you will not need to worry about the CAST portion of the expression, just use the column name.

unable to convert varchar to date in sql server

in my data a column called 'duedate' which is in the varchar(5) format has dates stored in the following format '20110725' for 25th july 2011, is there a way in which i can convert this to date format
i tried using
cast(duedate as datetime)
which did not work
then i tried to convert it to bigint and then to datetime
cast( cast(duedate as bigint) as datetime)
which said
arithematic overflow error
Sorry for the confusion it was varchar(50) - typo error, and thanks a lot for the help ill try the things you guys mentioned
If the column is really varchar(5), then it can't have values like '20110725', because that would be 8 characters.
Maybe the values were truncated when they were inserted?
'20110725' shortened to 5 characters becomes '20117', and converting that won't work.
I guess the problem is something like that, because as Mladen Prajdic already said, converting '20110725' to datetime works perfectly.
Please see this table of valid date-time conversion codes. The code you will need is 112 which converts from yyyymmdd format.
CONVERT (datetime, duedate, 112)
how didn't it work? doing SELECT cast('20110725' as datetime) works perfectly for me.
Try running this on your table to find the values that aren't dates:
SELECT duedate
FROM your_table
WHERE ISDATE(duedate) = 0;
Like Christian said, a VarChar(5) won't be able to hold the value you're expecting it to either.

SQL Server function to return minimum date (January 1, 1753)

I am looking for a SQL Server function to return the minimum value for datetime, namely January 1, 1753. I'd rather not hardcode that date value into my script.
Does anything like that exist? (For comparison, in C#, I could just do DateTime.MinValue)
Or would I have to write this myself?
I am using Microsoft SQL Server 2008 Express.
You could write a User Defined Function that returns the min date value like this:
select cast(-53690 as datetime)
Then use that function in your scripts, and if you ever need to change it, there is only one place to do that.
Alternately, you could use this query if you prefer it for better readability:
select cast('1753-1-1' as datetime)
Example Function
create function dbo.DateTimeMinValue()
returns datetime as
begin
return (select cast(-53690 as datetime))
end
Usage
select dbo.DateTimeMinValue() as DateTimeMinValue
DateTimeMinValue
-----------------------
1753-01-01 00:00:00.000
Have you seen the SqlDateTime object? use SqlDateTime.MinValue to get your minimum date (Jan 1 1753).
As I can not comment on the accepted answer due to insufficeint reputation points my comment comes as a reply.
using the select cast('1753-1-1' as datetime) is due to fail if run on a database with regional settings not accepting a datestring of YYYY-MM-DD format.
Instead use the select cast(-53690 as datetime) or a Convert with specified datetime format.
Enter the date as a native value 'yyyymmdd' to avoid regional issues:
select cast('17530101' as datetime)
Yes, it would be great if TSQL had MinDate() = '00010101', but no such luck.
Here is a fast and highly readable way to get the min date value
Note: This is a Deterministic Function, so to improve performance further we might as well apply WITH SCHEMABINDING to the return value.
Create a function
CREATE FUNCTION MinDate()
RETURNS DATETIME WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(DATETIME, -53690)
END
Call the function
dbo.MinDate()
Example 1
PRINT dbo.MinDate()
Example 2
PRINT 'The minimimum date allowed in an SQL database is ' + CONVERT(VARCHAR(MAX), dbo.MinDate())
Example 3
SELECT * FROM Table WHERE DateValue > dbo.MinDate()
Example 4
SELECT dbo.MinDate() AS MinDate
Example 5
DECLARE #MinDate AS DATETIME = dbo.MinDate()
SELECT #MinDate AS MinDate
It's not January 1, 1753 but select cast('' as datetime) wich reveals: 1900-01-01 00:00:00.000 gives the default value by SQL server.
(Looks more uninitialized to me anyway)
This is what I use to get the minimum date in SQL Server. Please note that it is globalisation friendly:
CREATE FUNCTION [dbo].[DateTimeMinValue]()
RETURNS datetime
AS
BEGIN
RETURN (SELECT
CAST('17530101' AS datetime))
END
Call using:
SELECT [dbo].[DateTimeMinValue]()
What about the following?
declare #dateTimeMin as DATETIME = datefromparts(1753, 1, 1);
select #dateTimeMin;
The range for datetime will not change, as that would break backward compatibility. So you can hard code it.

Using Parameters in DATEADD function of a Query

I am trying to us the DateAdd function of SQL in my Query. The problem is when I use a parameter to set the second arguement, the number argument I get an error which will say something like this:
Failed to convert parameter value from
a Decimal to a DateTime
While if I enter it parameterless, i.e hardcode an Int, it works fine.
This works:
SELECT FieldOne, DateField
FROM Table
WHERE (DateField> DATEADD(day, -10, GETDATE()))
while this does not:
SELECT FieldOne, DateField
FROM Table
WHERE (DateField> DATEADD(day, #days, GETDATE()))
Where #days = -10
Any ideas into what I am doing wrong? Incidentally I am setting this variable in SQL Server Manager, as I am trying to work out a bug in my DataAccess code. Not sure if that makes a difference.
Thanks
I know this is an old post, but for anyone else having this problem I had a similar issue in Reporting Services 2008 R2, although the error message was "Argument data type nvarchar is invalid for argument 2 of dateadd function." I think this issue could be related.
The problem was caused by the way Reporting Services parses the SQL code to generate a report dataset. In my case, I was able to change this dataset query:
SELECT DateAdd(wk, #NumWeeks, calendar_date) AS ToWeekFromDate
FROM dim_date
to this:
SELECT DateAdd(wk, Convert(Int, #NumWeeks), calendar_date) AS ToWeekFromDate
FROM dim_date
and the error was resolved.
EDIT: Just to expand on this answer a little: the issue was that Reporting Services was unable to parse the correct data type for #NumWeeks, I think possibly due to it being inside the DateAdd() function, and was defaulting it to NVarchar. Adding an explicit Convert() to set the data type to Int (even though it was already a number) enabled the parser to correctly identify the data type for #NumWeeks.
It sounds like you're passing the decimal as the 3rd instead of the 2nd parameter to DATEADD(), like:
DATEADD(day, GETDATE(), #days)
Although the snippet in the question looks fine.
(For extra clarity, the snippet above is an error. This is the code that would generate the error from the question.)
The following code works perfectly fine here (SQL Server 2005, executed in Management Studio):
DECLARE #days decimal
SET #days = -10
SELECT DATEADD(day, #days, GETDATE())
as does the following
DECLARE #days decimal
SET #days = -10
SELECT * FROM myTable WHERE myDate > DATEADD(day, #days, GETDATE())
So, the problem must lie somewhere else...
Are you sure the error is associated with this statement? There are no decimals involved and if I try this it still works
DECLARE #days decimal (19,6)
SET #days = -10.3346
--result is actually irrelevant
IF CAST(40000.6 AS decimal (19,6)) > DATEADD(day, #days, GETDATE())
SELECT 'yes'
ELSE
SELECT 'no'
Even trying to cast -10 decimal to smalldatetime this gives a different error
SELECT CAST(CAST(-10 AS decimal (19,6)) AS smalldatetime)
Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type smalldatetime.

Resources