8

.NET 環境から、 SqlCommandオブジェクトによって生成される完全な SQL 文字列にアクセスできますか?

注: 完全な SQL 文字列は、VisualStudio のデバッグ モードで、Intellisense ホバーに表示されます。

必要に応じて、リフレクション テクニックを使用します。ここにいる誰かがそれを手に入れる方法を知っていると確信しています。


更新 1 :
パラメータを持つストアド プロシージャを呼び出しておりcmd.CommandType = CommandType.StoredProcedure、生成されて実行された完全な SQL を取得しようとしています。cmd. Prepare()メソッドは、状態フィールドなどに完全な文字列を格納する可能性がある場合、この状況では役に立たない可能性があります。


更新 2:

準備中または実行中に完全な SQL 文字列が内部的に生成されないことを示す以下の (および参照されている) 回答に照らして、.NET Reflector を使用して少し調べてみました。内部接続クラスでさえ、オブジェクトを文字列に煮詰めるのではなく、渡すように見えます。次に例を示します。

内部抽象 void AddPreparedCommand( SqlCommand cmd );
宣言型: System.Data.SqlClient.SqlInternalConnection
アセンブリ: System.Data、Version=2.0.0.0


一般に、何ができるかを証明し、実際に何が起こっているかを示すために、詳細なレベルまで詳しく説明してくれた皆さんに感謝します。とても有難い。徹底した説明が好きです。彼らは確実性を追加し、答えに信憑性を与えます.

4

5 に答える 5

11

すべてのパラメーター名をその値に置き換える単純なループは、最終結果と同様のものを提供しますが、いくつかの問題があります。

  1. パラメータ値を使用して SQL が実際に再構築されることはないため、改行や引用符などを考慮する必要はありません。
  2. コメント内のパラメータ名は、実際にはその値に対して処理されることはなく、そのまま残されます

@NAMEそれらを配置し、やなどの同じ文字で始まるパラメーター名を考慮して、@NAME_FULLすべてのパラメーター名をそのパラメーターの代わりにある値に置き換えることができます。

string query = cmd.CommandText;
foreach (SqlParameter p in cmd.Parameters.OrderByDescending(p => p.ParameterName.Length))
{
    query = query.Replace(p.ParameterName, p.Value.ToString());
}

ただし、これには 1 つの問題が残っています。それは、パラメーターが文字列の場合、最初は次のような SQL になります。

SELECT * FROM yourtable WHERE table_code = @CODE

次のようになります。

SELECT * FROM yourtable WHERE table_code = SOME CODE WITH SPACES

これは明らかに正当な SQL ではないため、いくつかのパラメータ タイプについても説明する必要があります。

DbType[] quotedParameterTypes = new DbType[] {
    DbType.AnsiString, DbType.Date,
    DbType.DateTime, DbType.Guid, DbType.String,
    DbType.AnsiStringFixedLength, DbType.StringFixedLength
};
string query = cmd.CommandText;

var arrParams = new SqlParameter[cmd.Parameters.Count];
cmd.Parameters.CopyTo(arrParams, 0);

foreach (SqlParameter p in arrParams.OrderByDescending(p => p.ParameterName.Length))
{
    string value = p.Value.ToString();
    if (quotedParameterTypes.Contains(p.DbType))
        value = "'" + value + "'";
    query = query.Replace(p.ParameterName, value);
}
于 2011-03-18T18:47:26.693 に答える
6

ここにも同様の質問がいくつかあります。

最も説得力のある答えは、この質問に提供されました:SqlCommand-Objectから生成されたSQL-Statmentを取得する方法は?

答えは次のとおりです。

SQLを生成しないため、できません。

パラメータ化されたクエリ(CommandText内のクエリ)は、プリペアドステートメントと同等のものとしてSQLServerに送信されます。コマンドを実行すると、パラメーターとクエリテキストは別々に扱われます。どの時点でも、完全なSQL文字列は生成されません。

SQLプロファイラーを使用して、舞台裏を見ることができます。

于 2011-03-18T19:22:55.300 に答える
1

コマンドのCommandTextプロパティ (または の呼び出しToString()) により、小さな例外を除いてすべての SQL が得られます。デバッガーに表示されるものは間違いなく表示されます。これは parameter valuesを提供しませんが、実際のコマンドを提供することに注意してください。

唯一の注意点は、CommandTypeisの場合、ADO.NET フレームワークは、接続に対してコマンドを直接実行するのではなく、Text多くの場合 (実際、ほとんどの場合) を使用してコマンドを実行することです。sp_executesqlその意味で、実行される正確なSQL を取得することはできません。

于 2011-03-18T18:49:59.933 に答える
0

私はこれを試していませんが、SMO を使用したい場合は、キャプチャ モードを使用できる可能性があります。

http://msdn.microsoft.com/en-us/library/ms162182(v=sql.120).aspx

于 2014-10-28T19:46:32.587 に答える