I'm running the following statement to see what queries are executing in 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>')
The sql text that comes back is parameterized:
(@Parm0 int) select * from foo where foo_id = @Parm0
Is there any way to get the values for the parameters that the sta开发者_开发技巧tement is using? Say by joining to another table perhaps?
Edit : Remus is correct, this will only bring out the compiled versions on the first time that the query plan hit the cache, not subsequent runs.
You should be able to get the parameters from the query plan, since it contains the last parameters used. Altering your code:
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>')
You will find the final column of the query plan is query_plan, an xml version of the query plan which you can manually inspect, at the bottom of the XML are the parameters, or if you fancy the challenge use XML parsing and XQuery to pull out the ParameterList tags
A query that give the login name, hour of execution and query as text of last events, if you can give a hand to the join of sys.dm_exec_query_stats, but it works
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
In case someone stumble upon this thread looking for a proper solution (which the other answers sadly lack), I found this helpful post from mssqltips.
I cleaned-up and tweaked the query a little bit to make this one:
-- 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
It works quite well, and each parameters will have its own line.
For instance:
If you are using a version prior to SQL Server 2012 or Amazon RDS where the TRY_CONVERT function does not exist, this is a variation of the Indigo query that will work.
-- 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
精彩评论