У меня есть целевая таблица TargetTable, которая имеет столбец DECIMAL(20, 7). У меня также есть исходная таблица SourceTable, которая имеет столбец DECIMAL(20, 7), но значения в этой таблице все равно целые числа.
Когда я пытаюсь загрузить данные в TargetTable из SourceTable с помощью инструкции MERGE, я получаю стандартную ошибку.
Ошибка арифметического переполнения, преобразующая числовые данные в числовые данные.
Я действительно не понимаю, почему это произойдет, поскольку оба типа данных идентичны.
Однако это странно: когда я использую SELECT INTO on TargetTable для создания тестовой таблицы TestTable, измените цель слияния на TestTable, upsert завершает. Я также не понимаю, почему это было бы так, поскольку TargetTable и TestTable по большей части идентичны.
Кто-нибудь сталкивался с этим раньше, это ошибка, или есть какой-то неясный нюанс 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;
