เป็นไปได้หรือไม่ที่จะบันทึกค่าพารามิเตอร์ขาเข้าในการเรียกโพรซีเดอร์ขณะติดตามใน SQL Server Profiler?


13

ใช้ SQL Server Profiler (ฉันใช้ SQL Server 2012) ฉันพยายามสร้างการติดตามที่มีประโยชน์ที่แสดงค่าพารามิเตอร์ไม่ใช่เฉพาะ SQL ที่มีชื่อตัวแปร ขั้นตอนที่เก็บไว้จะนำข้อมูลคลังมารวมเพื่อสร้างผลลัพธ์ที่มีค่าอย่างยิ่งและฉันพยายามบันทึกพฤติกรรมที่มีอยู่แล้วดังนั้นฉันจึงสามารถทดสอบหน่วยกำหนดมันอย่างชัดเจนและกำหนดให้เป็นสิ่งที่มีสติ

ฉันมีโพรซีเดอร์ที่เก็บไว้ซึ่งดำเนินการโพรซีเดอร์ย่อย 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 พารามิเตอร์ ฉันต้องเขียน "54 บรรทัดของ debug-printfs" ใน SQL ของฉันหรือฉันสามารถถ่ายโอนค่าพารามิเตอร์ทั้งหมดของการเรียกโพรซีเดอร์ขณะที่ทำการติดตาม SQL ได้อย่างไร?

เมื่อฉันได้รับการติดตามในตอนนี้ฉันจะได้รับผลลัพธ์นี้:

EXEC  @ConsiderItem = InnerProcedureCallWithinLoop  @from_locn,        
                        @About53ParmsOmitted

สิ่งที่ผมอยากจะทราบว่าเป็นที่@from_locn = 1และ@About53ParmsOmitted = 'hello world'และอื่น ๆ

@from_locnนี้ไม่ได้บอกฉันค่าที่แท้จริงของพารามิเตอร์ ในกรณีของพารามิเตอร์แรกนั้นมันถูกส่งผ่านไปยังขั้นตอนการจัดเก็บระดับบนสุดของฉันดังนั้นฉันรู้ว่ามันเป็น 0 หรือ 1 เนื่องจากกรณีอาจ อย่างไรก็ตามประมาณ 40 จาก 43 params ในกระบวนงานภายในนั้นมาจากการFETCH NEXT FROM aCursorดำเนินการภายในWHILEลูป

ในขณะนี้การติดตามบอกฉันว่ามีกี่ครั้งที่InnerProcedureCallWithinLoopถูกเรียกใช้และใช้เวลานานเท่าใด แต่ไม่ได้มีค่าของพารามิเตอร์สำหรับการโทรนั้นเท่าไหร่ ถ้าฉันจะได้รับ "สคริปต์ SQL แบบสแตนด์อโลนที่รันได้" ซึ่งทำซ้ำบางส่วนของมุมที่ฉันพบในรหัสของฉันในขณะที่ติดตามสคริปต์เหล่านี้การตั้งค่าฟังก์ชั่นรวมเหล่านี้ (ฉันรู้ว่า 54 พารามิเตอร์นั่นคือขั้นต้นจริงๆ แต่ฉันไม่ได้เขียน พวกเขา!) อาจใช้เวลาหนึ่งชั่วโมงในการพิมพ์เพียงเพื่อสร้างสคริปต์ SQL ที่ให้ฉันเรียกใช้มุมตัวเองนี้นอกคำรามขนาดใหญ่ของ SQL Server ที่เก็บไว้

นี่เป็นส่วนหนึ่งของความพยายามที่จะเจาะลึกถึงนิพจน์ SQL และสร้างสคริปต์ที่สามารถตรวจสอบขั้นตอนการจัดเก็บที่ซับซ้อนเหล่านี้ได้

อัปเดตฉันพบตัวเลือกการบันทึก "Output Param" RPC แต่ไม่ใช่ตัวเลือกการบันทึก "RPC IN PARAM"


ไม่ใช่แค่ 54 พารามิเตอร์ที่เป็นขั้นต้น :-) ทุกอย่างที่วนลูปเพื่อเรียกเคอร์เซอร์ นั่นคือขั้นต้น :-) คุณเคยเล่นกับ Plan Explorer ของ SQL Sentry หรือไม่? คุณสามารถใช้รุ่นฟรีหรือใช้รุ่นเต็มและสามารถช่วยคุณได้หากคุณมีสายพร้อมพารามิเตอร์ทั้งหมด - sqlsentry.net/plan-explorer/sql-server-query-view.asp
Mike Walsh

คุณสามารถบอกเราว่าคุณจับภาพเหตุการณ์อะไร
Mike Walsh

2
ครั้งเดียวที่ผู้สร้างโปรไฟล์จับข้อมูลนั้น (ฉันคิดว่า) คือเมื่อคุณเรียกมันว่าอะไร? ลองตั้งค่าตารางการตรวจสอบกับพารามิเตอร์ทั้งหมดและทำการแทรกก่อนที่จะวนเคอร์เซอร์ของคุณ?
jcolebrand

RPC: เสร็จแล้วแสดงค่าพารามิเตอร์ แต่ที่ระดับนอก
Mike Walsh

3
+1 สำหรับคำถามเป็นการตอบแทนความเจ็บปวดของคุณ หากฉันสามารถทำได้ฉันจะ +1 อีกครั้งสำหรับการโพสต์คำถามโดยไม่มีการ expletives
Mark Storey-Smith

คำตอบ:


8

ฉันจะกัดกระสุนและบอกคุณว่าร่องรอยนั้นไม่สามารถตั้งค่าได้เพราะมันไม่ใช่จุดประสงค์ [รับรู้] ของการติดตาม ฉันทำแบบนี้มาตลอด:

ในขณะที่ (@@ FETCH_STATUS = 0) และ
            (@ About80MoreBooleanExpressionsHere)
BEGIN / * 1 * /
    - ประมาณ 700 เส้นของตรรกะคณิตศาสตร์และถ้าพารามิเตอร์นี้แล้วที่
    - สิ่งที่มองข้าม
      INSERT InnerProcedureCallWithinLoop__TraceTable
              VALUES (@from_locn @ About53PARAMSOMITTED

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

ถ้าฉันรู้ว่ามันถูกเรียกมาจากที่เดียวเท่านั้น มิฉะนั้นฉันจะทำมันใน callee แทนผู้โทร

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 หรือวิธีการทางอีเมลเพื่อเอาท์พุทภายนอกที่บันทึกไว้


นั่นคือสิ่งที่ฉันคิดว่า.
Warren P
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.