대상 테이블 TargetTable
에는 DECIMAL(20, 7)
컬럼이 있습니다. 또한 DECIMAL(20, 7)
컬럼을 가지고있는 소스 테이블 SourceTable
을 가지고 있지만,이 테이블의 값은 모두 정수입니다.MERGE로 산술 오버플로 오류 (숫자를 숫자로 나타냄) : SQL Server 버그?
TargetTable
에 SourceTable
에서 MERGE
문을 사용하여 데이터를 업 샘플하려고하면 표준 오류가 발생합니다.
수치를 데이터 유형 숫자로 변환하는 산술 오버플로 오류.
두 데이터 유형이 모두 동일하므로 왜 이런 일이 발생하는지 이해가되지 않습니다.
이상한 것은, 그래도 이것이다 : 다음, 테스트 테이블 TestTable
을 만들 TestTable
에 병합의 대상을 변경 TargetTable
에 SELECT INTO
를 사용할 때 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;
dba.stackexchange.com에 비해 적절하다고 판단되면 –
에 문의하시기 바랍니다. 사용하시는 질문을 게시하여 도와 드리겠습니다. – Lamak
@Lamak : 코드 게시를 생각하지 않았습니다. 이것이 구체적 일 때보다는 원칙적으로 일관성이없는 것처럼 보이기 때문에 필요합니다. 그러나 나는 코드를 게시 할 것입니다. –