SQL Server: (implicit?) date conversion failure from text - sql-server

I have the something akin to the following code:
DECLARE #EvalDate VARCHAR(254)
SET #Evaldate = '''4/30/2017'',''12/31/2016'',''12/31/2015'',''12/31/2014'',''12/31/2013'''
SELECT field1, field2, YEAR(datefield1) AS YR, datefield2
FROM table
WHERE datefield2 IN (#EvalDate)
When I run this code, I get the following error:
Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.
I'm pretty sure that the error comes from my SET #Evaldate statement since this used to run when I just entered the dates directly into the WHERE/IN clause. How can I correct this?
I am using SQL Server 2008 btw.

The error isn't from your SET command, it's from your WHERE statement. It's trying to convert the literal value '4/30/2017','12/31/2016','12/31/2015','12/31/2014','12/31/2013' into a date, and obviously failing.
You can't use a variable to insert multiple values into an IN like that. What this is doing is attempting to convert the entire string into a single date, and failing.
This should give you the results you want using a TABLE variable and doing a JOIN to it:
Declare #Dates Table
(
EvalDate Date
)
Insert #Dates (EvalDate)
Values ('2017-04-30'),
('2016-12-31'),
('2015-12-31'),
('2014-12-31'),
('2013-12-31');
SELECT field1, field2, YEAR(datefield1) AS YR, datefield2
FROM table T
Join #Dates D On D.EvalDate = T.DateField2
Additionally, you should always use the ISO standard date format (yyyy-MM-dd).

Related

Same code errors in a Stored Procedure, works in T-SQL

I have a stored procedure that calls a linked server like below. The column 'datestr' is of type char(8) and is not always properly formatted. It is usually yyyymmdd but since I do not control how that data is formatted, I am using the TRY_CAST to only get rows where I can format it into a date.
Executing the SP gives me the following error:
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Running the exact same code extracted from the SP in T-SQL returns data without error. I'm certain the issue is with the part of the WHERE clause with the DATEADD function hitting a value that is not able to be CAST into a date but I can't figure out why it runs differently in SP and extracted T-SQL.
I checked the plan using SET SHOWPLAN_ALL ON before running both and see some variations. Namely the estimated rows in the working query are much lower in the Remote Query operator (~200K vs. 15 mil)
CREATE Procedure [dbo].[SampleSP]
AS
SELECT top 50 tbl1.rowID as rowID,
year(datestr) as [year],
month(datestr) as [month],
count(*) AS CountRow
FROM [LinkedSer].[RemoteDB].[dbo].[tbl1] tbl1
inner join [dbo].[LocalTbl] tbl2 on tbl1.rowID = tbl2.rowID
WHERE tbl1.row_type = 'tbl1A'
and (TRY_CAST(tbl1.datestr AS date) IS NOT NULL
and tbl1.datestr > DATEADD(yy, -10, getdate()))
group BY tbl1.rowID, year(tbl1.datestr), month(tbl1.datestr)
The order the predicates are evaluated is plan-dependent. So you need to eliminate the potentially-invalid comparison from your code.
And simplifying to:
and TRY_CAST(tbl1.datestr AS date) > DATEADD(yy, -10, getdate())
should do the trick.

Char conversion to date fails depending on where clause

I am trying to set up a simple query on my data converting char YYYYMMDD to date type. I am using simple convert(date, MyDateColumn).
Select isdate(MyDateColumn),
convert(date,MyDateColumn)
FROM MyTable
WHERE MyTimeColumn = '000000'
Result: Conversion failed when converting date and/or time from character string.
Select isdate(MyDateColumn),
MyDateColumn
FROM MyTable
WHERE MyTimeColumn = '000000'
Result: 1 20190821
Select isdate(MyDateColumn),
convert(date,MyDateColumn)
FROM MyTable
WHERE MyDateColumn = '20190821' AND MyTimeColumn = '000000'
Result: 1 2019-08-21
I have observed that this query has failed for me for specific row above depending whether I added where clause to MyDateColumn. I have added where clause MyDateColumn=MyDateColumn as a workaround. Any idea for a better solution?
I am using SQL Server 2016 (13.0.5201.2). MyDateColumn is char(10) type
The best solution here is to stop storing your dates as text, in text columns, and to start using actual date columns instead. The conversion failure in your very first query is alarming, and would seem to indicate that either you have non dates stored, or maybe there is some trailing/leading whitespace. Since you are using SQL Server 2016, you may try the following query to flush out any non conforming date strings:
SELECT MyDateColumn
FROM MyTable
WHERE TRY_CONVERT(datetime, MyDateColumn) IS NULL;
Once you have located the problematical records, you may fix them, and then give your queries another try.

SQL DateTime Inserted Incorrectly From VB.NET

Have a table I'm logging information from a .NET program into.
The VB.NET app explicity dictates the format of the DATETIME string like below
responsedt = Date.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")
I then pass this into an INSERT statement that updates my table, however even though the entire setup of the SQL Server is en-GB (British English) the DateTime has gone in the following format:
2019-09-05 19:09:34.823
This was done yesterday so actually should be
2019-05-09 19:09:34.823
The day and month should be switched around, I have tried performing an update on the table post process to get it to update using the following code
FORMAT (xa.daterequested, 'yyyy-dd-MM HH:MM:ss.fff', 'en-gb')
How while this works in a SELECT statement it doesn't seem to work when I do the UPDATE statement.
It is not ideal to have to update all the records dates after the initial INSERT so a solution to either the .NET side of the issue or the SQL would be appreciated as its pickling my head.
You have 2 options to prevent the error from happening again:
Keep dates as date/time data types instead of converting them to strings.
Use formats that are not language or settings dependent. In SQL Server these would be YYYYMMDD hh:mm:ss.msss OR YYYY-MM-DDThh:mm:ss.mss (notice the T between date and time)
To correct the dates already inserted you could use the format codes in the CONVERT function.
UPDATE t SET
daterequested = STUFF( STUFF( StringDate, 5, 0, SUBSTRING(StringDate,7,2)), 9, 2, '')
FROM YourTable t
CROSS APPLY( SELECT CONVERT( varchar(25), '20190905 19:09:34.823', 121) AS StringDate) AS x;

Converting a MSSQL Datestamp to BIGINT for UNIX

I've been having trouble with something i cannot quite get my head around and I was wondering if you can help?
On my table, i have a column called
ADDEDDATE
This column shows the date in which an incident or ticket was added to the database table and its formatting is shown as the following example:
2015-08-25 09:58:14.967
I want to convert this to UNIX timestamp so first i have performed the following:
SELECT DATEDIFF(SECOND,{d '1970-01-01'}, ADDEDDATE) AS 'UNIX DATE ADDED' FROM dbo.TABLE
Running this I get integer values such as "1147855575". Now I understand in order to make this work on UNIX timestamp i need to use BIGINT to convert, so i wrote the following:
SELECT DATEDIFF(SECOND,{d '1970-01-01'}, ADDEDDATE) AS 'UNIX DATE ADDED',
CASE CAST(SUM('UNIX DATE ADDED' AS BIGINT) FROM dbo.TABLE
This returned an error:
Msg 195, Level 15, State 10, Line 2
'SUM' is not a recognized built-in function name.
So i did some googling and searching through Stackoverflow and found i did the second line wrong, it should look like:
SELECT DATEDIFF(SECOND,{d '1970-01-01'}, ADDEDDATE) AS 'UNIX DATE ADDED',
CASE CAST(BIGINT,'UNIX DATE ADDED') FROM dbo.TABLE
However this too fails with the following message:
Msg 1035, Level 15, State 10, Line 2
Incorrect syntax near 'CAST', expected 'AS'.
Can someone please assist me in trying to convert an entire column of integer data to BIGINT for UNIX Datestamp? I am using MSSQL (SSMS 2014).
Just:
SELECT CAST(DATEDIFF(SECOND, '1970-01-01', ADDEDDATE) AS bigint) AS 'UNIX DATE ADDED' FROM dbo.TABLE;
When you'll migrate on SQL Server 2016, you'll be able to use DATEDIFF_BIG

Converting NVARCHAR(255) to DATE

I'm trying to transfer some old SQL Server data using Excel into SQL Server. It seems that Import/Export Data application automatically sets most data columns to NVARCHAR(255). Problem I have, is one of my columns is supposed to be a DATE type, but all data in it looks like this 18.08.2000 14:48:15.
So, when I try to use this query:
SELECT CONVERT(Date, DATE_TIME, 113)
FROM someTable
I get this error:
Msg 9807, Level 16, State 0, Line 1
The input character string does not follow style 113, either change the input character string or use a different style.
None of the [styles] from CAST and CONVERT (Transact-SQL) are working in my case.
Any advise or help is greatly appreciated.
SOLVED:
UPDATE myTable
SET columnName = CONVERT(NVARCHAR(255),CONVERT(SMALLDATETIME, columnName,105))
ALTER TABLE myTable
ALTER COLUMN columnName SMALLDATETIME
So, if it will ever become useful to anyone, this is the exact code that changes datatype NVARCHAR to DATETIME:
UPDATE myTable
SET columnName = CONVERT(NVARCHAR(255),CONVERT(SMALLDATETIME, columnName,105))
ALTER TABLE myTable
ALTER COLUMN columnName SMALLDATETIME
As far as I can tell - style no. 103 (British/French) should work - no?
DECLARE #input NVARCHAR(255)
SET #input = '18.08.2000 14:48:15'
SELECT CONVERT(DATETIME, #input, 103)
Gives me the output of:
2000-08-18 14:48:15.000
which seems pretty reasonable, no??
If you are using SQL Server 2012, try:
PARSE(Date AS datetime USING 'en-GB')
Or if that doesn't work, try:
PARSE(Date AS datetime USING 'Et-EE')
The Estonian culture specifically uses '.' as a date separator (d.MM.yyyy H:mm:ss) so it should work.
(Both seem to work fine on SQL Fiddle)

Resources