3

列を持つターゲットテーブルTargetTableがありDECIMAL(20, 7)ます。列のあるソーステーブルもありSourceTableますDECIMAL(20, 7)が、このテーブルの値はすべて整数です。

ステートメントを介してデータをTargetTablefromにアップサートしようとすると、標準エラーが発生します。SourceTableMERGE

数値をデータ型数値に変換する際の算術オーバーフローエラー。

両方のデータ型が同一であるため、なぜこれが発生するのかよくわかりません。

ただし、奇妙なことに、SELECT INTOonを使用TargetTableしてテストテーブルを作成しTestTable、マージのターゲットをに変更するとTestTable、アップサートが完了します。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;
4

2 に答える 2

9

コードにエラーはまったくないようです。さらに、元のテーブルと同じ構造とデータを使用して、ターゲットとして別のテーブルを作成すると正常に機能するという事実は、エラーが存在しないことを示しています。最も可能性の高い理由は、失敗したクエリを実行している元のテーブルにトリガーがあり、それが表示されているエラーであるということです。

于 2012-06-07T15:16:52.063 に答える
0

このタイプのエラーは、その特定のテーブルでトリガーを使用できるために発生しますが、そのテーブルコンテキストまたは一部の変更はデータベースで実行されるため、このタイプのエラーはエラーとして表示されるため、plzzはトリガーを無効にしてタスクを実行します

于 2020-03-03T19:17:17.813 に答える