読者です 読者をやめる 読者になる 読者になる

PRINT・RAISERRORとSqlConnection.InfoMessageイベント

T-SQLのPRINTを使うとクライアントにメッセージを通知できます。そのメッセージはSqlConnection.InfoMessageイベントで取得できます。 また、RAISERRORでも重大度(severity)が10以下の場合は、同様にSqlConnection.InfoMessageイベントでメッセージを取得できます。

ということを知ったので、このあたりについてをサンプルコードを残しておきます。(PRINTはSSMSでメッセージを表示するだけの機能だと思ってました・・・。)

また、RAISERRORに似た機能で、SQL Server 2012から利用できるTHROWについても確認してみました。

サンプルコード

例のごとくDapperを使っています。

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;

namespace ConsoleApp {
    class Program {
        static readonly string _connectionString
            = new SqlConnectionStringBuilder {
                DataSource = ".",
                InitialCatalog = "Test",
                IntegratedSecurity = true,
            }.ToString();

        static void Main(string[] args) {
            using (var connectoin = new SqlConnection(_connectionString)) {
                // InfoMessageイベントでメッセージをコンソール出力
                connectoin.InfoMessage += (sender, eventArgs) =>
                    Console.WriteLine("InfoMessage: " + eventArgs.Message);

                // print
                // InfoMessageイベントが発生する
                connectoin.Execute("print N'printのテスト';");

                // raiserror
                // severityが10以下のメッセージはInfoMessageイベントが発生する
                connectoin.Execute("raiserror(N'raiserrorのテスト', 10, 0);");

                // raiserror
                // severityが11以上のメッセージはSqlExceptionが発生する
                try {
                    connectoin.Execute("raiserror(N'raiserrorのテスト2', 11, 0);");
                } catch (SqlException exception) {
                    Console.WriteLine("SqlException: " + exception.Message);
                }

                // throw
                // severityは常に16ということで、SqlExceptionが発生する
                try {
                    connectoin.Execute("throw 50000, N'throwのテスト', 0;");
                } catch (SqlException exception) {
                    Console.WriteLine("SqlException: " + exception.Message);
                }
            }
        }
    }
}

実行結果

InfoMessage: printのテスト
InfoMessage: raiserrorのテスト
SqlException: raiserrorのテスト2
SqlException: throwのテスト

PRINTとRAISERROR(severityが10以下)は、InfoMessageイベントでメッセージを取得でき、RAISERROR(severityが11以上)とTHROWは、SqlExceptionが発生することが確認できました。TRHOWはseverityが常に16とのことで、常に例外が発生します。

参考