C# でできる SQL Server テーブル変更監視:サンプルコード付きでわかりやすく解説

2024-07-27

C# で SQL Server テーブル変更を監視する方法

変更データ キャプチャ (CDC)

CDC は、SQL Server に組み込まれた機能で、データベース内のデータ変更を追跡する最も効率的な方法の 1 つです。 CDC を使用すると、挿入、更新、削除などの操作に関する情報を取得できます。

CDC を C# で使用するには、次の手順に従います。

  1. .NET Framework Data Provider for SQL Server NuGet パッケージをプロジェクトにインストールします。
  2. System.Data.SqlClient 名前空間を using ディレクティブに追加します。
  3. SqlConnection オブジェクトを作成し、SQL Server インスタンスに接続します。
  4. SqlCommand オブジェクトを作成し、CDC を有効にする T-SQL コマンドを実行します。
  5. SqlNotificationRequest オブジェクトを作成し、監視するテーブルと列を指定します。
  6. SqlNotificationService オブジェクトを作成し、SqlNotificationRequest オブジェクトを渡します。
  7. SqlNotificationService.Start() メソッドを呼び出して、通知の監視を開始します。
  8. SqlNotificationEventHandler делегатを作成し、データ変更イベントが発生したときに呼び出されるようにします。
  9. SqlNotificationService.Subscribe() メソッドを使用して、SqlNotificationEventHandler делеゲートを SqlNotificationService オブジェクトに登録します。

トリガー

トリガーは、データベース内のデータが変更されたときに自動的に実行されるストアド プロシージャです。 トリガーを使用して、C# アプリケーションに通知を送信したり、他のアクションを実行したりできます。

トリガーを使用して C# で SQL Server テーブル変更を監視するには、次の手順に従います。

  1. 監視するテーブルに対して INSERT、UPDATE、または DELETE トリガーを作成します。
  2. トリガー内で、C# アプリケーションに通知を送信するコードを追加します。

ポーリング

ポーリングは、一定間隔で SQL Server テーブルをクエリして、変更がないかどうかを確認する最も単純な方法です。 ポーリングは、他の方法と比較してパフォーマンスが低くなりますが、実装が最も簡単です。

  1. 監視するテーブルに対してクエリを作成します。
  2. Timer クラスを使用して、クエリを一定間隔で実行します。
  3. クエリの結果を前回のクエリ結果と比較して、変更がないかどうかを確認します。
  4. 変更がある場合は、必要な処理を実行します。

どの方法を選択するべきですか?

使用する方法は、要件によって異なります。

  • パフォーマンスが重要ではない場合 は、ポーリングを使用するのが最善の方法です。
  • 特定の操作に対してのみアクションを実行する必要がある場合 は、トリガーを使用するのが最善の方法です。
  • 変更を追跡する必要がある場合 は、CDC を使用するのが最善の方法です。



using System;
using System.Data.SqlClient;
using Microsoft.SqlServer.ChangeData.DataAccess;

namespace SqlServerCdcSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 接続文字列を指定
            string connectionString = "Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True";

            // 監視するテーブルと列を指定
            string tableName = "MyTable";
            string[] columnNames = new string[] { "Id", "Name", "Price" };

            // CDC サービスを作成
            using (var cdcService = new ChangeDataCaptureService(connectionString))
            {
                // データ変更イベントが発生したときの処理を定義
                cdcService.OnChangeEvent += OnChangeEvent;

                // CDC サービスを開始
                cdcService.Start();

                // コンソールに入力があるまで待機
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();

                // CDC サービスを停止
                cdcService.Stop();
            }
        }

        static void OnChangeEvent(object sender, ChangeDataEventArgs e)
        {
            // 変更されたデータを取得
            var changeTable = e.ChangeTable;

            // 変更された各行を処理
            foreach (DataRow row in changeTable.Rows)
            {
                // 変更の種類を取得
                ChangeType changeType = row.RowState;

                // 変更された列を取得
                var changedColumns = row.GetModifiedColumns();

                // 変更された値を取得
                foreach (DataColumn column in changedColumns)
                {
                    object newValue = row[column];

                    // 変更内容をコンソールに出力
                    Console.WriteLine($"Table: {tableName}, ChangeType: {changeType}, Column: {column.ColumnName}, NewValue: {newValue}");
                }
            }
        }
    }
}
using System;
using System.Data.SqlClient;

namespace SqlServerTriggerSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 接続文字列を指定
            string connectionString = "Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True";

            // トリガーを作成
            string triggerSql = @"
CREATE TRIGGER MyTrigger ON MyTable
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
    -- C# アプリケーションに通知を送信
    -- 例: 電子メールを送信
    -- ...
END
";

            // トリガーを作成する
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                using (var command = new SqlCommand(triggerSql, connection))
                {
                    command.ExecuteNonQuery();
                }
            }

            // コンソールに入力があるまで待機
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}
using System;
using System.Data.SqlClient;

