This question already has answers here:
Conversion to datetime fails only on WHERE clause?
(6 answers)
Conversion failed when converting from a character string to uniqueidentifier error in SQL Server
(4 answers)
Closed 6 years ago.
I have been hitting a strange issue lately on SQL Server.
The application I am using is saving user's attributes in a table containing user/attribute/value records. I need to find whether a user is still valid using his end of validity date. The query I have been using is the following:
SELECT COUNT(*) FROM value_all
WHERE AttrName = 'VALIDTO' AND
userkey=574924 AND
CONVERT (DATE,Value, 120) < GETDATE();
The conversion is necessary because all values are stored as VARCHAR.
The query was working correctly but lately I have been hitting the following error:
SQL Error [241] [S0001]: Conversion failed when converting date and/or time from character string.
I though that the stored validity date was wrong. However, the value does match the correct format:
SELECT * FROM value_all
WHERE AttrName = 'VALIDTO' AND
userkey=574924 AND
|userkey |AttrName |Value |
|--------|-----------|--------------------|
|574924 |VALIDTO |2016-07-31T23:59:59 |
I can even do a convert and show the result correctly:
SELECT CONVERT (DATE,Value, 120) AS Date FROM value_all
WHERE AttrName = 'VALIDTO' AND
userkey=574924 AND
CONVERT (DATE,Value, 120) < GETDATE();
|Date |
|-----------|
|2016-07-31 |
However, as soon as I add the COUNT, the error is coming back.
Does any-one have an idea of what is going on in this case? Is it linked, in some way, to the value used?
EDIT
Thanks to the question at "Conversion to datetime fails only on WHERE clause?", I was able to rework my query as follow, which correct the issues I had:
SELECT COUNT(*) FROM value_all
WHERE AttrName = 'VALIDTO' AND
userkey=574924 AND
CONVERT (DATE, CASE WHEN ISDATE(Value) THEN Value END, 120) < GETDATE();
The answer is that there is no guarantee of the order in which the WHERE clause operates. It looks like it may be applying the Convert of the value field before it filters the rows on userkey or attrName. Most likely the count is causing the plan to change which is just an unlucky side effect.
You chould retrieve the row with the userkey and attrname and then convert the value.
Curious, is there an index on the userkey field? And on attrname?
Related
Im trying to update table using code below but got error SQL Error: ORA-01840: input value not long enough for date format, DUE_ON_DT_WID is a number column with sample records like this '20191231' and the expected sult on X_NEED_BY_DATE is '31-DEC-19'. X_NEED_BY_DT is a date column. Thank you in advance for the help.
update ADW12_DW.W_PURCH_COST_F T
set (
T.X_NEED_BY_DT
) =
(
select
TO_DATE(DUE_ON_DT_WID,'YYYYMMDD')
from ADW12_DW.I$_1200778522_6 S
where T.DATASOURCE_NUM_ID =S.DATASOURCE_NUM_ID
and T.INTEGRATION_ID =S.INTEGRATION_ID
)
where (DATASOURCE_NUM_ID, INTEGRATION_ID)
in (
select DATASOURCE_NUM_ID,
INTEGRATION_ID
from ADW12_DW.I$_1200778522_6
where IND_UPDATE = 'U'
)
There must be an issue with your data as format YYYYMMDD must have 8 as the length of data (as Year is coming first in your data).
Please find the issue data using the following query and correct it.
select * from ADW12_DW.I$_1200778522_6 where length(DUE_ON_DT_WID) <> 8
I think you have the data like this 20191231 and also 191231. do you want to consider them as the same? i.e. '31-DEC-19' then you need to use the CASE..WHEN and RR/YYYY for formatting the Year as follows:
CASE WHEN LENGTH(DUE_ON_DT_WID) = 6 THEN
TO_DATE(DUE_ON_DT_WID,'RRMMDD')
WHEN LENGTH(DUE_ON_DT_WID) = 8 THEN
TO_DATE(DUE_ON_DT_WID,'YYYYMMDD')
END
If you are using Oracle 12.2 or higher then you can use ON CONVERSION ERROR clause in the TO_DATE to default some value when the conversion from your column to date fails as follows:
TO_DATE(DUE_ON_DT_WID DEFAULT '20010101' ON CONVERSION ERROR, 'YYYYMMDD' )
This question already has answers here:
Equals(=) vs. LIKE for date data type
(3 answers)
Closed 5 years ago.
Query 1 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM = '25-JAN-13';
Result: 1
Query 2 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM like '25-JAN-13';
Result: 19
In my DB I have 19 rows with TXN_HEADER_DTTM as 25-JAN-13.
Data Type of TXN_HEADER_DTTM is DATE.
Can someone please explain the difference in output?
An Oracle DATE column contains a date and a time. The LIKE condition is only for VARCHAR columns. If applied to other data types Oracle implicitly converts that to a varchar (using rules depending on the current client settings).
So you might have rows with e.g. 2013-01-25 17:42:01, however the string constant '25-JAN-13' is (most probably) converted to: 2013-01-25 00:00:00 and thus the = comparison doesn't work.
To find all rows for a specific day use trunc() and a proper date literal. Don't rely on the evil implicit data type conversion to specify date values.
Use trunc() to set the time part of a DATE value to 00:00:00:
I prefer ANSI SQL date literals:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = DATE '2013-01-25';
You can also use Oracle's to_date:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = to_date('2013-01-25', 'yyyy-mm-dd');
Note that Oracle can't use an index on TXN_HEADER_DTT, so if performance is critical use a range query:
select count(*)
from CI_TXN_HEADER
where TXN_HEADER_DTTM >= DATE '2013-01-25'
and TXN_HEADER_DTTM < DATE '2013-01-25' + 1;
The difference between like and equal is explained in this link very good
https://stackoverflow.com/a/2336940/4506285
I checked your problem on my table and I get the same results.
This link helps also to understand how to compare dates in sql
https://stackoverflow.com/a/18505739/4506285
Maybe your data consists of space, it is not exactly '25-JAN-13' but ' 25-JAN-13';
Please refer this two link:
Equals(=) vs. LIKE
What's the difference between "LIKE" and "=" in SQL?
So I'm writing a SQL query and it gives me an odd error:
Conversion failed when converting the varchar value 'J' to data type int
I narrowed it down to a LEFT(ProjApprovelDate,1), which for some reason gives me a J.
ProjApprovelDate is a DateTime most of the time, there are a few instances where it is entered incorrectly and is an int instead. To find these I've used (LEFT(ap.ApprovalDate,1) != 1 and LEFT(ap.ApprovalDate,1) != 2). It always begins with either a 1 or 2 when it's in the wrong format. The whole column (in the original table) is int format and shows up with most dates like 20170614, but there are several that show up like 1170614 instead. I'm converting these into the correct format and inserting them all into a new table with this column as DateTime so that it correctly makes them into a date.
When reviewing to make sure that I got them all I found this interesting case where the ones that are already formatted correctly as DateTime give me a J.
So my question is why does taking the first LEFT character of a DateTime give a J for the output?
The implicit conversion is a string, so...
Select cast(getdate() as varchar(25))
,left(getdate(),1)
Returns
(No column name) (No column name)
Jun 14 2017 10:28AM J
Take a peek at https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine
Just for fun, try
Select left(25,1)
This question already has answers here:
Conversion failed when converting date and/or time from character string while inserting datetime
(18 answers)
Closed 7 years ago.
I'm trying to update field (Type of Date) from a string field.
The string field example : 20/10/2015
I am new in sql. I tried this query:
UPDATE [dbo].[EmployeeWithCompCar]
SET [EMER_AttachEndDate] = cast([EMER_info1] as date)
I get this message:
Conversion failed when converting date and/or time from character string.
Can you help me fix it?
Thank's!
You need to use convert() with a format. So try this:
UPDATE [dbo].[EmployeeWithCompCar]
SET [EMER_AttachEndDate] = convert(date, [EMER_info1], 103);
The formats are available in the documentation.
Note: In SQL Server 2012+, use try_convert() instead of convert(). That way, if a string is in the wrong format, the result is NULL instead of an error.
You can use CONVERT with the format style 103.
UPDATE [DBO].[EMPLOYEEWITHCOMPCAR]
SET [EMER_ATTACHENDDATE] = CONVERT(DATE, [EMER_INFO1], 103)
And if you don't blank to be updated to 1900-01-01 you can use NULLIF function to avoid that.
UPDATE [DBO].[EMPLOYEEWITHCOMPCAR]
SET [EMER_ATTACHENDDATE] = CONVERT(DATE, NULLIF([EMER_INFO1], ''), 103)
Date Formats in SQL Server
NULLIF
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)