从SQL中的字符串转换日期和/或时间时,转换失败

从SQL中的字符串转换日期和/或时间时,转换失败,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我的表中有以下列: year decimal(4,0) month decimal(2,0) day decimal(2,0) 我正试图将其转换为以下内容: SELECT (CAST (CAST(year AS varchar(4)) +CAST(month AS varchar(2)) +CAST(day AS varchar(2) ) AS date ) ) AS xDate FROM table

我的表中有以下列:

year  decimal(4,0)
month decimal(2,0)
day   decimal(2,0)
我正试图将其转换为以下内容:

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
但我得到了这个错误:

从字符串转换日期和/或时间时,转换失败


这个问题是因为表中有冗余数据(查询没有问题)。在您的表格中检查以下内容

1) 。天列的值不得大于相关月份中的最大天数(例如第2个月不得有30天或31天)


2) 。月列的值不得大于12或等于0

您的方法没有考虑到
可以是一位数字值。如果你有这样的争吵:

year  month  day
----  -----  ---
2014  7      18
CAST(CAST(year * 10000 + month * 100 + day AS char(8)) AS date)
您的方法将把这些部分连接为
2014718
,随后尝试将其转换为
date
将导致出现问题的错误

您可能打算组合如下部分:
20140718
,它将转换为
date
,而不会出现问题。对我来说,从数字部分获得该格式的最简单方法是这样:

year  month  day
----  -----  ---
2014  7      18
CAST(CAST(year * 10000 + month * 100 + day AS char(8)) AS date)
  • 计算
    年*10000+月*100+天

  • 将先前的结果转换为
    char(8)

  • 将字符串转换为日期

因此,在Transact-SQL中是这样的:

year  month  day
----  -----  ---
2014  7      18
CAST(CAST(year * 10000 + month * 100 + day AS char(8)) AS date)
在不同的注释中,我不可能知道你是否真的需要把你的日期存储成这样,当然,如果你坚持这样做的话,至少应该考虑使用整数类型。我意识到,
decimal(2,0)
可能对您起到某种约束作用,确保您的月或日值不能超过2位,但它仍然不能保护您不使用无效的月或日。另一个要点是
decimal(2,0)
需要比
int
更多的存储空间,更不用说
smallint
tinyint

所以,我觉得这很好

year  int,
month int,
day   int
但是,如果您希望尽可能节省存储空间,您也可以尝试以下方法:

year  smallint,
month tinyint,
day   tinyint
最后,为了确保这些列中不能有无效值,可以添加如下检查约束:

ALTER TABLE tablename
ADD CONSTRAINT CK_tablename_yearmonthday CHECK 
  ISDATE(CAST(year * 10000 + month * 100 + day AS char(8))) = 1
;
altertablename
添加约束CK\u tablename\u yearmonthday检查
ISDATE(铸造(年*10000+月*100+天,字符(8))=1

;你想转换成日期时间吗?我用硬编码的数字做了一个快速测试,它对我有效,所以你确定“年”、“月”和“日期”是数字并且在可接受的范围内吗?@Kris-我想转换成日期,但是,如果很容易转换为datetime,那么也可以,但我得到了错误。@jimo3-是的,它们是数字,但数据类型是decimal,并试图转换为Date数据类型。