Reputation: 725
I know there are many posts about the error message "Conversion failed when converting date and/or time from character string" but I couldn't find out why I get the error.
I have a table (let's call it MyTable
) that has a varchar(255) column Filename
. Every filename has a date portion in it. For example:
[Filename]
-----------------
FILE-160105_1.CSV
FILE-160105_2.CSV
FILE-160106_1.CSV
FILE-160106_2.CSV
...
My task is to get the date part out of the filenames and filter the resultset to a specific range of dates. The first step works fine
SELECT Convert(date, SUBSTRING([Filename],6,6), 12) AS dat
FROM mytable
and I get a correct result without errors:
dat
----------
05.01.2016
05.01.2016
06.01.2016
06.01.2016
But now, when I put the SELECT-Statement above in a common table expression and filter the dat
column, I get the error as shown. The complete code which queries the base table in the database is as follows:
WITH CTE AS
(
SELECT Convert(date, SUBSTRING([Filename],6,6), 12) AS dat
FROM dbo.myTable
)
SELECT dat
FROM CTE
WHERE dat = Convert(date,'160105',12);
What I do not understand is, why the SELECT in the CTE gives me a result set, converted as date but the outer query tries to convert something.
Because I could not find the error, I thought, I could use another CTE to generate the same data as in MyTable
for testing. And the funny part is: The following example works, but when I query the basetable directly, an error is thrown. Why?
WITH mytable as
(
SELECT [Filename] FROM (VALUES ('FILE-160105_1.CSV'), ('FILE-160105_2.CSV'), ('FILE-160106_1.CSV'),
('FILE-160106_2.CSV')) AS Files([Filename])
)
, CTE AS
(
SELECT Convert(date, SUBSTRING([Filename],6,6), 12) AS dat
FROM mytable
)
SELECT dat
FROM CTE
WHERE dat = Convert(date,'160105',12);
This gives me the correct result:
dat
---------
05.01.2016
05.01.2016
It would be great if someone could help me. Thanks. PS: By the way: the session language in SQL-Server is set to us_english
******** UPDATE ******
In the comments there is an advice to use TRY_CAST. When I run the following code, SQL Server Returns no error. I get the result with all rows:
WITH CTE AS
(
SELECT Convert(date, SUBSTRING([Filename],6,6), 12) AS dat
FROM dbo.MyTable
WHERE [Filename] LIKE 'FILE-%'
)
SELECT dat, TRY_CAST(dat as date) as trydat
FROM CTE
When I look through the rows manually there are no NULLs in the column trydat
so the CAST was successful. BUT, when I put TRY_CAST in the WHERE Clause to filter the dat column the Statement Fails:
WITH CTE AS
(
SELECT Convert(date, SUBSTRING([Filename],6,6), 12) AS dat
FROM dbo.MyTable
WHERE [Filename] LIKE 'FILE-%'
)
SELECT dat
FROM CTE
WHERE TRY_CAST(dat as date) = '20160106';
I think there is something wrong with the table. When I create a new table and query it, there are no conversion problems.
Upvotes: 0
Views: 978
Reputation: 725
The hint from Matt Gibsons comment gave me the idea to re-write the query and use the APPLY-Operator instead.
The query works now with the SQL-Statement
SELECT [Filename], A1.dat
FROM dbo.MyTable
OUTER APPLY (SELECT Convert(date, SUBSTRING([Filename],6,6), 12)) AS A1(dat)
WHERE [Filename] LIKE 'FILE-%'
AND A1.dat = '20160120'
I think for the original-query the optimizer decides to first CAST AS date
and then filter the rows with [Filename] LIKE 'FILE-%'
.
This doesn't work because in the table are different filenames where the date is at different positions. But those I didn't want to query.
Upvotes: 1