7

我有一些 SQL 可以将 javascript 日期转换为 SQL 日期,效果很好。但是,我遇到了一些太大并导致异常的数据:

将表达式转换为数据类型 int 的算术溢出错误

这是有问题的SQL:

  DATEADD(MILLISECOND, cast(569337307200000 as bigint) % 1000, DATEADD(SECOND, cast(569337307200000 as bigint) / 1000, '19700101'))

我在 SQL Server 2008 上运行它。

4

5 回答 5

10

只需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()))
于 2015-05-15T06:16:23.120 回答
6

我解决整数溢出问题的一种方法是从 microtime unix 时间戳中减去一个更新的日期。

DATEADD(s, (CreationTimeStamp/1000-1384128000), '2013-11-11') AS CreateDate,

这不会解决 OP 的问题,因为它们仍然会溢出日期列上的最大值。

于 2013-11-14T14:12:02.623 回答
3

根据MSDN,在DATEADD (datepart , number , date )

number是一个表达式,可以解析为添加到日期的日期部分的 int。用户定义的变量是有效的。如果您指定带有小数的值,则该小数将被截断而不是四舍五入。

另请注意,即使您将数字作为整数给出,取决于您的日期和日期部分,它也可能会溢出日期的最大范围,即 sql server 2008 的 31-12-9999

数字必须是整数。这是一个测试演示

于 2013-02-22T18:22:12.403 回答
1

我有同样的问题,我想满足 mssql 的日期时间范围

  • 最小日期时间:1753-01-01 00:00:00.000 (-6847804800)
  • 最大日期时间:9999-12-31 23:59:59.997 (253402300799)

为了实现这一点,我发现的唯一解决方案是循环使用带有 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'

希望它会有所帮助。

于 2018-11-06T18:35:12.407 回答
-2

我也遇到了这个问题。在我的sql语句中,当日期时间值为空时发生错误。

我的解决方案是使用“CASE When”检查日期时间值是否为空。只有当它不为空时才运行算术,问题就解决了。

于 2018-10-03T03:10:38.943 回答