Utilisation du profileur SQL Server (je suis sur SQL Server 2012), j'essaie de générer une trace utile indiquant les valeurs de paramètre, pas seulement le SQL avec des noms de variables. La procédure stockée traverse une quantité brute de données d'inventaire pour générer des résultats extrêmement précieux, et j'essaie de documenter le comportement existant afin que je puisse le tester, le définir exactement, puis le refactuer dans quelque chose d'esprit.
J'ai une procédure stockée qui effectue une sous-procédure de 54 paramètres exécutée, à l'intérieur d'une boucle où la procédure stockée crée un curseur puis une boucle de temps. Voici une vue simplifiée:
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
Comment obtiendrais-je une trace pour me montrer toutes les valeurs de paramètre transmises à InnerProcedureCallWithinLoop
? Il y a 54 paramètres. Dois-je écrire essentiellement "54 lignes de débogoufs" à l'intérieur de ma SQL ou puis-je jeter toutes les valeurs de paramètre d'un appel de procédure tout en faisant une trace SQL Quel que soit?
Quand je reçois une trace en ce moment, je reçois cette sortie:
EXEC @ConsiderItem = InnerProcedureCallWithinLoop @from_locn,
@About53ParmsOmitted
Ce que j'aimerais savoir, c'est que @from_locn = 1
et @About53ParmsOmitted = 'hello world'
etc.
Cela ne me dis pas la valeur réelle du paramètre @from_locn
. Dans le cas de ce premier paramètre, il est transmis à ma procédure stockée au niveau supérieur, donc je sais que c'est 0 ou 1, selon le cas. Cependant, environ 40 des 43 paramètres de la procédure interne proviennent du FETCH NEXT FROM aCursor
Opération à l'intérieur d'une boucle WHILE
.
À l'heure actuelle, le traçage me dit combien de fois InnerProcedureCallWithinLoop
est invoqué et combien de temps a pris chaque que chacun a pris, mais pas quelles étaient les valeurs des paramètres à cet appel. Si je pouvais en quelque sorte obtenir des "scripts standalones annoncables" qui reproduisent du boîtier de coin, je trouve dans mon code, tout en suivant ces scripts, configurez ces fonctions brutes (je sais, 54 paramètres, c'est vraiment brut, mais je n'ai pas écrit Les!) Pourriez-vous me faire une heure de taper juste pour construire un script SQL qui me permet d'invoquer ce coin-caisse moi-même, en dehors de ce grand ruisseau Gargantuan Snarl des procédures stockées SQL Server.
Tout cela fait partie de l'effort de forcer à une expression SQL et de créer des scripts pouvant sonder ces procédures stockées complexes.
Mise à jour J'ai trouvé une option d'enregistrement RPC "Sortie param", mais pas une option d'enregistrement "RPC in param".
Je vais mordre la balle et vous dire qu'une telle trace ne peut pas être configurée, car ce n'est pas le but [perçu] des traces. Je l'ai toujours fait de cette façon:
Tandis que (@@ fetch_status = 0) et
[.____] (@ environ80moreboolantanexpressionsHere)
[.____] commence/* 1 * /
[.____] - environ 700 lignes de logique, mathématiques et si-paramètres-this-this-que
[.____] - Des trucs omis
[.____] insérer innerprocédeurecallwithInloop__Trable
Valeurs (@from_locn, @ environ53paramsomite
[.____] EXEC @CONSIDERITEM =
InnerprocédeurecallwithInloop
[.____] @from_locn,
[.____] @ environ53Paramsomited,
...
Si je sais que ce n'est jamais appelé d'un endroit. Sinon, je le fais dans la callee au lieu de l'appelant.
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
Ceci est évidemment différent de l'utilisation d'une trace, capable de capturer des événements même s'ils ont commencé et n'ont jamais fini (paramètres défectueux, transactions roulées). Si tel est votre problème, vous devez examiner les méthodes CLR ou Email pour externaliser la sortie capturée.