执行后跟踪存储过程的参数

Cra*_*ein 7 sql-server stored-procedures

我被要求确定存储过程的权限问题。根据用于其参数的值,此存储过程以两种可能的方式运行。

exec ps_my_stored_procedure @a=1, @b=2, @c=3
Run Code Online (Sandbox Code Playgroud)

处理方式与

exec ps_my_stored_procedure @a=5, @b=7, @c=0
Run Code Online (Sandbox Code Playgroud)

您可以说这ps_my_stored_procedure在逻辑上分为两个完全独立的过程。

使用dm_exec_procedure_statsdm_exec_query_stats,我可以找到显示所使用存储过程的 SQL 的执行计划。但是,我无法恢复参数的定义方式和值。

是否可以使用dm_exec_procedure_statsdm_exec_query_stats和任何其他管理视图来重建存储过程的执行,以显示用于其参数的值。

我真正想要的是在缓存中找到存储过程的实际执行,以便我可以执行它EXECUTE AS LOGIN = 'someone'来解决权限问题

Pix*_*ted 11

我经常使用来自http://www.sommarskog.se/query-plan-mysteries.html#otherreasons的以下查询来返回嗅探到的值。另一种方法是在SQL Sentry Plan Explorer 中打开计划并选择参数选项卡。假设您正在查看实际执行计划,XML 方法和计划资源管理器方法都将显示运行时值。

DECLARE @dbname    nvarchar(256),
        @procname  nvarchar(256)

SELECT @dbname  = '',
       @procname = '' -- enter proc name

; WITH basedata AS (
   SELECT qs.plan_handle,
            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 plan_handle,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]
       , n.plan_handle
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)


Tom*_*m V 5

如果您有执行计划,您可以将其查看为 xml,并搜索已编译的参数值

例如,这是来自我的计划缓存中的查询之一的执行计划的实际片段:

   <ParameterList>
      <ColumnReference Column="@P69" ParameterCompiledValue="'2015-06-10 00:00:00.0000000'" />
       <ColumnReference Column="@P68" ParameterCompiledValue="'somestring'" />
   </ParameterList>
Run Code Online (Sandbox Code Playgroud)

如果您的计划被重用,它会在编译时显示值。