У меня есть целевая таблица 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;