我正在运行以下语句,以查看在sql server中执行的查询:
select *
from sys.dm_exec_requests r
cross apply sys.dm_exec_sql_text(r.sql_handle)
where r.database_id = DB_ID('<dbname>')
返回的sql文本已参数化:
(@Parm0 int) select * from foo where foo_id = @Parm0
有没有办法获取语句正在使用的参数的值?或许加入另一张桌子说?
答案 0 :(得分:6)
编辑:Remus是正确的,这只会在查询计划首次点击缓存而不是后续运行时显示已编译的版本。
您应该能够从查询计划中获取参数,因为它包含最后使用的参数。改变你的代码:
select *
from sys.dm_exec_requests r
cross apply sys.dm_exec_query_plan(plan_handle) as qp
cross apply sys.dm_exec_sql_text(r.sql_handle)
where r.database_id = DB_ID('<dbname>')
您会发现查询计划的最后一列是query_plan,您可以手动检查的查询计划的xml版本,XML的底部是参数,或者如果您喜欢挑战,请使用XML解析和XQuery拉出ParameterList标签
答案 1 :(得分:2)
一个查询,它提供登录名,执行时间和查询作为最后一个事件的文本,如果可以帮助您连接sys.dm_exec_query_stats,但是可以使用
SELECT distinct
s.login_name,
qs.creation_time
,SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset END
- qs.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_sessions S
LEFT JOIN sys.dm_exec_connections AS c ON S.session_id = c.session_id
,sys.dm_exec_query_stats QS --qs on c.most_recent_sql_handle = qs.sql_handle
OUTER APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
WHERE ST.text LIKE '%yourKeyWord%' and s.login_name <> 'NT SERVICE\SQLSERVERAGENT'
order by qs.creation_time desc
答案 2 :(得分:1)
万一有人偶然发现此线程以寻找适当的解决方案(其他人遗憾地缺乏此解决方案),我发现了这个helpful post from mssqltips。
我整理了一下查询语句并进行了一些调整,以使其成为一个:
-- cleanup
IF OBJECT_ID('tempdb..#compiledValue') IS NOT NULL
DROP TABLE #compiledValue
GO
-- Prepare temp table #compiledValue
SELECT
OBJECT_NAME(est.objectid) ObjectName,
DB_NAME(est.dbid) DBName,
eqs.last_execution_time,
est.text,
(eqs.statement_start_offset / 2) + 1 AS statement_start_offset,
(IIF(eqs.statement_end_offset = -1, DATALENGTH(est.text), eqs.statement_end_offset) - eqs.statement_start_offset) / 2 + 1 AS statement_end_offset,
TRY_CONVERT(XML,
SUBSTRING(etqp.query_plan,
CHARINDEX('<ParameterList>',etqp.query_plan),
CHARINDEX('</ParameterList>',etqp.query_plan) + LEN('</ParameterList>') - CHARINDEX('<ParameterList>',etqp.query_plan) )) AS statement_params
INTO #compiledValue
FROM sys.dm_exec_query_stats eqs
CROSS APPLY sys.dm_exec_sql_text(eqs.sql_handle) est
CROSS APPLY sys.dm_exec_text_query_plan(eqs.plan_handle, eqs.statement_start_offset, eqs.statement_end_offset) etqp
SELECT
cvalue.last_execution_time,
cvalue.DBName,
cvalue.ObjectName,
SUBSTRING(cvalue.text,cvalue.statement_start_offset,cvalue.statement_end_offset) AS sql_text,
pc.compiled.value('@Column', 'nvarchar(128)') AS Parameterlist,
pc.compiled.value('@ParameterCompiledValue', 'nvarchar(128)') AS [compiled Value]
FROM #compiledValue cvalue
OUTER APPLY cvalue.statement_params.nodes('//ParameterList/ColumnReference') AS pc(compiled)
WHERE cvalue.text NOT LIKE '%#compiledValue%' -- ignore these queries based on temp table name
ORDER BY cvalue.last_execution_time DESC
GO
-- cleanup
DROP TABLE #compiledValue
GO
效果很好,每个参数都有自己的一行。
答案 3 :(得分:0)
如果您使用的是不存在 TRY_CONVERT 函数的 SQL Server 2012 或 Amazon RDS 之前的版本,则这是可以工作的 Indigo 查询的变体。
-- cleanup
IF OBJECT_ID('tempdb..#compiledValue') IS NOT NULL
DROP TABLE #compiledValue
GO
-- Prepare temp table #compiledValue
SELECT
OBJECT_NAME(est.objectid) ObjectName,
DB_NAME(est.dbid) DBName,
eqs.last_execution_time,
est.text,
(eqs.statement_start_offset / 2) + 1 AS statement_start_offset,
(IIF(eqs.statement_end_offset = -1, DATALENGTH(est.text), eqs.statement_end_offset) - eqs.statement_start_offset) / 2 + 1 AS statement_end_offset,
--TRY_CONVERT(XML,
-- SUBSTRING(etqp.query_plan,
-- CHARINDEX('<ParameterList>',etqp.query_plan),
-- CHARINDEX('</ParameterList>',etqp.query_plan) + LEN('</ParameterList>') - CHARINDEX('<ParameterList>',etqp.query_plan) )) AS statement_params,
CASE
WHEN CHARINDEX('<ParameterList>', etqp.query_plan) > 0
THEN CONVERT(XML,
SUBSTRING(etqp.query_plan,
CHARINDEX('<ParameterList>', etqp.query_plan),
CHARINDEX('</ParameterList>', etqp.query_plan) + LEN('</ParameterList>') - CHARINDEX('<ParameterList>', etqp.query_plan) ))
ELSE NULL
END AS statement_params
INTO #compiledValue
FROM sys.dm_exec_query_stats eqs
CROSS APPLY sys.dm_exec_sql_text(eqs.sql_handle) est
CROSS APPLY sys.dm_exec_text_query_plan(eqs.plan_handle, eqs.statement_start_offset, eqs.statement_end_offset) etqp
SELECT
cvalue.last_execution_time,
cvalue.DBName,
cvalue.ObjectName,
SUBSTRING(cvalue.text,cvalue.statement_start_offset,cvalue.statement_end_offset) AS sql_text,
pc.compiled.value('@Column', 'nvarchar(128)') AS Parameterlist,
pc.compiled.value('@ParameterCompiledValue', 'nvarchar(128)') AS [compiled Value]
FROM #compiledValue cvalue
OUTER APPLY cvalue.statement_params.nodes('//ParameterList/ColumnReference') AS pc(compiled)
WHERE cvalue.text NOT LIKE '%#compiledValue%' -- ignore these queries based on temp table name
ORDER BY cvalue.last_execution_time DESC
GO
-- cleanup
DROP TABLE #compiledValue
GO