Sql-Server

在 SQL Server 中,有沒有辦法確定傳遞給正在執行的儲存過程的參數值

  • November 29, 2019

確定正在執行的儲存過程的一種方法是使用“動態管理”方法,如下所示:

SELECT 
   sqlText.Text, req.* 
FROM 
   sys.dm_exec_requests req
OUTER APPLY 
   sys.dm_exec_sql_text(req.sql_handle) AS sqltext

但是,這僅顯示儲存過程的 create 語句的文本。例如:

CREATE PROCEDURE IMaProcedure @id int AS SELECT * FROM AllTheThings Where id = @id

理想情況下,我想看看執行過程的參數是什麼,導致它對於特定的違規參數集執行這麼長時間。

有沒有辦法做到這一點?(在這個問題中, Aaron Bertrand提到了 DBCC InputBuffer,但我認為這不適合這個問題。)

此資訊——傳遞到儲存過程(即 RPC 呼叫)或參數化查詢的執行時參數值——只能通過 SQL 跟踪獲得(我假設在較新版本的 SQL Server 中具有等效的擴展事件)。您可以通過執行 SQL Server Profiler(SQL Server 附帶)並選擇各種“已完成”事件來查看這一點,例如:RPC:Completed、、SP:CompletedSQL:BatchCompleted。您還需要選擇“TextData”欄位,因為值將在其中。

我的回答和@Kin 在這個問題上的回答之間的區別在於@Kin 的回答(除非我弄錯了,在這種情況下我會刪除它)側重於獲得:

  • 您自己的查詢計劃(在這種情況下,它可以包含執行時參數資訊,但不能用於其他會話/SPID),或者
  • 來自 DMV 的計劃(在這種情況下,它們應該只有編譯的參數值,而不是執行時值)。

我的回答側重於獲取目前正在執行的*其他會話的參數值。*依賴 DMV 時,無法知道執行時參數值是否與編譯後的參數值相同。這個問題的上下文是跟踪通過其他會話/SPID 送出的查詢的執行時值(在 SQL Server 2005 中,而在 SQL Server 2008 中引入了擴展事件)。

可以打開實際執行計劃,然後查看執行計劃 XML。

在此處輸入圖像描述

或者您可以使用sql sentry 的計劃資源管理器工具並查看parameters將列出實際執行計劃的選項卡。compiled value``run time value

如果您無法打開實際計劃,則可以如下所述查看計劃記憶體。

-- borrowed from  Erland Sommarskog
-- Link : http://www.sommarskog.se/query-plan-mysteries.html#dmvgettingplans
-- Remember that you are looking at the estimated plan so the actual no. of rows and actual executions wont be there ! <-- Important why a particular plan is bad.

DECLARE @dbname    nvarchar(256),
       @procname  nvarchar(256)
SELECT @dbname = 'Northwind',  -- Your DB name
      @procname = 'dbo.List_orders_11' -- The SP that you want to get parameters for !

; WITH basedata AS (
  SELECT qs.statement_start_offset/2 AS stmt_start,
         qs.statement_end_offset/2 AS stmt_end,
         est.encrypted AS isencrypted, est.text AS sqltext,
         epa.value AS set_options, qp.query_plan,
         charindex('<ParameterList>', qp.query_plan) + len('<ParameterList>')
            AS paramstart,
         charindex('</ParameterList>', qp.query_plan) AS paramend
  FROM   sys.dm_exec_query_stats qs
  CROSS  APPLY sys.dm_exec_sql_text(qs.sql_handle) est
  CROSS  APPLY sys.dm_exec_text_query_plan(qs.plan_handle,
                                           qs.statement_start_offset,
                                           qs.statement_end_offset) qp
  CROSS  APPLY sys.dm_exec_plan_attributes(qs.plan_handle) epa
  WHERE  est.objectid  = object_id (@procname)
    AND  est.dbid      = db_id(@dbname)
    AND  epa.attribute = 'set_options'
), next_level AS (
  SELECT stmt_start, set_options, query_plan,
         CASE WHEN isencrypted = 1 THEN '-- ENCRYPTED'
              WHEN stmt_start >= 0
              THEN substring(sqltext, stmt_start + 1,
                             CASE stmt_end
                                  WHEN 0 THEN datalength(sqltext)
                                  ELSE stmt_end - stmt_start + 1
                             END)
         END AS Statement,
         CASE WHEN paramend > paramstart
              THEN CAST (substring(query_plan, paramstart,
                                  paramend - paramstart) AS xml)
         END AS params
  FROM   basedata
)
SELECT set_options AS [SET], n.stmt_start AS Pos, n.Statement,
      CR.c.value('@Column', 'nvarchar(128)') AS Parameter,
      CR.c.value('@ParameterCompiledValue', 'nvarchar(128)') AS [Sniffed Value],
      CAST (query_plan AS xml) AS [Query plan]
FROM   next_level n
CROSS  APPLY   n.params.nodes('ColumnReference') AS CR(c)
ORDER  BY n.set_options, n.stmt_start, Parameter

引用自:https://dba.stackexchange.com/questions/142488