SQL Server で PRINT を使うと、メッセージがすぐにクライアント(SSMS など)に表示されず、サーバー側で一旦バッファに貯められて、処理がまとまった単位で送られることがあります。
これを「バッファされがち」と言います。
例
PRINT '処理開始';
WAITFOR DELAY '00:00:05';
PRINT '処理中…';
WAITFOR DELAY '00:00:05';
PRINT '処理終了';
上を実行しても、5秒ごとに順番に表示されるわけではなく、
最後にまとめて一気に出力されることが多いです。
対策
-
RAISERRORをWITH NOWAIT付きで使うと、
バッファを通さず即座にメッセージがクライアントに送られます。
RAISERROR(N'処理開始', 0, 1) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
RAISERROR(N'処理中…', 0, 1) WITH NOWAIT;
WAITFOR DELAY '00:00:05';
RAISERROR(N'処理終了', 0, 1) WITH NOWAIT;
こうすると、本当にリアルタイムで表示されるようになります。
👉 つまり「バッファされがち」というのは、PRINT の出力が「リアルタイムに見えにくい」挙動のことを指していて、
WITH NOWAIT 付き RAISERROR を使えば回避できます。
SQL Server では PRINT と RAISERROR はどちらもメッセージを出すために使えますが、用途や性質が大きく違います。整理します。
🔹 PRINT
-
用途
単純にメッセージを出力する。 -
表示先
SSMS(SQL Server Management Studio)の「メッセージ」タブに表示される。 -
特徴
- 処理の進行状況やデバッグ用の簡単なログ出力に使う。
- メッセージは即時に出ないことが多い(SQL Server のバッファに溜め込まれて遅れて表示される)。
- 重要な制御フローには使えない。
PRINT '処理開始';
-- 何らかの処理
PRINT '処理完了';
🔹 RAISERROR
-
用途
エラーや警告としてメッセージを出す。 -
表示先
同じく「メッセージ」タブだが、エラーとして扱われる。 -
特徴
- エラー番号や深刻度(severity)を設定できる。
- severity によっては処理を中断させられる。
- severity 10 以下なら「情報メッセージ」として使えるので、
PRINTの代わりにリアルタイムにメッセージを出す用途でよく使う。 -
WITH NOWAITを付けると、バッファされずに即時出力される。
RAISERROR ('処理を開始します', 10, 1) WITH NOWAIT;
-- 何らかの処理
RAISERROR ('処理完了しました', 10, 1) WITH NOWAIT;
🔹 使い分け
-
デバッグや軽いログ →
PRINT(ただし遅延するので注意) -
即時表示したいログや進行状況表示 →
RAISERROR(severity 10 以下) -
エラーとして処理を中断させたい →
RAISERROR(severity 11 以上) -
SQL Server 2012 以降では
THROWも追加され、エラーをシンプルに投げられる(ただし情報メッセージ用途には不向き)。
✅ 結論:
-
ログ用途 →
PRINT(手軽) orRAISERRORwith severity 10 +NOWAIT(リアルタイム) -
例外処理 →
RAISERROR(severity 11 以上)またはTHROW
もしユーザーさんの利用シーンが「バッチ処理の進捗ログ」なのか「エラー制御」なのかによって選択が変わります。