SQL Server FUNCTION overflow int vs bigint

时间:2013-09-18 03:35:14

标签: sql sql-server

我正在使用SQL Server函数,它返回bigInt并在触发器中使用它来为类型bigint的列分配值。但是,当我运行触发器时,会发生溢出异常(Arithmetic overflow error converting expression to data type int.),即它将其视为int,而不是bigint

功能是:

ALTER FUNCTION [dbo].[longIntDateTime] ()
RETURNS bigint
AS
BEGIN
    -- Declare the return variable here
    DECLARE @ResultVar bigint;
    DECLARE @now Datetime;

    set @now = getdate();
    SET @ResultVar=DATEPART(YYYY,@now)*100000000 + DATEPART(MM,@now)*1000000 + DATEPART(DD,@now)*10000 + DATEPART(HH,@now)*100;
    --  DATEPART(HH,@now)*100 +  DATEPART(MI,@now);

    -- Return the result of the function
    RETURN (@ResultVar);
END

触发器是:

ALTER TRIGGER [dbo].[employeesInsert] 
ON  [dbo].[employees] 
AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    UPDATE employees
    SET changeTimeStamp = dbo.longIntDateTime()
    FROM inserted INNER JOIN employees On inserted._id = employees._id  
END

,表定义为:

CREATE TABLE [dbo].[employees](
    [_id] [int] IDENTITY(1,1) NOT NULL,
    [employee_name] [varchar](50) NOT NULL,
    [password] [varchar](50) NOT NULL,
    [isActive] [int] NOT NULL,
    [isDeleted] [int] NOT NULL,
    [changeTimeStamp] [bigint] NOT NULL,

    CONSTRAINT [PK_employees] PRIMARY KEY CLUSTERED ([_id] ASC)
)

ALTER TABLE [dbo].[employees] 
   ADD CONSTRAINT [DF_employees_isActive]  DEFAULT ((0)) FOR [isActive]

ALTER TABLE [dbo].[employees] 
   ADD CONSTRAINT [DF_employees_isDeleted]  DEFAULT ((0)) FOR [isDeleted]
GO

如果我从函数的第一个yyyy部分取出两个'0',则触发器成功,但是它会失败。

显然,产生的价值小于一个大的。

任何想法?

安东

2 个答案:

答案 0 :(得分:1)

问题在于这行代码:

SET @ResultVar=DATEPART(YYYY,@now)*100000000 + DATEPART(MM,@now)*1000000 + DATEPART(DD,@now)*10000 + DATEPART(HH,@now)*100;

常量被解释为int,因此整个计算都是这样完成的。您可以通过将第一个转换为bigint

来轻松解决此问题
SET @ResultVar=DATEPART(YYYY,@now)*cast(100000000 as bigint)+ DATEPART(MM,@now)*1000000 + DATEPART(DD,@now)*10000 + DATEPART(HH,@now)*100;

答案 1 :(得分:0)

这是因为DATEPART返回int。在乘以

之前尝试强制转换为bigint
cast (DATEPART(YYYY,@now) as bigint)*100000000