web-dev-qa-db-ja.com

印刷ステートメントを使用してストアドプロシージャをデバッグする方法

SQL Server Management Studio 2008でストアドプロシージャをデバッグしようとしています。印刷ステートメントを挿入して、間違っているとわかっているIFステートメントをテストしたいと思います。

デバッグを行うために、_PRINT '5'_コマンドを使用してみました。

'RAISERROR (N'Start',10,1) WITH NOWAIT'のようなRAISERRORを使用してみました。

ただし、これらには印刷結果は表示されず、結果セットのみが表示されました。メッセージには_1 row affected_とだけ書かれています。

私はそのようにコードを書き込もうとしました(おそらくこれは間違ったアプローチです):

_SET NOCOUNT ON         
RAISERROR (N'Start',10,1) WITH NOWAIT    
DECLARE @DocHandle INT        
DECLARE @PageSize INT, @PageIndex INT, @TOTL_CONT NUMERIC(5,0), @Paging BIT        
DECLARE @Type INT, @Search varchar(20) , @ORDE nVARCHAR(50), @SORT_ID nVARCHAR(50) 
DECLARE @CreatedOn varchar(25), @SystemGenerate bit   
_

印刷ステートメントを使用してストアドプロシージャをデバッグする最良の方法は何ですか?

33
Art F

MSSQL Server Management Studioを使用している場合、印刷ステートメントは[結果]タブではなく、[メッセージ]タブの下に印刷されます。

enter image description here

そこに印刷ステートメントが表示されます。

26
Kevin Kunderman

繰り返し答えを得る前に。私がここで受け入れる唯一の答えは、上記の one によって KM。 であることを認めています。他の回答については、彼らが実際に質問に答えなかったか、十分ではなかったため、私は反対票を投じました。 PRINT出力は確かにメッセージウィンドウに表示されますが、それはまったく尋ねられたものではありません。

ストアドプロシージャの実行中にPRINTステートメントの出力が表示されないのはなぜですか?
この回答の短縮版は、sprocの実行をSQL​​サーバーに送信し、トランザクション全体が完了するまで応答しないということです。これにあるより良い答えは 外部リンク です。

  • さらに多くの意見/観察については、このSO post here に注目してください。
  • Phil-factorによる同じ投稿の answer を具体的に見てください(Ha ha!Love the SQLユーモア)
  • RAISERROR WITH NOWAITの使用に関する提案については、この answer による同じ投稿の JimCarden をご覧ください。

これらのことをしないでください

  1. 一部の人々は、PRINTステートメントの後にGOステートメントを使用できるという印象を受けていますが、sprocの内部でGOステートメントを使用することはできません。その解決策は出ています。
  2. 結果セットをナンセンスで汚すだけなので、printステートメントをSELECTすることはお勧めしません。あなたのsprocが後でプログラムによって消費されることになっている場合、ループするときにスキップする結果セットを知る必要がありますデータリーダーからの結果を通じて。これは単なる悪い考えなので、やらないでください。
  3. 印刷ステートメントのSELECT-INGに関する別の問題は、それらが常にすぐに表示されないことです。私はさまざまな実行に対してこれについてさまざまな経験をしてきたので、この方法論との一貫性を期待しないでください。

ストアドプロシージャ内のPRINTの代替
実際、これは構文が使用されているコンテキストで混乱しているため、私の意見では厄介な回避策の一種です。デバッグ情報を出力することだけを目的としてエラーを発生させるという考えが好きではありません...

既にRAISERROR WITH NOWAITで何度も説明されているように、この問題を回避する唯一の方法のようです。私は例を提供し、このアプローチの小さな問題を指摘しています:

ALTER
--CREATE 
    PROCEDURE [dbo].[PrintVsRaiseErrorSprocExample]
AS
BEGIN
    SET NOCOUNT ON;

    -- This will print immediately
    RAISERROR ('RE Start', 0, 1) WITH NOWAIT
    SELECT 1;

    -- Five second delay to simulate lengthy execution
    WAITFOR DELAY '00:00:05'

    -- This will print after the five second delay
    RAISERROR ('RE End', 0, 1) WITH NOWAIT
    SELECT 2;
END

GO

EXEC [dbo].[PrintVsRaiseErrorSprocExample]

両方のSELECTステートメントの結果は、実行が終了した後にのみ表示され、printステートメントは上記の順序で表示されます。

このアプローチの潜在的な問題
PRINTステートメントとRAISERRORステートメントの両方が次々にあり、両方が印刷されるとしましょう。これはバッファリングと関係があると確信していますが、これが起こる可能性があることに注意してください。

ALTER
--CREATE 
    PROCEDURE [dbo].[PrintVsRaiseErrorSprocExample2]
AS
BEGIN
    SET NOCOUNT ON;

    -- Both the PRINT and RAISERROR statements will show
    PRINT 'P Start';
    RAISERROR ('RE Start', 0, 1) WITH NOWAIT
    SELECT 1;

    WAITFOR DELAY '00:00:05'

    -- Both the PRINT and RAISERROR statements will show
    PRINT 'P End'
    RAISERROR ('RE End', 0, 1) WITH NOWAIT
    SELECT 2;
END

GO

EXEC [dbo].[PrintVsRaiseErrorSprocExample2]

したがって、ここでの回避策は、PRINTとRAISERRORの両方を使用せず、どちらかを選択するだけです。 sprocの実行中に出力を表示するには、RAISERROR WITH NOWAITを使用します。

13
dyslexicanaboko

次に、printステートメントの使用例を示します。前の人が示したように、メッセージタブの下に表示されます。

    Declare @TestVar int = 5;

    print 'this is a test message';
    print @TestVar;
    print 'test-' + Convert(varchar(50), @TestVar);

Print Messages

13
cmartin

使用してみてください:

RAISERROR('your message here!!!',0,1) WITH NOWAIT

また、デフォルトのツールバーの「実行」の右側にあるアイコンの「テキストへの結果」に切り替えることもできます。

上記の両方を設定しても、まだメッセージが表示されない場合は、編集しているプロシージャの同じサーバー/データベース/所有者バージョンを実行していることを確認してください。 RAISERRORコマンドをヒットしていることを確認し、プロシージャ内の最初のコマンドにします。

他のすべてが失敗した場合、テーブルを作成できます。

create table temp_log (RowID int identity(1,1) primary key not null
                      , MessageValue varchar(255))

その後:

INSERT INTO temp_log VALUES ('Your message here')

次に、プロシージャを実行した後(ロールバックなし)、テーブルをselectします。

11
KM.