2017-01-29 10 views
0

SQL Serverデータベースで次のクエリを実行しました。cでSQLクエリテキストを正規化する

SELECT * FROM Production.Product WHERE Name = 'Bearing Ball' 

は、それから私は、次のSQLコマンドを使用して統計と一緒にクエリテキストを取得しようとしました:

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 

私はこの

​​

ような何かを得る。しかし、私が実行したいです私のC#プログラムからの文字列の一致とクエリテキストの統計情報を取得します。 C#プログラムは元のクエリ(SELECT * FROM Production.Product WHERE Name = 'Bearing Ball')のみを知っています。置き換えられるパラメータは唯一の問題ではありません。データベースサーバがテーブル名に角括弧を追加しているのがわかるからです。

この問題を解決する方法はありますか? SELECT * FROM [Production]。[Product] WHERE [Name] = @(varchar(8000))を正規化した正規表現に変換するにはどうすればよいですか? 1)? Microsoft.Data.Schema.ScriptDomを使用してこれを行うことはできますか?データベースサーバーでクエリを実行せずにクエリを正規化する必要があることに注意してください。

答えて

0

一つの解決策、あなたは、単にそれらを一致できるようにしたい場合は、コメントにGUIDを使用してSQL文をプレフィックスと、そのことで一致し、次のようになります。

だから、C#で:

var statementMagicStringMarker = Guid.NewGuid().ToString("N"); 
cmd.CommandText = "--" + statementMagicStringMarker + "\n" + 
"SELECT * FROM Production.Product WHERE Name = 'Bearing Ball'"; 
cmd.ExecuteNonQuery(); 

その後、統計クエリを実行するときに、statementMagicStringMarkerを含むクエリを探します。クリーンアップされたとしても、同じステートメントがあることがわかります。 Guid.NewGuid()を使用すると、異なるクライアントから実行していても、すべてのクエリに対して一意のマーカーが得られることがわかります。

+0

クエリは第三者アプリケーションからも実行されるため、すべてのクエリの統計情報を取得できるように、クエリを汎用フォーマットに変換できる方が良いでしょう。 – Deepan

0

ScriptDomを使用してT-SQLコードを正規化することは可能です。 ScriptDomは有効なT-SQLのみを解析するので、解析する前に接頭辞付きのパラメータリストを削除する必要があります。

ただし、Microsoft.Data.Schema.ScriptDomは、Visual Studioに同梱されていた古いバージョンです。 SQL Server 2012には、SQL Server自体に新しいバージョンが付属しているため、これには名前空間Microsoft.SqlServer.TransactSql.ScriptDomがあり、最新のSQLサーバーバージョンで最新の状態に保たれています。プログラミングScriptDomは、しかし、簡単な作業ではありません。 T-SQLコードの正規化はさらに複雑な作業です。 Arvind Shyamsundarがトピックのブログをmsdn blogsに投稿しました。 Arvindによってデモされたメソッドは、コードのすべてのコピーを正規化し、結果のステートメントをチェックサムで返し、キーのチェックサムを使用して辞書に結果を格納します。チェックサムが同じ場合、T-SQLは以前に入れられたものと同等でなければなりません。おそらくArvindのデモのすべての正規化があなたのユースケースに役立つわけではありませんが、このアイデアはあなたにとっても役立ちます。リテラル値の正規化のように、いくつかをオフにする必要があるかもしれません。

Arvindは彼のブログにデモコードを添付しているので、そこから簡単に始めることができます。私は拡張機能を追加できるように、ArvindにGitHubにコードを公開するコメントを頼んだが、彼からまだ聞いていない。余分な中カッコを削除する、ブール論理を正規化する、スカラー式を正規化するなど、より多くの正規化を行うためのArvindのデモについては、自分の目的のために拡張しました。さらに、私はジョインステートメントやジョイン条項を正規化するなど、さらに多くの正規化に取り組んでいます。しかし、これはむしろ複雑であることがわかります...私は自分のコードを共有したいと思っています。