sql >> データベース >  >> RDS >> Sqlserver

データを更新する SQL MERGE ステートメント

    実際の SQL Server MERGE が必要だと仮定します ステートメント:

    MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
    USING dbo.temp_energydata AS source
        ON target.webmeterID = source.webmeterID
        AND target.DateTime = source.DateTime
    WHEN MATCHED THEN 
        UPDATE SET target.kWh = source.kWh
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (webmeterID, DateTime, kWh)
        VALUES (source.webmeterID, source.DateTime, source.kWh);
      

    ソースにないターゲットのレコードも削除する場合:

    MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
    USING dbo.temp_energydata AS source
        ON target.webmeterID = source.webmeterID
        AND target.DateTime = source.DateTime
    WHEN MATCHED THEN 
        UPDATE SET target.kWh = source.kWh
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (webmeterID, DateTime, kWh)
        VALUES (source.webmeterID, source.DateTime, source.kWh)
    WHEN NOT MATCHED BY SOURCE THEN
        DELETE;
      

    これは少し一般的になっているため、注意すべきいくつかの注意点を付けて、この回答を少し拡張する必要があると思います.

    まず、MERGE の同時実行の問題 声明 古いバージョンの SQL Server では。この問題が後の版で対処されたかどうかはわかりません。いずれにせよ、これは HOLDLOCK を指定することで大部分回避できます。 または SERIALIZABLE ロックのヒント:

    MERGE INTO dbo.energydata WITH (HOLDLOCK) AS target
    [...]
      

    より制限的なトランザクション分離レベルを使用して、同じことを達成することもできます。

    その他の既知の問題がいくつかあります MERGE で . (Microsoft は Connect を無効にし、古いシステムの問題を新しいシステムの問題にリンクしなかったため、これらの古い問題を追跡するのは難しいことに注意してください。Microsoft に感謝します!) 私が知る限り、それらのほとんどは一般的ではありません。問題を解決するか、上記と同じロックヒントで回避できますが、テストしていません.

    MERGE で問題が発生したことはありませんが、そのままです。 私自身、私は常に WITH (HOLDLOCK) を使用しています 私は、最も単純なケースでのみステートメントを使用することを好みます.



    1. 左最新のレコードに参加

    2. エラーが発生したときにPostgresスクリプトを停止するにはどうすればよいですか?

    3. 投稿データ変数が多すぎますか?

    4. MySQLで過去12か月のデータを取得する方法