I executed the following query in the SQL Server database.
SELECT * FROM Production.Product WHERE Name = 'Bearing Ball'
Then I tried to get the query text along with the statistics using the following SQL command :
SELECT
qs.sql_handle,
qs.execution_count AS EXECUTION_COUNT,
AVG_TIME = --Converted from microseconds
(qs.total_elapsed_time/1000000) / qs.execution_count,
qs.total_elapsed_time,
TOTAL_TIME = --Converted from microseconds
qs.total_elapsed_time/1000000,
st.text AS TEXT
FROM
sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC
I get something like this
(@1 varchar(8000))SELECT * FROM [Production].[Product] WHERE [Name]=@1
But, I want to perform a string match from my c# program and get the statistics of the query text. The c# program only knows about the original query (SELECT * FROM Production.Product WHERE Name = 'Bearing Ball'). The parameters getting replaced is not the only problem, as you can see the database server added square brackets to the table names.
Is there a way to overcome this issue. How can I convert my original query(SELECT * FROM Production.Product WHERE Name = 'Bearing Ball') to normalized one((@1 varchar(8000))SELECT * FROM [Production].[Product] WHERE [Name]=@1)? Can I do this using Microsoft.Data.Schema.ScriptDom? Please note that I want to normalize my query without executing it in the database server.
One solution, if you simply want to be able to match them up, would be to prefix your SQL statement with a GUID in a comment and then match by that:
So in C#:
Then when you run your statistics query, look for the query that contains your statementMagicStringMarker, and you'll know you have the same statement, even though it may be cleaned-up. By using Guid.NewGuid() you know you'll get a unique marker for every query, even if running from different clients.