在 SQL Server 中,有没有办法确定传递给正在执行的存储过程的参数的值

use*_*667 13 sql-server-2005 sql-server stored-procedures t-sql dmv

确定正在执行的存储过程的一种方法是使用“动态管理”方法,如下所示:

SELECT 
    sqlText.Text, req.* 
FROM 
    sys.dm_exec_requests req
OUTER APPLY 
    sys.dm_exec_sql_text(req.sql_handle) AS sqltext
Run Code Online (Sandbox Code Playgroud)

但是,这仅显示存储过程的 create 语句的文本。例如:

CREATE PROCEDURE IMaProcedure @id int AS SELECT * FROM AllTheThings Where id = @id
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想看看运行过程的参数是什么,导致它针对特定的一组违规参数运行这么长时间。

有没有办法做到这一点?(在这个问题中, Aaron Bertrand提到了DBCC InputBuffer,但我认为这不适合这个问题。)

Sol*_*zky 16

此信息——传递到存储过程(即 RPC 调用)或参数化查询的运行时参数值——只能通过 SQL 跟踪(并且我假设在较新版本的 SQL Server 中具有等效的扩展事件)。您可以通过运行SQL Server事件探查器(它与SQL服务器),并选择不同的“已完成”的事件,比如看到:RPC:CompletedSP:Completed,和SQL:BatchCompleted。您还需要选择“TextData”字段,因为值将在那里。

我的回答与@Kin对这个问题的回答之间的区别在于,@Kin 的回答(除非我弄错了,在这种情况下我将删除它)侧重于获得:

  • 您自己的查询计划(在这种情况下,它可以包含运行时参数信息,但不能包含其他会话/SPID),
  • 来自 DMV 的计划(在这种情况下,它们应该只有编译的参数值,而不是运行时值)。

我的回答侧重于获取当前正在运行的其他会话的参数值。依赖 DMV 时,无法知道运行时参数值是否与编译参数值相同。这个问题的上下文是跟踪通过其他会话/SPID 提交的查询的运行时值(在 SQL Server 2005 中,而在 SQL Server 2008 中引入了扩展事件)。


Kin*_*hah 13

可以打开实际执行计划,然后查看执行计划 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
Run Code Online (Sandbox Code Playgroud)

  • 计划缓存只有编译后的值,而不是稍后特定运行的值。也可以在 Profiler 中使用“Showplan XML Statistics Profile”事件来获取实际计划,但如果推出 Profiler,那么获取此信息的密集度会降低。 (6认同)