简体   繁体   中英

Conversion failed when converting date and/or time from character string in SQL

I have the following columns in my table:

year  decimal(4,0)
month decimal(2,0)
day   decimal(2,0)

and I am trying to convert them as below:

SELECT (CAST (CAST(year  AS varchar(4))
             +CAST(month AS varchar(2))
             +CAST(day   AS varchar(2)
             ) AS date ) ) AS xDate
FROM table 
ORDER BY xDate DESC

But I am getting this error:

Conversion failed when converting date and/or time from character string.

Your approach does not take into account that month or day can be a single-digit value. If you had a row like this:

year  month  day
----  -----  ---
2014  7      18

your method would concatenate the parts as 2014718 and the subsequent attempt to convert that into a date would result in the error in question.

You probably meant to combine the parts like this: 20140718 , which would convert to date without issues. To me, the easiest way to get to that format from numerical parts is to go like this:

  • calculate year * 10000 + month * 100 + day ;

  • convert the previous result to char(8) ;

  • convert the string to date .

So, in Transact-SQL it would be like this:

CAST(CAST(year * 10000 + month * 100 + day AS char(8)) AS date)

On a different note, I cannot possibly know whether you really need to store your dates split like that, of course, but if you do insist on doing so, at least consider using integer type(s) for the parts. I realise that decimal(2,0) may serve as some kind of constraint for you that makes sure that you cannot have month or day values with more than 2 digits, but it still does not protect you from having invalid months or days. And another major point is decimal(2,0) requires more storage space than even int , let alone smallint or tinyint .

So, this would seem fine to me

year  int,
month int,
day   int

but if you are into saving the storage space as much as possible, you could also try this:

year  smallint,
month tinyint,
day   tinyint

Finally, to make sure you cannot have invalid values in those columns, you could add a check constraint like below:

ALTER TABLE tablename
ADD CONSTRAINT CK_tablename_yearmonthday CHECK 
  ISDATE(CAST(year * 10000 + month * 100 + day AS char(8))) = 1
;

This issue is because you have redundant data in your table(Nothing wrong with your query). check following in your table.

1). values for days columns must not be greater than max number of days in associated month (eg month 2 must not have 30 or 31 days in it).

2). value for month column must not be greater than 12 or equal to 0 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM