最近、データベースに対してSQLコードレビューツールを使用しました。 EXEC
の代わりにSP_EXECUTESQL
を使用することをお勧めします。
SP_EXECUTESQL
は、SQLインジェクションを回避するのに役立ちます。 EXEC
とSP_EXECUTESQL
を使用する場合、パフォーマンスに違いはありますか?.
これは、セキュリティと一貫性のために主に優先されるものであり、パフォーマンスとは何の関係もありません(ただし、SQL Serverの古いバージョンではそれが問題であった可能性があります)。
パラメータがあるときに常に_sp_executesql
_を使用する必要があるときにEXEC()
を使用する理由EXEC()
は、すべての変数を単一の文字列に連結するように強制します。これにより、乱用に熟します。
これについては、ここで詳しく説明しました。
ここでは、SQLインジェクションから身を守る方法についても書きました。
SQLインジェクションはかなり大きな問題であり、他の多くの人々もそれについて書いています。
最後に、システムプロシージャを呼び出すときは、_sys.all_objects
_に格納されているものと一致する適切な大文字小文字を使用していることを確認してください。すべて小文字にする必要があります。そうしないと、コードが大文字と小文字を区別するインスタンスにデプロイされると、すべて失敗し始めます。
まず、両方のコマンドの意味を確認してみましょう。
_sp_executesql
_:何度も再利用できるTransact-SQLステートメントまたはバッチ、または動的に構築されたものを実行します。 Transact-SQLステートメントまたはバッチには、埋め込みパラメーターを含めることができます。exec
:Transact-SQLバッチ内のコマンド文字列または文字列、またはシステムストアドプロシージャ、ユーザー定義のストアドプロシージャ、CLR(共通言語ランタイム)のいずれかを実行しますプロシージャ、スカラー値のユーザー定義関数、または拡張ストアドプロシージャ。 EXECUTEステートメントを使用して、パススルーコマンドをリンクサーバーに送信できます。
主な違いのいくつか:
sp_executesql
_では、ステートメントをパラメータ化できるため、SQLインジェクションの点でEXECよりも安全です。sp_executesql
_は、キャッシュされたクエリプランを活用できます。TSQL文字列は1回だけ作成され、その後、同じクエリが_sp_executesql
_で呼び出されるたびに、SQL Serverはキャッシュからクエリプランを取得して再利用します。参照:
https://blogs.msdn.Microsoft.com/turgays/2013/09/17/exec-vs-sp_executesql/
https://msdn.Microsoft.com/en-us/library/ms188001.aspx
https://msdn.Microsoft.com/en-us/library/ms188332.aspx
編集:
パフォーマンスに関する次の記事を見つけました:
パフォーマンスは、ストアドプロシージャのこれら2つの方法の間の議論の問題です。その名前が示すように、_sp_execute
_自体は、システムデータベースに格納されるストアドプロシージャです。したがって、_SP_ExecuteSQL
_にはSQL文字列を渡す必要があります。ただし、キャッシュの可能性が高い場合を除き、2回目以降の実行ではパフォーマンスが向上します。
つまり、パラメータ化された動的T-SQLは再利用を促進します。さらに、sp_executeは、exec()
に対して動的クエリを実行しているときに不要なコンパイルを回避する可能性が高いと考えられます。しかし、一部の専門家は、両方の方法について計画がキャッシュされると考えるので、それを誤解を招くものと見なします。実際、_SP_ExecuteSQL
_のパラメーター化されていないクエリの場合、後者と同じ特性が示されます。
http://www.technovisitors.com/2014/07/SPExecuteSQL-Vs-Execute-SQL-Server.html
EXECはアドホックキャッシュを使用し、アドホックプランの肥大化を引き起こす可能性がありますが、sp_executesqlはそうしませんが、プランの安定度に依存します。