SQL不允许将日期列强制转换为datetime?

SQL不允许将日期列强制转换为datetime?,sql,sql-server,date,datetime,Sql,Sql Server,Date,Datetime,表A.date中存储的值为“2015-08-24”,表示数据没有问题 当我执行上述语句时,我得到 将日期数据类型转换为日期时间数据类型导致值超出范围 我可以知道为什么不能将日期列强制转换为datetime吗?使用SQL Server中通用的格式yyyymmdd Select * from tableA inner join tableB on tableA.id = tableB.aid and cast(a.date AS DATETIME) = CA

表A.date中存储的值为“2015-08-24”,表示数据没有问题

当我执行上述语句时,我得到

将日期数据类型转换为日期时间数据类型导致值超出范围


我可以知道为什么不能将日期列强制转换为datetime吗?

使用SQL Server中通用的格式yyyymmdd

Select * 
from tableA 
inner join tableB on tableA.id = tableB.aid 
                  and cast(a.date AS DATETIME) = CAST('2015-08-24' AS DATETIME) 
我没有发现a.Date中的“0001-01-01”值有问题。你可以做一个像这样的肮脏的把戏:

Select * from tableA inner join tableB 
on tableA.id = tableB.aid 
and cast(a.date AS DATETIME) = CAST('20150824' AS DATETIME) 

尝试合并ISDATE以确保数据有效。听起来像tableA.date是一个字符串

Select * from tableA inner join tableB 
on tableA.id = tableB.aid 
and case when substring(a.date, 1, 2) not in ('19', '20') then null else CAST(a.date AS DATETIME) end = CAST('20150824' AS DATETIME) 
问题的根本原因是:

数据类型日期的可接受值范围为01-01-0001到12-31-9999 数据类型DATETIME的可接受值范围为01-01-1753到12-31-9999 因此,如果您恰好有一个1753年之前的日期,或者一个空/空值,这将超出DATETIME可以处理的范围

您应该停止在SQL Server 2008及更新版本中使用DATETIME。改用DATETIME2n,其中n表示所需的小数秒数

所以试试这个:

    Select * from tableA inner join tableB 
        on tableA.id = tableB.aid 
        and ISDATE(tableA.date)
        and cast(tableA.date AS DATETIME) = CAST('2015-08-24' AS DATETIME)

我确信这会很好地工作。

您确定a.date中的所有值都是明确格式的有效日期吗?e、 2015年1月2日是不明确的,因为它可能是2月2日的1月2日1st@D斯坦利:它有一行数据,值为“0001-01-01”,这可能是它向我抛出该错误的原因吗?@Mr.sequestesheep Yes。DateTime的最小值为“01-01-1753”。请尝试运行此查询并查看无效记录。从表a中选择*where isdatea.date=0如果使用IsDate,请不要错误地认为可以通过将IsDate放在第一位来短路where谓词。在sql server中不能这样做以确保操作顺序。理想情况下,您应该将表的数据类型更改为datetime,并停止将此数据存储为字符串。停止使用datetime如果您使用CRM ERP和许多其他知名软件包,这是一个困难或不现实的解决方案。常见的错误是假设日期小于日期时间。它们是不同的,我更喜欢避免过滤不可强制转换值的问题:isnullplain_date,'0001-01-01'>'1753-01-01'@diegoscaravagi:就所需空间而言,它们是不同的-日期需要3个字节,而日期时间需要8个字节,覆盖的范围也更小!抱歉,我的意思是,假设日期只是DATETIME的YYYY-MM-DD部分是一个常见错误,通常99.99%的crm erp数据可能部分为真。在我的情况下,这个错误是由来自CSV的错误etl引起的,我们发现DBMS中的一列被转换为DATETIME。我很高兴你添加了这个答案!
select * 
from tableA 
inner join tableB on tableA.id = tableB.aid 
                  and cast(a.date AS DATETIME2(3)) = CAST('2015-08-24' AS DATETIME2(3))