You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft SQL Server:整数存储日期的WHERE子句转换报错问题

问题解决方法

报错原因

直接将整数类型的chinto(存储格式为YYYYMMDD)转换为datetime时,SQL Server会把该整数当作从1900-01-01开始的累计天数处理。而20240520这类数值远超出datetime类型的最大允许范围(对应最大天数为2958465,对应日期9999-12-31),因此触发算术溢出错误。

正确的转换与筛选方案

方案1:先转字符串再转日期(兼容所有SQL Server版本)

先将整数转换为8位字符串,再解析为日期类型,同时用TRY_CONVERT自动过滤无效日期值:

AND TRY_CONVERT(DATETIME, CONVERT(VARCHAR(8), h.chinto)) >= DATEADD(DAY, -30, GETDATE())

若需要主动排除非有效日期的数值(比如chinto为0或长度不足8位),可额外添加范围判断:

AND h.chinto BETWEEN 17530101 AND 99991231 -- 限定datetime支持的有效日期范围
AND TRY_CONVERT(DATETIME, CONVERT(VARCHAR(8), h.chinto)) >= DATEADD(DAY, -30, GETDATE())

方案2:使用DATEFROMPARTS函数(SQL Server 2012及以上版本)

拆分整数中的年、月、日部分,直接构造日期,效率更高且逻辑更清晰:

AND DATEFROMPARTS(
    h.chinto / 10000,     -- 提取年份(前4位)
    (h.chinto / 100) % 100, -- 提取月份(中间2位)
    h.chinto % 100        -- 提取日期(后2位)
) >= DATEADD(DAY, -30, GETDATE())

同样可先过滤无效数值避免异常:

AND h.chinto BETWEEN 17530101 AND 99991231
AND DATEFROMPARTS(h.chinto/10000, (h.chinto/100)%100, h.chinto%100) >= DATEADD(DAY, -30, GETDATE())

完整修改后的WHERE子句示例

以方案2为例,修改后的WHERE部分代码:

WHERE 
    h.chgpno = 'CTT0001'
    AND h.chinto BETWEEN 17530101 AND 99991231
    AND DATEFROMPARTS(h.chinto/10000, (h.chinto/100)%100, h.chinto%100) >= DATEADD(DAY, -30, GETDATE())

额外排查:找出无效数据

如果仍有报错,说明表中存在不符合YYYYMMDD格式的chinto值,可先查询定位这些数据:

SELECT chinto
FROM ACO.dbo.clmhdr
WHERE 
    chinto < 17530101 
    OR chinto > 99991231
    OR (chinto % 100) > 31 -- 日期大于31
    OR ((chinto / 100) % 100) > 12 -- 月份大于12

内容的提问来源于stack exchange,提问作者Mistymanor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:35:44