算术溢出错误:msg 8115,级别16,状态2

vohkndzv  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(439)

我遇到一个存储过程问题,导致:
将表达式转换为数据类型int时出现算术溢出错误。
有两个表,第一个从odbc连接中提取数据。数据包含活动及其开始时间。有一个每天运行的存储过程,它将这些开始时间转换为时间间隔。这在绝大多数时间都是有效的,但在过去的一年中,由于算术溢出错误,它已经失败了十几天。我试图将数据类型从int改为numeric,但这并没有解决问题。任何帮助/想法/想法都将不胜感激!
存储过程:

insert into [DB].[dbo].[Final_Table]
([resourceName]
      ,[eventdatetime]
      ,[EV2]
      ,[IntervalTime]
      ,[event])

(
SELECT DS1.[resourceName]
      ,DS2.[eventdatetime]
      ,DS1.[eventdatetime] as EV2
      ,CONVERT(varchar(8), DATEADD(ms, DATEDIFF(SECOND, DS2.[eventdatetime], DS1.[eventdatetime]) * 1000, 0), 114) AS [IntervalTime]
      ,DS2.[event]
FROM [DB].[dbo].[Staging_Table] DS1

INNER JOIN [DB].[dbo].[Staging_Table] DS2
    ON DS1.[resourceName] = DS2.[resourceName]
    AND DS1.[ID] = DS2.[ID] + 1)

暂存表:

CREATE TABLE [dbo].[Staging_Table](
    [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [resourceName] [varchar](50) NULL,
    [eventdatetime] [datetime] NULL,
    [event] [varchar](9) NULL,
PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

暂存表中的数据:

最终表格:

CREATE TABLE [dbo].[Final_Table](
    [resourceName] [varchar](50) NULL,
    [eventdatetime] [datetime] NULL,
    [EV2] [datetime] NULL,
    [IntervalTime] [varchar](8) NULL,
    [event] [varchar](9) NULL
) ON [PRIMARY]
GO

最终表格数据:

m3eecexj

m3eecexj1#

datediff函数返回 INT . 然后将其与1000相乘,得到以毫秒为单位的秒数结果。
但是,有时这可能会导致 overflow . 例如:

DECLARE @A DATETIME2 = '2000-01-01'
       ,@B DATETIME2 = '2001-01-01'

SELECT DATEDIFF(SECOND, @A, @B) * 1000

msg 8115,级别16,状态2,第5行算术溢出错误,将表达式转换为数据类型int。
所以,就投给 BIGINT 第一:

DECLARE @A DATETIME2 = '2000-01-01'
       ,@B DATETIME2 = '2001-01-01'

SELECT CAST(DATEDIFF(SECOND, @A, @B) AS BIGINT) * 1000

实际上,上面的方法并不能解决您的问题,因为如果您选中dateadd函数:
number参数不能超出int的范围。在以下语句中,number的参数超出int的范围1。这些语句都返回以下错误消息:“msg 8115,level 16,state 2,line 1。将表达式转换为数据类型int时出现算术溢出错误。“
这意味着即使你通过 BIGINT 值,您将继续得到以下错误:

DECLARE @C BIGINT = 31622400000    
SELECT DATEADD(MILLISECOND,  @C  , 0)

你需要用不同的方式来处理这种情况。例如,设置 MAX 如果您的差异超过 INT .

DECLARE @A DATETIME2 = '2000-01-01'
       ,@B DATETIME2 = '2001-01-01'

SELECT TRY_CAST(CAST(DATEDIFF(SECOND, @A, @B) AS BIGINT) * 1000 AS INT)

相关问题