1

sp_executesqlに渡されたパラメーターを使用していくつかのselectステートメントを実行するプログラムをC#で作成しています。テスト中に遭遇する問題の1つは、SQL Profilerから実行するコマンドを取得する場合でも、Visual Studioのウォッチからコマンドを取得する場合でも、パラメーターの値は、明示的に指定されるのではなく、ステートメントの最後に指定されることです。クエリの行。テストの目的で、パラメーターの代わりにパラメーター値を使用する簡単な方法が必要です。

したがって、代わりに:

exec sp_executesql N'
SELECT CustomerName
FROM CustomerTable ct WITH(NOLOCK)
WHERE ct.CustomerId <> @CustomerId
AND ct.ItemId <> @ItemId
AND ct.TransactionId = @TransactionId'
,N'@CustomerId bigint,@ItemId nvarchar(1),@TransactionId nvarchar(30), @CustomerId = 3000, @ItemId = N'4', @TransactionId=N'43281'

が欲しいです:

exec sp_executesql N'
SELECT CustomerName
FROM CustomerTable ct WITH(NOLOCK)
WHERE ct.CustomerId = 3000
AND ct.ItemId <> N'4'
AND ct.TransactionId = N'43281''

例の構文は概念を示すために使用されているだけなので、あまり注意を払わないでください。誰かがこれを行うための速い方法を知っていますか?基本的には、条件を変更して、返される結果にどのように影響するかをテストするのが簡単になるため、テスト目的で置き換えてもらいたいと思います。どなたでもお役に立てれば幸いです。ありがとう。

4

1 に答える 1

3

パラメータ化されたsp_executesqlには、次のような多くの利点があります。

  • 明示的にパラメーター化することにより、SQLが明確なタイプの適切なクエリプランをキャッシュする機会を与えています
  • パラメータ化することで、SQLインジェクション攻撃のような厄介な問題を防ぐことができますが、問題のある文字をエスケープする必要もなくなります。

したがって、生成されたsp_executesqlを「パラメータ化解除」できたとしても、インラインSQLを実行すると、クエリプランはパラメータ化されたバージョンと大幅に異なる可能性があり、エスケープなども行う必要があります(つまり、適切ではありません)。リンゴとリンゴのテスト用)。

パラメータ化されたsp_executesqlが必要ない理由を私が考えることができる唯一の理由は、読みやすさのためですか?

編集:代用しようとすると、使用しているテクノロジーによって異なります

@mellamokbが示唆したように、ExecuteReaderを使用している場合、これは非常に簡単です。

あなたのコードが次のようなものだと仮定します

string sqlCmd = "SELECT CustomerName 
FROM CustomerTable ct WITH(NOLOCK) 
WHERE ct.CustomerId <> @CustomerId 
AND ct.ItemId <> @ItemId 
AND ct.TransactionId = @TransactionId";

cmd.CommandText = sqlCmd;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("CustomerId", DbType.Int32, myCustomerId));
cmd.Parameters.Add(new SqlParameter("ItemId", DbType.String, myItemId));
..
cmd.ExecuteReader()

次に、コードを追加してテストクエリを作成できます。

string sqlMyTest = sqlCmd.Replace("@CustomerId", myCustomerId.ToString());
sqlMyTest = sqlMyTest.Replace("@ItemId", specialEscapeFunction(myItemId));
.. do something with sqlMyTest

ただし、Linq2SQLやEFのようなORMはそれほど簡単ではありません

customerTable.Where(c => (c.CustomerId != myCustomerId) && (c.ItemId != myItemId) && (c.TransactionId == myTransactionId))

おそらくLinqPadのようなツールが役立つかもしれませんか?

于 2012-03-27T18:21:54.437 に答える