ユーザーが名、姓、学期、またはコースの任意の組み合わせを指定できる検索画面があります。これらの潜在的なオプション パラメータを処理するために、SQL Server 2005 ストアド プロシージャを最適にコーディングする方法がわかりません。最も効率的な方法は何ですか?組み合わせごとに別々の手順?項目を null 許容パラメーターとして取り込み、動的 SQL を構築しますか?
5 に答える
各パラメーターをオプションに設定します(デフォルト値はnullです)
そして、それをWHERE ....で処理します。
FirstName=ISNULL(@FirstName,FirstName)
AND
LastName=ISNULL(@LastName,LastName)
AND
SemesterID=ISNULL(@SemesterID,SemesterID)
これは、名のみ、姓のみ、3 つすべてなどを処理します。
また、SQL文字列を動的に構築して実行するよりも、はるかにきれい/管理しやすく/堅牢です。
最善の解決策は、sp_execute_sql を利用することです。例えば:
--BEGIN SQL
declare @sql nvarchar(4000)
set @sql =
'select * from weblogs.dbo.vwlogs
where Log_time between @BeginDate and @EndDate'
+ case when @UserName is null then '' else 'and client_user = @UserName' end
sp_execute_sql
@sql
, @params = '@UserName varchar(50)'
, @UserName = @UserName
--END SQL
ムエルテが述べたように、これは同様のステートメントを exec() するよりもパフォーマンス上の利点があります。
muerteが指摘しているように、プランは最初のパラメーターセットに対してキャッシュされます。これにより、代替パラメーターを使用してその後毎回実行すると、パフォーマンスが低下する可能性があります。これを解決するには、プロシージャのWITHRECOMPILEオプションを使用します。
ケビン・フェアチャイルドと同じコンセプトを投稿しただけで、それが私たちが通常それを処理する方法です.
コードで動的SQLを実行して、必要に応じてステートメントを作成できますが、その場合はSQLインジェクションを監視する必要があります。
プランは最初のパターン、または最初の条件セットに対してのみキャッシュされるため、sp_executesqlを使用して実行します。
このTechNet の記事をご覧ください。
ストアド プロシージャの代わりに sp_executesql を使用すると、Transact-SQL ステートメントのパラメーター値の変更が唯一のバリエーションである場合に、Transact-SQL ステートメントを何度も実行できます。Transact-SQL ステートメント自体は一定のままで、パラメーター値のみが変更されるため、SQL Server クエリ オプティマイザーは、最初の実行で生成した実行プランを再利用する可能性があります。