使用MERGE的算术溢出错误(数字到数字):SQL Server错误?

时间:2012-06-07 14:51:24

标签: sql sql-server sql-server-2008

我有一个TargetTable列的目标表DECIMAL(20, 7)。我还有一个包含SourceTable列的源表DECIMAL(20, 7),但此表中的值都是整数。

当我尝试通过TargetTable语句将数据从SourceTable发送到MERGE时,我收到标准错误。

  

将数字转换为数据类型为数字的算术溢出错误。

我真的不明白为什么会发生这种情况,因为两种数据类型都相同。

但奇怪的是:当我在SELECT INTO上使用TargetTable创建测试表TestTable时,将合并目标更改为TestTable ,upsert完成。我也不明白为什么会出现这种情况,因为TargetTableTestTable大部分都是相同的。

之前有没有遇到过这个问题,这是一个错误,还是我错过了一些不为人知的SQL Server细微差别?


示例代码

失败:

SET NUMERIC_ROUNDABORT Off
GO

MERGE
    TargetTable Target
USING
    (
        SELECT
            cast(forecast as DECIMAL(20, 7)) forecast
          ,[SegmentID]
          ,[Country]
          ,[Environment]
          ,[YearColumn]
          ,[ForecastYear]
          ,[Criterion]
        FROM
            SourceTable
    ) Source
    ON
    (
        Target.SegmentID = Source.SegmentID
        AND Target.Country = Source.Country
        AND Target.Environment = Source.Environment
        AND Target.YearColumn = Source.YearColumn
        AND Target.ForecastYear = Source.ForecastYear
        AND Target.Criterion = Source.Criterion
    )
WHEN NOT MATCHED BY TARGET AND Source.Forecast <> 0 AND Source.Forecast IS NOT NULL THEN
    INSERT (SegmentID, Country, Environment, YearColumn, Forecast, ForecastYear, Criterion)
    VALUES (Source.SegmentID, Source.Country, Source.Environment, Source.YearColumn, Source.Forecast, Source.ForecastYear, Source.Criterion)
WHEN MATCHED AND (Source.Forecast = 0 OR Source.Forecast IS NULL) THEN
    DELETE
WHEN MATCHED AND Source.Forecast <> Target.Forecast THEN
    UPDATE SET Target.Forecast = Source.Forecast;

成功:

SELECT
    *
INTO
    TestTable
FROM
    TargetTable
GO

SET NUMERIC_ROUNDABORT Off
GO

MERGE
    TestTable Target
USING
    (
        SELECT
            cast(forecast as DECIMAL(20, 7)) forecast
          ,[SegmentID]
          ,[Country]
          ,[Environment]
          ,[YearColumn]
          ,[ForecastYear]
          ,[Criterion]
        FROM
            SourceTable
    ) Source
    ON
    (
        Target.SegmentID = Source.SegmentID
        AND Target.Country = Source.Country
        AND Target.Environment = Source.Environment
        AND Target.YearColumn = Source.YearColumn
        AND Target.ForecastYear = Source.ForecastYear
        AND Target.Criterion = Source.Criterion
    )
WHEN NOT MATCHED BY TARGET AND Source.Forecast <> 0 AND Source.Forecast IS NOT NULL THEN
    INSERT (SegmentID, Country, Environment, YearColumn, Forecast, ForecastYear, Criterion)
    VALUES (Source.SegmentID, Source.Country, Source.Environment, Source.YearColumn, Source.Forecast, Source.ForecastYear, Source.Criterion)
WHEN MATCHED AND (Source.Forecast = 0 OR Source.Forecast IS NULL) THEN
    DELETE
WHEN MATCHED AND Source.Forecast <> Target.Forecast THEN
    UPDATE SET Target.Forecast = Source.Forecast;

2 个答案:

答案 0 :(得分:9)

您的代码似乎没有任何错误。此外,当您使用与原始表显示错误不存在的相同结构和数据时,它在您创建另一个表作为目标时工作正常。最可能的原因是您的原始表上有一个触发器正在执行失败的查询,这就是您所看到的错误。

答案 1 :(得分:0)

发生这种类型的错误是因为您可以对特定的表使用触发器,但是表上下文或数据库中的某些更改会执行,因此它会显示这种类型的错误,因此请禁用触发器并执行任务