namespace SqlServerPollingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 接続文字列を指定
            string connectionString = "Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True";

            // 監視するテーブルと列を指定
            string tableName = "MyTable";
            string[] columnNames = new string[] { "Id", "Name", "Price" };

            // 前回のクエリ結果を格納する変数
            DataRow previousRow = null;

            // ポーリング間隔を指定 (ミリ秒)
            int pollingInterval = 10000;

            while (true)
            {
                // クエリを実行
                using (var connection = new SqlConnection(connectionString))
                {
                    connection.Open();

                    using (var command = new SqlCommand($"SELECT {string.Join(",", columnNames)} FROM {tableName}", connection))
                    {
                        var reader = command.ExecuteReader();

                        if (reader.Read())
                        {
                            // 現在のクエリ結果を取得
                            DataRow currentRow = reader[0];

                            // 前回のクエリ結果と比較
                            if (previousRow != null)
                            {
                                // 変更がある場合は処理を実行
                                foreach (DataColumn column in columnNames)
                                {



  • カスタム ソリューション

  • ログの監視

  • サードパーティ製のツール

  • 高いセキュリティが必要な場合 は、ログの監視を使用するのが最善の方法です。
  • 複雑な監視シナリオが必要な場合 は、サードパーティ製のツールを使用するか、カスタム ソリューションを開発するのが最善の方法です。
  • シンプルな監視ソリューションが必要な場合 は、変更データ キャプチャ (CDC) を使用するのが最善の方法です。

c# sql-server monitoring



INSERT INTOステートメントのIGNOREオプションでMySQL REPLACE INTOを代替

MySQLのREPLACE INTOコマンドは、SQL Server 2005では完全に同じように実装されていません。しかし、いくつかの代替方法を用いることで、同様の動作を実現することができます。REPLACE INTO とはREPLACE INTOは、INSERT INTOと似ていますが、以下の点が異なります。...


SQL Serverで複数のユーザーがデータベースレコードを編集する方法

最も基本的な方法は、レコードを編集する前にロックすることです。これにより、他のユーザーがレコードを編集するのを防ぐことができます。ロックの種類排他ロック: 他のユーザーがレコードを読み取ることも、編集することもできません。ロックの取得方法LINQ to SQL: DataLoadOptions クラスの LockMode プロパティを使用します。...


C#データベース接続とレコードセットループ処理:パフォーマンスチューニング

データベースへの接続まず、使用するデータベースの種類に合った接続文字列を作成する必要があります。以下は、SQL Serverデータベースへの接続文字列の例です。接続文字列を作成したら、SqlConnectionクラスを使用してデータベースへの接続を開きます。...


ORDER BY句、WITH構文、PIVOT関数:SQL Serverで列を論理的に並べ替える3つのアプローチ

列の論理的な並べ替えを実現する方法はいくつかあります。ORDER BY句を使用する: これは、SELECTクエリで最も一般的な方法です。ORDER BY句を使用すると、結果セットを1つ以上の列に基づいて並べ替えることができます。各列には、昇順 (ASC) または降順 (DESC) のどちらかのソート方向を指定できます。...


サンプルコード: SQL Serverの永続性をxUnit.netでテストする

単体テストは、ソフトウェア開発において重要な役割を果たします。コードの各部分が独立して動作することを確認することで、コードの品質と信頼性を向上させることができます。TDDと永続性TDD(テスト駆動開発)は、単体テストを開発プロセスの中心に据えた開発手法です。TDDでは、コードを書く前にまずテストケースを作成します。テストケースが成功するまでコードを書き換え、最終的にすべてのテストケースが成功することを確認します。...



SQL SQL SQL Amazon で見る



SQL Server Profilerを使ってSQL Serverテーブルの変更をチェックする

Change Trackingは、テーブルレベルで変更されたデータを追跡する機能です。有効にすると、どの行が挿入、更新、削除されたかを追跡できます。メリットクエリで変更内容を取得できる設定が簡単比較的軽量な機能古い情報は自動的に削除される変更されたデータの内容は追跡できない


C#/VB.NET プログラマー必見!T-SQL CAST デコードのすべて

T-SQL CAST は、データを異なるデータ型に変換する関数です。C#/VB. NET で T-SQL CAST を使用する場合、デコードが必要になることがあります。この解説では、T-SQL CAST のデコード方法について、C#/VB


データ移行ツール、クラウドサービス、オープンソースツールを使って SQL Server 2005 から MySQL へデータを移行する

このチュートリアルでは、SQL Server 2005 から MySQL へデータを移行する方法について 3 つの方法を説明します。方法 1: SQL Server Management Studio を使用方法 2: bcp コマンドを使用


SQL Serverデータベースのバージョン管理:Subversionとの連携方法

この解説では、Subversion(SVN)と呼ばれるバージョン管理システムを用いて、SQL Serverデータベースのバージョン管理を行う方法について説明します。SVNは、ファイルやディレクトリのバージョン管理に広く用いられるオープンソースツールであり、データベースのバージョン管理にも活用できます。


SQL Server 6.5 からのアップグレードに関する専門家のサポート

SQL Server 6.5 は 2000 年にリリースされた古いバージョンであり、現在ではサポートされていません。最新の機能やセキュリティパッチを利用するためには、新しいバージョンへのアップグレードが必要です。アップグレード方法アップグレード方法はいくつかありますが、一般的には以下の 2 つの方法が選択されます。