Ist es möglich, eingehende Parameterwerte in einem Prozeduraufruf während der Ablaufverfolgung in SQL Server Profiler aufzuzeichnen?


13

Mit dem SQL Server Profiler (ich arbeite mit SQL Server 2012) versuche ich, eine nützliche Ablaufverfolgung zu generieren, die die Parameterwerte und nicht nur SQL mit Variablennamen anzeigt. Die gespeicherte Prozedur durchläuft eine große Menge von Inventardaten, um äußerst wertvolle Ergebnisse zu erzielen. Ich versuche, das vorhandene Verhalten zu dokumentieren, damit ich es nach einem Komponententest definieren, genau definieren und dann in etwas Vernünftiges umgestalten kann.

Ich habe eine gespeicherte Prozedur, die eine 54-Parameter-Unterprozedur ausführt, in einer Schleife, in der die gespeicherte Prozedur einen Cursor erstellt und dann eine while-Schleife ausführt. Hier ist eine vereinfachte Ansicht:

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        

Wie erhalte ich eine Ablaufverfolgung, in der alle Parameterwerte angezeigt werden, an die übergeben wurde InnerProcedureCallWithinLoop? Es gibt 54 Parameter. Muss ich im Wesentlichen "54 Zeilen debug-printfs" in mein SQL schreiben, oder kann ich alle Parameterwerte eines Prozeduraufrufs sichern, während ich ein SQL-Trace wie mache?

Wenn ich gerade einen Trace erhalte, erhalte ich folgende Ausgabe:

EXEC  @ConsiderItem = InnerProcedureCallWithinLoop  @from_locn,        
                        @About53ParmsOmitted

Was ich möchte wissen , ist , dass @from_locn = 1und @About53ParmsOmitted = 'hello world'und so weiter.

Dies sagt mir nicht den tatsächlichen Wert des Parameters @from_locn. Im Fall dieses ersten Parameters wird er an meine gespeicherte Prozedur der obersten Ebene übergeben, sodass ich weiß, dass er 0 oder 1 ist. Ungefähr 40 der 43 Parameter in dieser inneren Prozedur stammen jedoch aus der FETCH NEXT FROM aCursorOperation innerhalb einer WHILESchleife.

Im Moment sagt mir die Ablaufverfolgung, wie oft InnerProcedureCallWithinLoopaufgerufen wurde und wie lange jeder Aufruf gedauert hat, aber nicht, welche Werte die Parameter für diesen Aufruf hatten. Wenn ich irgendwie "ausführbare eigenständige SQL-Skripte" bekommen könnte, die einen Eckfall aus meinem Code nachbilden, während ich diese Skripte durcharbeite und diese Bruttofunktionen einrichte (ich weiß, 54 Parameter, das ist wirklich grob, aber ich habe nicht geschrieben) Ich könnte eine Stunde brauchen, um ein SQL-Skript zu erstellen, mit dem ich diesen Eckfall selbst aufrufen kann, außerhalb dieses riesigen Knurrens von gespeicherten SQL Server-Prozeduren.

Dies ist Teil der Bemühungen, einen Drilldown zu einem SQL-Ausdruck durchzuführen und Skripts zu erstellen, mit denen diese komplexen gespeicherten Prozeduren überprüft werden können.

Update Ich habe eine RPC-Aufzeichnungsoption "Output Param" gefunden, aber keine "RPC IN PARAM" -Aufzeichnungsoption.


Es sind nicht nur die 54 Parameter, die eklatant sind :-) All diese Schleifen, um einen Cursor aufzurufen. Das ist eklig :-) Hast du schon mit dem Plan Explorer von SQL Sentry gespielt? Sie können die kostenlose Version oder eine Testversion der Vollversion verwenden. Dies
Mike Walsh

Können Sie uns mitteilen, welche Ereignisse Sie aufzeichnen?
Mike Walsh

2
Das einzige Mal, wenn der Profiler diese Daten abfängt (glaube ich), ist, wenn Sie es aufrufen? Versuchen Sie, eine Audit-Tabelle mit all diesen Parametern einzurichten, und fügen Sie sie einfach ein, bevor Sie den Cursor in eine Schleife setzen.
Jcolebrand

RPC: Abgeschlossen zeigt Parameterwerte, jedoch auf der äußeren Ebene.
Mike Walsh

3
+1 für die Frage, als Belohnung für Ihren Schmerz. Wenn ich könnte, würde ich noch einmal +1 geben, wenn ich die Frage ohne Erklärungen stelle.
Mark Storey-Smith

Antworten:


8

Ich beiße auf die Kugel und sage Ihnen, dass eine solche Spur nicht eingerichtet werden kann, weil sie nicht der [wahrgenommene] Zweck von Spuren ist. Ich habe es immer so gemacht:

WHILE (@@ FETCH_STATUS = 0) AND
            (@ About80MoreBooleanExpressionsHere)
BEGIN / * 1 * /
    - Ungefähr 700 Zeilen Logik, Mathematik und If-Parameter-this-then-that
    -
      Material
weggelassen INSERT InnerProcedureCallWithinLoop__TraceTable               VALUES (@from_locn, @ About53PARAMSOMITTED
      EXEC @ConsiderItem =
            InnerProcedureCallWithinLoop
                  @from_locn,
                        @ About53PARAMSOMITTED,
...

Wenn ich weiß, dass es immer nur von einem Ort aus angerufen wird. Ansonsten mache ich es in der Angerufenen statt im Anrufer.

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

Dies unterscheidet sich offensichtlich von der Verwendung eines Trace, der Ereignisse erfasst, auch wenn sie gestartet und nie beendet wurden (fehlerhafte Parameter, zurückgesetzte Transaktionen). Wenn dies Ihr Problem ist, müssen Sie sich die CLR- oder E-Mail-Methoden ansehen, um die erfasste Ausgabe nach außen zu verschieben.


Das ist was ich dachte.
Warren P
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.