Czy można rejestrować przychodzące wartości parametrów w wywołaniu procedury podczas śledzenia w programie SQL Server Profiler?

13

Korzystając z SQL Server Profiler (korzystam z SQL Server 2012), próbuję wygenerować użyteczny ślad, który pokazuje wartości parametrów, a nie tylko SQL z nazwami zmiennych. Procedura przechowywana przechodzi przez ogromną ilość danych Inwentaryzacyjnych, aby wygenerować bardzo cenne wyniki, i próbuję udokumentować istniejące zachowanie, więc mogę je przetestować, dokładnie zdefiniować, a następnie przekształcić w coś rozsądnego.

Mam procedurę składowaną, która wykonuje 54-parametrową podprocedurę, wewnątrz pętli, w której procedura składowana tworzy kursor, a następnie wykonuje pętlę while. Oto uproszczony widok:

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        

Jak uzyskać ślad, aby pokazać mi wszystkie przekazane wartości parametrów InnerProcedureCallWithinLoop? Jest 54 parametrów. Czy muszę napisać zasadniczo „54 wiersze debugowania-printfs” w moim SQL, czy mogę zrzucić wszystkie wartości parametrów wywołania procedury podczas wykonywania śledzenia SQL, jak to zrobić?

Gdy otrzymuję teraz ślad, otrzymuję ten wynik:

EXEC  @ConsiderItem = InnerProcedureCallWithinLoop  @from_locn,        
                        @About53ParmsOmitted

Co chciałbym wiedzieć, jest to, że @from_locn = 1a @About53ParmsOmitted = 'hello world'i tak dalej.

To nie mówi mi rzeczywistej wartości parametru @from_locn. W przypadku tego pierwszego parametru jest on przekazywany do mojej procedury składowanej najwyższego poziomu, więc wiem, że jest to 0 lub 1, zależnie od przypadku. Jednak około 40 z 43 parametrów tej wewnętrznej procedury pochodzi z FETCH NEXT FROM aCursoroperacji wewnątrz WHILEpętli.

W tej chwili śledzenie mówi mi, ile razy InnerProcedureCallWithinLoopwywoływano i jak długo trwało każde, ale nie jakie były wartości parametrów tego wywołania. Gdybym mógł jakoś uzyskać „działające samodzielne skrypty SQL”, które replikują niektóre przypadki narożne, które znajduję w moim kodzie, śledząc te skrypty, konfigurując te funkcje brutto (wiem, 54 parametry, to naprawdę obrzydliwe, ale nie napisałem im!) może zająć mi godzinę pisania tylko po to, aby zbudować skrypt SQL, który pozwala mi samodzielnie wywoływać ten przypadek, poza tym ogromnym warknięciem procedur przechowywanych SQL Server.

To wszystko jest częścią starań, aby przejść do wyrażenia SQL i zbudować skrypty, które mogą sondować te złożone procedury składowane.

Aktualizacja Znalazłem opcję nagrywania RPC „Output Param”, ale nie opcję nagrywania „RPC IN PARAM”.

Warren P.
źródło
Nie tylko 54 parametry są obrzydliwe :-) Cała ta pętla do wywołania kursora. To obrzydliwe :-) Czy grałeś w Eksploratorze planów SQL Sentry? Możesz użyć darmowej wersji lub skorzystać z wersji próbnej pełnej wersji, co może ci pomóc, jeśli masz połączenie ze wszystkimi parametrami - sqlsentry.net/plan-explorer/sql-server-query-view.asp
Mike Walsh
Czy możesz nam powiedzieć, które wydarzenia przechwytujesz?
Mike Walsh
2
Jedyny raz, kiedy profilujący przechwytuje te dane (tak myślę), kiedy je wywołujesz? Spróbuj skonfigurować tabelę audytu z tymi wszystkimi parametrami i po prostu wstaw wstawkę przed zapętleniem kursora?
jcolebrand
RPC: Zakończone pokazuje wartości parametrów, ale na poziomie zewnętrznym.
Mike Walsh
3
+1 za pytanie, jako rekompensatę za twój ból. Gdybym mógł, dałbym +1 za opublikowanie pytania bez przekleństw.
Mark Storey-Smith

Odpowiedzi:

8

Ugryzę pocisk i powiem, że takiego śladu nie można ustawić, ponieważ nie jest to [postrzegany] cel śladów. Zawsze robiłem to w ten sposób:

PODCZAS (@@ FETCH_STATUS = 0) ORAZ
            (@ About80MoreBooleanExpressionsHere)
POCZĄTEK / * 1 * /
    - około 700 wierszy logiki, matematyki i if       -parametr -to-to-tamto
    - pominięto
INSERT InnerProcedureCallWithinLoop__TraceTable
              VALUES (@from_locn) About53PARAMSOMITTED

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

Jeśli wiem, że jest wywoływany tylko z jednego miejsca. W przeciwnym razie robię to w odbiorcy zamiast dzwoniącego.

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

To oczywiście różni się od korzystania ze śledzenia, które jest w stanie przechwytywać zdarzenia, nawet jeśli się rozpoczęły i nigdy nie zakończyły (błędne parametry, wycofane transakcje). Jeśli to jest twój problem, musisz przyjrzeć się CLR lub metodom e-mail w celu eksternalizacji przechwyconych danych wyjściowych.

孔夫子
źródło
Tak myślałem.
Warren P