web-dev-qa-db-ja.com

SQL Serverプロファイラでトレースしているときに、着信するパラメータ値をプロシージャコールで記録することはできますか?

SQL Serverプロファイラー(SQL Server 2012を使用しています)を使用して、変数名のあるSQLだけでなく、パラメーター値を示す便利なトレースを生成しようとしています。ストアドプロシージャは大量のInventoryデータを調べて非常に貴重な結果を生成します。既存の動作を文書化しようとしているので、単体テストを行って正確に定義し、適切なものにリファクタリングできます。

ストアドプロシージャがカーソルを作成し、whileループを実行するループ内で、54パラメータのサブプロシージャを実行するストアドプロシージャがあります。簡略化したビューを次に示します。

CREATE PROCEDURE 
   [dbo].[OuterProcedure]       
   (  @ProductCode varchar(8),          
     -- 41 more parameters omitted
   )
AS            
  SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED   
  SET NOCOUNT ON           
 DECLARE @AboutFourHundredLocalvariables -- omit about 400 local variable declarations.
 -- OMIT ABOUT 10 temporary table declarations.
 DECLARE  aCursor CURSOR FAST_FORWARD FOR         
   SELECT [ID],bkno,  -- about 40 fields omitted.
              FROM vwVeryComplexViewThatDoesALotOfVeryBrutalJoins         
              WHERE  (about_80_boolean_expressions AND omitted_here)
        ORDER BY some,keys,like,this

OPEN aCursor          
FETCH NEXT FROM aCursor /* Get First Record */         
    INTO @ID, @about_40_fields,.... 
WHILE (@@FETCH_STATUS = 0) AND         
          ( @About80MoreBooleanExpressionsHere)  
BEGIN   /* 1 */            
     -- about 700 lines of logic, math and if-parameter-this-then-that
     -- stuff omitted
            EXEC  @ConsiderItem = 
                      InnerProcedureCallWithinLoop
                                            @from_locn,        
                        @About53PARAMSOMITTED,
                                                ...

    FETCH NEXT FROM CurInventory /* Get Next Record */       
       INTO @ID,@MoreStuff,...    
END                   
CLOSE CurInventory          
DEALLOCATE CurInventory        

InnerProcedureCallWithinLoopに渡されたすべてのパラメーター値を表示するトレースを取得するにはどうすればよいですか? 54のパラメーターがあります。 SQL内に基本的に「54行のdebug-printfs」を書き込む必要がありますか、SQLトレースを実行しているときにプロシージャコールのすべてのパラメータ値をダンプできますか?

今すぐトレースを取得すると、次の出力が得られます。

EXEC  @ConsiderItem = InnerProcedureCallWithinLoop  @from_locn,        
                        @About53ParmsOmitted

私が知りたいのは、@from_locn = 1@About53ParmsOmitted = 'hello world'などです。

これはパラメータ@from_locnの実際の値を教えてくれません。最初のパラメーターの場合は、最上位のストアドプロシージャに渡されるので、場合によっては0または1です。ただし、その内部プロシージャの43個のパラメータのうち約40個は、WHILEループ内のFETCH NEXT FROM aCursor操作からのものです。

現在のトレースでは、InnerProcedureCallWithinLoopが呼び出された回数とそれぞれにかかった時間がわかりますが、その呼び出しに対するパラメーターの値はわかりません。これらのスクリプトをトレースしながら、これらのスクリプトをトレースしながら、コード内で見つけたコーナーケースをレプリケートする「実行可能なスタンドアロンSQLスクリプト」をどうにかして取得できた場合(54のパラメーターを知っています。それら!)SQL Serverのストアドプロシージャのこの巨大なうなり声の外で、このコーナーケースを自分で呼び出すことができるSQLスクリプトを構築するためだけに入力するのに1時間かかるかもしれません。

これは、SQL式にドリルダウンして、これらの複雑なストアドプロシージャを調査できるスクリプトを作成するための取り組みの一部です。

更新 RPC「出力パラメータ」記録オプションが見つかりましたが、「RPC IN PARAM」記録オプションが見つかりませんでした。

13
Warren P

弾丸をかじって、そのようなトレースは[認識された]トレースの目的ではないため、セットアップできないことをお伝えします。私はいつもこのようにしてきました:

WHILE(@@ FETCH_STATUS = 0)および
(@ About80MoreBooleanExpressionsHere)
BEGIN/* 1 * /
-約700行のロジック、数学、if-parameter-this-then-that
-省略されたもの
INSERT InnerProcedureCallWithinLoop__TraceTable
VALUES(@from_locn、@ About53PARAMSOMITTED

EXEC @ConsiderItem =
InnerProcedureCallWithinLoop
@from_locn、
@ About53PARAMSOMITTED、
...

1つの場所からしか呼び出されないことがわかっている場合。それ以外の場合は、呼び出し元ではなく呼び出し先で行います。

ALTER PROC InnerProcedureCallWithinLoop
    @from_locn int,
    @About53PARAMSOMITTED ...
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET NOCOUNT ON;
INSERT InnerProcedureCallWithinLoop__TraceTable VALUES (@from_locn, @prm2, @prm3....
--- rest of proc

これは、トレースを使用する場合とは明らかに異なります。トレースを使用すると、開始して終了しなかった場合でもイベントをキャプチャできます(障害のあるパラメータ、トランザクションのロールバック)。それが問題である場合は、CLRまたは電子メールメソッドを調べて、キャプチャされた出力を外部化する必要があります。

8
孔夫子