回答:
sp_executesql
クエリプランの再利用を促進する可能性が高くなります。を使用する場合sp_executesql
、パラメーターは呼び出し署名で明示的に識別されます。この優れた記事はこのプロセスを説明しています。
動的SQLの多くの側面についてよく引用されるリファレンスは、Erland Sommarskogの必読の記事です:「動的SQLの呪いと祝福」。
SP_EXECUTESQLの大きな点は、パラメーター化されたクエリを作成できることです。これは、SQLインジェクションに関心がある場合に非常に適しています。
Microsoftの「sp_executesqlの使用」の記事sp_executesql
では、execute
ステートメントの代わりに使用することを推奨しています。
このストアドプロシージャはパラメータ置換をサポートしているため、sp_executesqlはEXECUTEよりも用途が広いです。また、sp_executesqlはSQL Serverで再利用される可能性が高い実行プランを生成するため、EXECUTEよりもsp_executesqlの方が効率的です。
したがって、要点:ステートメントを使用しないでexecute
ください。を使用しsp_executesql
ます。
sp_executesql
いるため、交換に使用できないケースを見てきましたexecute
。おそらく、私が強調しようとしている点を次のsp_executesql
ようにexecute
表現する必要があります。
最近は常にsp_executesqlを使用しますが、それはすべて、パラメーターと変数を処理するEXECのラッパーです。
ただし、特に複数のデータベースにまたがるデータがあり、CONSTRAINTを使用してインデックススキャンを制限している非常に大規模なデータベースでクエリをチューニングする場合は、OPTION RECOMPILEを忘れないでください。
OPTION RECOMPILEを使用しない限り、SQLサーバーはクエリの「1つのサイズですべてに適合する」実行プランを作成しようとし、実行されるたびにフルインデックススキャンを実行します。
これはシークよりもはるかに効率が悪く、クエリを実行していない範囲に制限されているインデックス全体をスキャンする可能性があります。
コマンドを実行する
declare @sql varchar (100)
set @sql ='select * from #td1'
if (@IsMonday+@IsTuesday !='')
begin
set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
end
exec( @sql)
int
を動的SQLにすることはできません。@sqlは次のように宣言されていることに注意してくださいvarchar
かnvarchar