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」記録オプションが見つかりませんでした。
弾丸をかじって、そのようなトレースは[認識された]トレースの目的ではないため、セットアップできないことをお伝えします。私はいつもこのようにしてきました:
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または電子メールメソッドを調べて、キャプチャされた出力を外部化する必要があります。