SQL:将DATEADD与bigint一起使用

时间:2013-02-22 18:05:23

标签: sql sql-server-2008

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

  

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

以下是有问题的SQL:

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

我在SQL Server 2008上运行它。

5 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:2)

只需要分两步完成有问题的DATEADD,从较粗的时间单位(秒,分钟,小时等)开始,然后再回到细粒度的剩余部分。

避免达到几周和几个月的水平,因为这需要实际的日历计算,我们希望系统能够处理它。

以下示例需要计算开始时间,以毫秒为单位给出(可能)大电流持续时间。

- 大的持续时间可能会溢出DATEADD所需的整数参数

- 两个步骤减去分钟(60000ms)然后剩余毫秒。

DATEADD(ms,-large_duration_ms%60000,DATEADD(day,-large_duration_ms / 60000,GETDATE()))

答案 2 :(得分:1)

根据MSDNDATEADD (datepart , number , date )

  

数字是一个表达式,可以解析为添加的   到日期的日期部分。用户定义的变量有效。如果你   指定一个带小数部分的值,该部分被截断并且   不圆润。

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

数字必须是整数。这是Test Demo

答案 3 :(得分:0)

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

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

要实现这一目标,我发现的唯一解决方案是循环使用具有整数范围值的DATEADD。

因此,根据以下答案:{{3}}

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'

希望这会有所帮助。

答案 4 :(得分:-2)

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

我的解决方案是使用“ CASE When”检查日期时间值是否为空。仅在算术不为null时运行算术,问题得以解决。