I have the following line in a TVF:
CASE WHEN MIN(ISNULL(EersteStart,GETDATE())) = GETDATE()
then 'InOverleg'
else MIN(ISNULL(EersteStart,GETDATE())) end as EersteStartDatum
Except the fact that this seems kind of inefficiënt it still does not work, since
it generates the following error:
Conversion failed when converting date and/or time from character string.
I understand the error but how can I adjust the query to provide the functionality I want? (return string 'InOverleg' when the underlying query returns null for all EersteStartDatum fields of each row or show the MIN date when there are rows where EersteStartDatum is not NULL).
What is confusing? case is an expression and needs to return one type. SQL Server tends to convert to the more restrictive type. In this case, the more restrictive time is a datetime. 'InOverLeg' does not convert.
You can convert the date to a string:
(CASE WHEN MIN(COALESCE(EersteStart, GETDATE())) = GETDATE()
THEN 'InOverleg'
ELSE CONVERT(VARCHAR(10), MIN(COALESCE(EersteStart, GETDATE())), 121) -- or whatever format you like
END) as EersteStartDatum
Use CAST(data_to_return AS varchar(my_desired_string_length)) for all your return data (then result and else result). Now you will have string returned in any case.
Related
I've created a view, and a part of the code looks like this:
, IIF (ownedbyteamt = 'Validation'
AND (titlet LIKE '%Build validation%'
OR
titlet LIKE '%OP Build%'),
CAST(closeddatetimet AS NVARCHAR(255)), '-1111111') AS 'OP_Build_Validation'
Then, I used this view in a join with the table and the code that I have there looks like this:
,(
CASE
WHEN cher.[Max_OP Build Validation] <> -111111
AND cher.max_cf <> -111111
AND cher.max_cf >= cher.max_op_build _validation
THEN DATEDIFF(DAY, CONVERT(DATE, cher.max_cf), CONVERT(DATE, cher.max_op_build_validation))
ELSE '07/07/1777'
END) AS 'Days-Cf'
Now, I get this error:
Conversion failed when converting date and/or time from character string.
What am I doing wrong?
Thanks
A case expression returns a single value with a specified type.
You have a then clause that returns a datediff(). That is an integer.
You have an else clause that returns a string.
When there are different types, SQL Server uses type conversion rules to figure out what to do. In this case, it tries to convert everything to an integer -- and you get an error.
I have 4 string-datatype columns in a SQL Server 2008 SP4 table that should be dates. I cant change that so I need a way to convert those strings to dates. The string is formatted as "YYYY-MM-DD".
For 2 of those columns, a CONVERT(datetime, [columname], 101) works but the other 2 have strings that go like this "1700-01-01" and when I try to convert them it shows a conversion out-of-range error.
I expect all strings values to be converted to a date, if the conversion fails I rather have it as a blank or any other way, I accept recommendations when handling date conversions errors. This table will be extensively used in applications made in C#/VBA and excel queries. Specifically for Excel, I need a friendly way to show this conversion errors in queries.
You can use TRY_CONVERT() which returns null if the conversion is not possible:
TRY_CONVERT(datetime, '1700-01-01', 101)
will return null instead of an error.
I think this works for SQL Server 2012+
If your version does not support it, you can check for the year part of the string and do something like this:
case
when left([columname], 4) < '1753' then null
else CONVERT(datetime, [columname], 101)
end
Depending on SQL Server version, you can try using:
TRY_CONVERT(DATETIME, [columnname], 101)
Instead of failing, this will produce a NULL value that you can then handle gracefully.
I didn't spot you're using SQL Server 2008. You could try using ISDATE() function.
SELECT CASE ISDATE('1700-01-01')
WHEN 1 THEN CONVERT(DATETIME, '1700-01-01', 101)
ELSE NULL
END AS Converted
This is probably best you can use. I'm not 100% sure if ISDATE() always behaves correctly, given that ISNUMERIC() has issues.
I currently have dates stored in a general attribute field in the database as a string.
They are all stored in the format DD/MM/YYYY for example 01/01/2000
I am able to convert them them to datetime successfully by using the following in my select statement. For example CONVERT(DATETIME, attribute.field_value, 103) where attribute.field_value contains a date.
The SELECT statement works fine and returns the whole table with them correctly.
I can also return a column with todays date in the same format as follows CAST(getdate() AS datetime)
The problem occurs when I try to compare, now I only want to return everything that is newer than today in pseudo code that would dateNewerThanToday > dateToday
Therefore I have tried
WHERE CONVERT(DATETIME, attribute.field_value, 103) > CAST(getdate() AS datetime)
this gives me the error
Conversion failed when converting datetime from character string.
I have tried a multitude of cast/converts to get it to work. I have also wrapped by select so I am only doing it on dataset with the correct data.
Any help would be super useful! Many thanks in advance!!
A couple of things ..
You do not need to convert to GETDATE() to DATETIME data type as it already returns datetime data type.
Instead of CONVERT(DATETIME, attribute.field_value, 103)
use
CONVERT(DATETIME, attribute.field_value) or CAST(attribute.field_value AS DATETIME)
Add a where clause in your select to get only valid DATETIME values. something like
WHERE ISDATE(attribute.field_value) = 1
This will filter out any values which appears to be a date value but sql server doesnt see them as valid date values.
Important Not
Use appropriate data types. If this column is storing date values why not use the DATE or DATETIME data types.
I ran into this exact problem.
Values from a VARCHAR(50) column returned in the SELECT could be cast as date without issue. However when cast in a comparison in the WHERE clause the error occurred.
Of note, the error only occurred when I had other restrictions in the WHERE clause.
When I added ISDATE() to the WHERE clause, the error no longer occurred.
e.g. Shortened example of what worked:
SELECT CONVERT(DATE, mat.myAttributeColumn), mdct.myDateComparisonColumn
FROM myAttributeTable mat
JOIN myDateComparisonTable mdct ON mdct.key = mat.key
WHERE ISDATE(mat.myAttributeColumn) = 1
and mdct.myDateComparisonColumn < convert(DATE, mat.myAttributeColumn)
I have a table and need to verify that a certain column contains only dates. I'm trying to count the number of records that are not follow a date format. If I check a field that I did not define as type "date" then the query works. However, when I check a field that I defined as a date it does not.
Query:
SELECT
count(case when ISDATE(Date_Field) = 0 then 1 end) as 'Date_Error'
FROM [table]
Column definition:
Date_Field(date, null)
Sample data: '2010-06-27'
Error Message:
Argument data type date is invalid for argument 1 of isdate function.
Any insight as to why this query is not working for fields I defined as dates?
Thanks!
If you defined the column with the Date type, it IS a Date. Period. This check is completely unnecessary.
What you may want to do is look for NULL values in the column:
SELECT SUM(case when Date_Field IS NULL THEN 1 ELSE 0 end) as 'Date_Error' FROM [table]
I also sense an additional misunderstanding about how Date fields, including DateTime and DateTime2, work in Sql Server. The values in these fields are not stored as a string in any format at all. They are stored in a binary/numeric format, and only shown as a string as a convenience in your query tool. And that's a good thing. If you want the date in a particular format, use the CONVERT() function in your query, or even better, let your client application handle the formatting.
ISDATE() only evaluates against a STRING-like parameter (varchar, nvarachar, char,...)
To be sure, ISDATE()'s parameter should come wrapped in a cast() function.
i.e.
Select isdate(cast(parameter as nvarchar))
should return either 1 or 0, even if it's a MULL value.
Hope this helps.
IsDate takes a character string or exression that yeilds a character string as it's argument
The problem is this method ISDATE() only admits arguments of type datetime and smalldatetime within the "time" types, so it won´t work if you are using date type.
Also if you use date as type for that field, you won´t have to check the information there because it won´t admit other type of field.
You shoul only check for null values in your column, that´s all.
I have a date column with dates stored as strings, such as 20120817. Unfortunately, the text form field that populates this column is free text, so I cannot guarantee that an occasional "E" or "whatever" shows up in this column. And more than a few already have.
What I need to do is convert the string column into a date column. Of course the convert will reject the random string characters. Is there any way to create a derived column that will not only convert the strings but exclude the non-date convertible strings?
If there were no non-date convertible strings in the table, the following would work:
ADD [convertedDate] AS CONVERT(DATE, [stringDate], 102)
And it does work perfectly in a test table I created. But when I introduce other non-convertible strings, I receive the dreaded "Conversion failed when converting date and/or time from character string" error for obvious reasons.
Is there a function that will catch non-convertible elements that I can add on to this derived column code? Or is a view or function the only - or best - way to handle this? I played around with IsDate() with little luck.
Thank you!
There's a function called ISDATE(date), maybe you can use it in a CASE statement or in the WHERE part of the query... It depends on how you're doing it, maybe something like this
ADD [convertedDate] AS CASE WHEN ISDATE([stringDate]) = 1 THEN CONVERT(DATE,[stringDate], 102) ELSE NULL END
If you're using SQL Server 2012 you can make use of the try_convert function
http://msdn.microsoft.com/en-us/library/hh230993.aspx
It will work normally if the conversion succeeds but return null if the conversion fails
ADD [convertedDate] AS TRY_CONVERT(DATE, [stringDate], 102)
This should give you some ideas...
DECLARE #date1 varchar(50)
DECLARE #date2 varchar(50)
SET #date1 = '20120101'
SET #date2 = 'e20120101'
SELECT
ISDATE(#date1),
ISDATE(#date2),
CASE WHEN ISDATE(#date1) = 1 THEN CONVERT(SMALLDATETIME,#date1) END,
CASE WHEN ISDATE(#date2) = 1 THEN CONVERT(SMALLDATETIME,#date2) END