T-SQL-使用毫秒时出现算术溢出

T-SQL-使用毫秒时出现算术溢出,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我在TSQL中有一个非常简单的脚本,它试图将以毫秒为单位的时间戳转换为DATETIME数据类型。这还包括本地时间偏移 DECLARE @Time AS BIGINT SET @Time = 1413381394000 SELECT DATEADD(MILLISECOND, @Time - DATEDIFF(MILLISECOND, GETDATE(), GETUTCDATE()), CAST('1970-01-01 00:00:00' AS DATETIME))

我在TSQL中有一个非常简单的脚本,它试图将以毫秒为单位的时间戳转换为
DATETIME
数据类型。这还包括本地时间偏移

DECLARE @Time AS BIGINT
SET @Time = 1413381394000 
SELECT DATEADD(MILLISECOND, 
               @Time - DATEDIFF(MILLISECOND, GETDATE(), GETUTCDATE()), CAST('1970-01-01 00:00:00' AS DATETIME)) AS [Datetime]
它一直给我的错误是:

Arithmetic overflow error converting expression to data type int.
现在,我在这个查询中没有任何显式的
int
变量,我所做的任何
CAST()
to
BIGINT
DECIMAL(13,0)
都导致了相同的错误

这个查询中哪个部分是错误的?
int
DATEDIFF()
的默认返回数据类型吗

我知道我可以用
@Time
除以1000,然后用
秒来工作,而不是
毫秒来工作,我只想知道是否有一种方法可以直接用毫秒来工作,因为其思想是将此脚本用作内联表值函数(由于此查询之外的其他原因,无法使用标量函数).

确实返回了一个int,但我怀疑是它给出了错误消息

不幸的是,正如您所说,您需要以这种精度工作,因为您希望在毫秒内工作

DATEADD(日期部分、编号、日期)

number
是一个表达式,可以解析为添加到日期部分的int。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.
很明显,您可以使用循环或其他方法来编写代码,但显然您需要考虑成本/收益。

确实返回int,但我怀疑这会给您带来错误消息

不幸的是,正如您所说,您需要以这种精度工作,因为您希望在毫秒内工作

DATEADD(日期部分、编号、日期)

number
是一个表达式,可以解析为添加到日期部分的int。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.
很明显,您可以使用循环或其他方法来编写代码,但显然您需要考虑成本/收益。

确实返回int,但我怀疑这会给您带来错误消息

不幸的是,正如您所说,您需要以这种精度工作,因为您希望在毫秒内工作

DATEADD(日期部分、编号、日期)

number
是一个表达式,可以解析为添加到日期部分的int。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.
很明显,您可以使用循环或其他方法来编写代码,但显然您需要考虑成本/收益。

确实返回int,但我怀疑这会给您带来错误消息

不幸的是,正如您所说,您需要以这种精度工作,因为您希望在毫秒内工作

DATEADD(日期部分、编号、日期)

number
是一个表达式,可以解析为添加到日期部分的int。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.

显然,您可以使用循环或其他方法来编写代码,但显然您需要考虑成本/收益。

DATEADD的第二个参数应该是INT-not-BIGINT。转换为秒,然后传递到日期添加

DECLARE @Time AS BIGINT
SET @Time = 1413381394000 
DECLARE @seconds AS INT = @Time / 1000
SELECT DATEADD(SECOND, @seconds, ...)
如果不想损失毫秒,可以添加第二步:

DECLARE @milliseconds INT = @Time % 1000
SELECT DATEADD(MILLISECOND, @milliseconds, <date from before>)
DECLARE@millides INT=@Time%1000
选择日期添加(毫秒,@毫秒)

DATEADD的第二个参数应该是INT而不是BIGINT。转换为秒,然后传递到日期添加

DECLARE @Time AS BIGINT
SET @Time = 1413381394000 
DECLARE @seconds AS INT = @Time / 1000
SELECT DATEADD(SECOND, @seconds, ...)
如果不想损失毫秒,可以添加第二步:

DECLARE @milliseconds INT = @Time % 1000
SELECT DATEADD(MILLISECOND, @milliseconds, <date from before>)
DECLARE@millides INT=@Time%1000
选择日期添加(毫秒,@毫秒)

DATEADD的第二个参数应该是INT而不是BIGINT。转换为秒,然后传递到日期添加

DECLARE @Time AS BIGINT
SET @Time = 1413381394000 
DECLARE @seconds AS INT = @Time / 1000
SELECT DATEADD(SECOND, @seconds, ...)
如果不想损失毫秒,可以添加第二步:

DECLARE @milliseconds INT = @Time % 1000
SELECT DATEADD(MILLISECOND, @milliseconds, <date from before>)
DECLARE@millides INT=@Time%1000
选择日期添加(毫秒,@毫秒)

DATEADD的第二个参数应该是INT而不是BIGINT。转换为秒,然后传递到日期添加

DECLARE @Time AS BIGINT
SET @Time = 1413381394000 
DECLARE @seconds AS INT = @Time / 1000
SELECT DATEADD(SECOND, @seconds, ...)
如果不想损失毫秒,可以添加第二步:

DECLARE @milliseconds INT = @Time % 1000
SELECT DATEADD(MILLISECOND, @milliseconds, <date from before>)
DECLARE@millides INT=@Time%1000
选择日期添加(毫秒,@毫秒)

由于夏令时,您对本地偏移量的计算可能会错误一小时
DATEDIFF(毫秒,GETDATE(),GETUTCDATE())
将只获取当前偏移量,而不获取给定日期的偏移量。由于SQL缺乏用于此目的的功能,因此在应用程序或SQLCLR代码中处理UTC和本地时间之间的转换通常是最好的。看

Microsoft声明:

数字
可以解析为添加的int的表达式 日期的一部分。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.
因此,不能直接使用大于支持-2^31(-2147483648)到2^31-1(2147483647)范围的int的最大值的毫秒值,如中所述。你必须把日期加和一些模除法分开

DECLARE @Time bigint
DECLARE @Seconds int
DECLARE @RemainingMilliseconds int
DECLARE @EpochDate datetime

SET @Time = 1413381394000

SET @EpochDate = '1970-01-01 00:00:00'
SET @Seconds = @Time / 1000
SET @RemainingMilliseconds = @Time % 1000

SELECT DATEADD(MILLISECOND, @RemainingMilliseconds, DATEADD(SECOND,@Seconds, @EpochDate))

由于夏令时的原因,本地偏移的计算可能会错误一小时
DATEDIFF(毫秒,GETDATE(),GETUTCDATE())
将只获取当前偏移量,而不获取给定日期的偏移量。由于SQL缺乏用于此目的的功能,因此在应用程序或SQLCLR代码中处理UTC和本地时间之间的转换通常是最好的。看

Microsoft声明:

数字
可以解析为添加的int的表达式 日期的一部分。用户定义的变量是有效的

If you specify a value with a decimal fraction, the fraction is
truncated and not rounded.
因此,对于支持-2^31(-2147483648)到2^31-1(2)范围的整数,不能直接使用大于最大值的毫秒值