我有一些 SQL 可以将 javascript 日期转换为 SQL 日期,效果很好。但是,我遇到了一些数据太大并导致异常:
将表达式转换为数据类型 int 时出现算术溢出错误
这是有问题的 SQL:
DATEADD(MILLISECOND, cast(569337307200000 as bigint) % 1000, DATEADD(SECOND, cast(569337307200000 as bigint) / 1000, '19700101'))
我在 SQL Server 2008 上运行它。
只需分两步完成有问题的
DATEADD
,从较粗略的时间单位(秒、分钟、小时等)开始,然后在剩下的时间里回到细粒度的时间单位。
避免达到几周和几个月的水平,因为这需要实际的日历计算,我们希望系统能够处理这个问题。
下面的示例需要计算给定(可能)大电流持续时间(以毫秒为单位)的启动时间。
-- large durations can overflow the integer argument needed for DATEADD
-- so do as two steps subtracting minutes (60000ms) and then remaining milliseconds.
DATEADD(ms, -large_duration_ms%60000, DATEADD(minute, -large_duration_ms/60000, GETDATE()))
解决整数溢出问题的一种方法是从 microtime unix 时间戳中减去更新的日期。
DATEADD(s, (CreationTimeStamp/1000-1384128000), '2013-11-11') AS CreateDate,
这不会解决OP的问题,因为它们仍然会溢出日期列上的最大值。
我有同样的问题,我想满足mssql的日期时间范围
为了实现此目的,我找到的唯一解决方案是循环使用带有 int 范围值的 DATEADD。
所以基于这个答案:https://stackoverflow.com/a/2904294/687490
CREATE FUNCTION dbo.fn_ConvertToBigDateTime (@Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
DECLARE @result datetime = Convert(datetime, '01/01/1970');
DECLARE @LocalTimeOffset BIGINT
,@AdjustedLocalDatetime BIGINT
,@MinIntValue INT
,@MaxIntValue INT
,@RemainingSeconds BIGINT;
-- define int limit
SET @MinIntValue = -2147483648;
SET @MaxIntValue = 2147483647;
-- compute the datetime with the offset
SET @LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET @AdjustedLocalDatetime = @Datetime - @LocalTimeOffset
-- going to the future
WHILE(@AdjustedLocalDatetime>@MaxIntValue)
BEGIN
SET @AdjustedLocalDatetime = @AdjustedLocalDatetime - @MaxIntValue;
SELECT @result = Convert(datetime, dateadd(ss, @MaxIntValue,@result));
END
-- going back in the past
WHILE(@AdjustedLocalDatetime<@MinIntValue)
BEGIN
SET @AdjustedLocalDatetime = @AdjustedLocalDatetime - @MinIntValue;
SELECT @result = Convert(datetime, dateadd(ss, @MinIntValue,@result));
END
RETURN (SELECT DATEADD(second,@AdjustedLocalDatetime, @result))
END;
然后您可以使用以下命令测试该功能:
select dbo.fn_ConvertToBigDateTime(-6847804800) as 'min datetime',
dbo.fn_ConvertToBigDateTime(253402300799) as 'max datetime'
希望能有所帮助。
您可以尝试将毫秒转换为天,将天添加到 EPOCH 的开头,并将毫秒部分添加到末尾的日期。问题是您试图将毫秒转换为秒,对于较大日期的 INT 来说,这仍然是太大的数字。
DATEADD(MILLISECOND,
CAST(myLongDateMs AS BIGINT) % 86400000,
DATEADD(day,
CAST(myLongDateMs AS BIGINT) / 86400000,
'19700101'
)
)
您可以使用以下代码将时间戳从秒更改为小时,这应该使其足够小以成为整数。例如。 16719994800 是 '01/11/2499, 11:00:00' 的 bigint,适用于此。
DATEADD(hour, TimeStamp_here/3600, '1970-01-01 00:00:00') AS UTC_Time
我也遇到这个问题了。在我的sql语句中,当日期时间值为空时发生错误。
我的解决方案是使用“CASE When”检查日期时间值是否为空。只有当它不为空时才运行算术,问题就解决了。