É possível registrar valores de parâmetros de entrada em uma chamada de procedimento durante o rastreamento no SQL Server Profiler?

13

Usando o SQL Server Profiler (estou no SQL Server 2012), estou tentando gerar um rastreamento útil que mostra os valores dos parâmetros, não apenas o SQL com nomes de variáveis. O procedimento armazenado percorre uma quantidade bruta de dados do Inventory para gerar resultados extremamente valiosos, e estou tentando documentar o comportamento existente, para que eu possa testá-lo por unidade, defini-lo exatamente e depois refatorá-lo para algo sensato.

Eu tenho um procedimento armazenado que executa um sub-procedimento de 54 parâmetros, dentro de um loop em que o procedimento armazenado cria um cursor e, em seguida, executa um loop while. Aqui está uma visão simplificada:

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        

Como obter um rastreamento para me mostrar todos os valores de parâmetros passados InnerProcedureCallWithinLoop? Existem 54 parâmetros. Preciso escrever essencialmente "54 linhas de debug-printfs" dentro do meu SQL ou posso despejar todos os valores de parâmetros de uma chamada de procedimento enquanto faço um rastreio de SQL de alguma maneira?

Quando recebo um rastreio agora, recebo esta saída:

EXEC  @ConsiderItem = InnerProcedureCallWithinLoop  @from_locn,        
                        @About53ParmsOmitted

O que eu gostaria de saber é que @from_locn = 1e @About53ParmsOmitted = 'hello world'e assim por diante.

Isso não me diz o valor real do parâmetro @from_locn. No caso desse primeiro parâmetro, ele é passado para o meu procedimento armazenado de nível superior, então eu sei que é 0 ou 1, conforme o caso. No entanto, cerca de 40 dos 43 parâmetros desse procedimento interno vêm da FETCH NEXT FROM aCursoroperação dentro de um WHILEloop.

No momento, o rastreamento me diz quantas vezes InnerProcedureCallWithinLoopé chamado e quanto tempo cada um levou, mas não quais foram os valores dos parâmetros para essa chamada. Se eu pudesse, de alguma maneira, obter "scripts SQL autônomos executáveis" que replicam algumas letras maiúsculas encontradas no meu código, enquanto rastreio esses scripts, configurando essas funções brutas (eu sei, 54 parâmetros, isso é realmente bruto, mas não escrevi) eles!) podem levar uma hora para digitar apenas para criar um script SQL que me permita invocar essa caixa de canto, fora desse grande e enorme emaranhado de procedimentos armazenados do SQL Server.

Isso tudo faz parte de um esforço para detalhar uma expressão SQL e criar scripts que possam analisar esses procedimentos armazenados complexos.

Atualização Encontrei uma opção de gravação RPC "Output Param", mas não uma opção de gravação "RPC IN PARAM".

Warren P
fonte
Não são apenas os 54 parâmetros que são brutos :-) Todo esse loop para chamar um cursor. Isso é nojento :-) Você já brincou com o Plan Explorer do SQL Sentry? Você pode usar a versão gratuita ou uma avaliação da versão completa e isso pode ajudá-lo se você tiver uma chamada com todos os parâmetros - sqlsentry.net/plan-explorer/sql-server-query-view.asp
Mike Walsh
Você pode nos dizer quais eventos você está capturando?
Mike Walsh
2
A única vez que o criador de perfis captura esses dados (eu acho) é quando você os chama? Tente configurar uma tabela de auditoria com todos esses parâmetros e faça uma inserção antes de fazer um loop no cursor?
jcolebrand
RPC: Concluído mostra os valores dos parâmetros, mas no nível externo.
Mike Walsh
3
+1 na pergunta, como recompensa pela sua dor. Se pudesse, marcaria novamente com +1 por postar a pergunta sem palavrões.
Mark Storey-Smith

Respostas:

8

Vou morder a bala e dizer que esse rastreamento não pode ser configurado, porque não é o objetivo [percebido] dos rastreamentos. Eu sempre fiz assim:

ENQUANTO (@@ FETCH_STATUS = 0) AND
            (@ About80MoreBooleanExpressionsHere)
BEGIN / * 1 * /
    - cerca de 700 linhas de lógica, matemática e se o parâmetro é isso então o que é
    omitido
      INSERT InnerProcedureCallWithinLoop__TraceTable
              VALUES (@from_locn, @ Sobre53PARAMSOMITTED

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

Se eu sei que só é chamado de um local. Caso contrário, eu faço isso no chamado em vez do chamador.

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

Obviamente, isso é diferente de usar um rastreamento, capaz de capturar eventos, mesmo que tenham iniciado e nunca terminado (parâmetros defeituosos, transações recuperadas). Se esse for o seu problema, é necessário examinar os métodos CLR ou email para externalizar a saída capturada.

孔夫子
fonte
Isso foi o que eu pensei.
Warren P.