Architect's Log

I'm a Cloud Architect. I'm highly motivated to reduce toils with driving DevOps.

SQLのMergeの代わりにDataTableのMergeを使用する

新しいレコードとキーの一致するレコードが、現在のデータに存在する場合はUPDATE、存在しない場合はINSERTしたいケースでは、SQLのMergeが使用できます。しかし、SQL Server 2005以前のバージョンではMergeが実装されていません。
このエントリーでは、SQLのMergeの代わりにDataTableのMergeを使用して、新しいデータをUPDATE/INSERTする方法を紹介します。

ソースコード

using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication {
    class Program {
        static void Main(string[] args) {
            DataTable newData = new DataTable();
            
            // newDataに新しいデータをセットしておく。

            DataTable currentData = new DataTable();

            // currentDataに現在のデータのSELECT結果をセットしておく。 

            /*
             * currentDataをnewDataとマージする。これによってnewDataのRowStateを設定する。
             * currentDataに存在したDataRowはModified、存在しなかったDataRowはAddedに設定される。
             */
            newData.Merge(currentData, true);

            // マージ前のnewDataを取得し直す。
            //(マージ前にnewDataになかったDataRowは、RowStateがUnchangedなのでGetChangesの戻り値には含まれない)
            DataTable changedData = newData.GetChanges();
            if(changedData != null) {
                using(SqlConnection connection = new SqlConnection([connetionString]))
                using(SqlDataAdapter adapter = new SqlDataAdapter()) {
                    connection.Open();

                    // adapter.InsertCommandをセットアップ
                    
                    // adapter.UpdateCommandをセットアップ

                    // RowStateがModifiedのDataRowはUPDATE、AddedのDataRowはINSERTされる。
                    adapter.Update(changedData);
                }
            }
        }
    }
}