2017-02-10 6 views
2

私は、動的SQLを使用するいくつかのストアドプロシージャを持っています。 エラー処理のためにトラブルシューティングや変更が非常に煩わしくなる可能性があるため、動的ではないように変更したいと思います(エラーメッセージをクリックしてもエラーにはなりません)。私はテキストを選択してこれを手助けするために通常のSQLとして貼り付けることができますが、かなりイライラしています。動的SQLの代替

私がこれに抱えている問題は、動的ではない場合、クエリがより遅く実行されることです。具体的には、where句は、柔軟性の向上により動的クエリではるかに高速です。句は次のようになりどこ

where 
    SomeColumn = case when @variable1 = 0 then SomeColumn else @variable1 end 
and(
    (@variable2 = -2 and SomeColumn2 = 1) 
    or (@variable2 = -1) 
    or (@variable2 = 0 and SomeColumn2 = 0 and SomeColumn3 = 0) 
    or (@variable2 = 1 and SomeColumn2 = 0 and SomeColumn3 > 0) 
    ) 

しかし、動的:このような場合ステートメントを使用して

where ' + @SomeCondition + @SomeCondition2 + ' 

declare @SomeCondition nvarchar(max) = case 
    when @variable3 = -2 then N'Condition 1' 
    when @variable3 = 0 then N'Condition 2' 
    when @variable3 = 1 then N'Condition 3' 
    else N'' 
    end 

のみたとえば、静的な句は次のようなものになるだろう場所私が考えることができるのは複数のifステートメントを使用しており、各ステートメントのwhere句のみを変更することですが、これは非常に無駄で時間がかかるようです。

その他の動的SQLの代替方法はありますか? これは失敗しました。SQL Serverにエラーを正しく伝えるためにできることはありますか?

+0

動的SQLに起因するエラーを取得するために 'try' /' catch'を使用していますか?エラー処理を修正することで、必要な処理が行われる可能性があります。あなたが 'recompile'オプションを使わなければ、複数の' if'でも問題になることがあります。 –

+0

これは非常に役に立ちます。不満足なエラー処理は、私が動的クエリを変更する唯一の理由です。私はちょうどSQLを含む変数内でtry/catchを使用するか、それを外部に書き出す必要がありますか?私は、動的SQLを使ってそれをどうやってどうやって進めるかについては完全にはわかりません –

+1

専門的で最適化された手順を作成し、パラメータに基づいて適切な手順を呼び出すことで、OR条件を避けることができます。しかし、あなたは維持するためのより多くの手続きを持っています。私の経験では、ダイナミックなクエリや特殊なクエリだけでなく、機能するための「ワンサイズ・オール・オール」クエリ(ここではor-or-or-orパターン)は決して得られません。 –

答えて

3

OPTION (RECOMPILE)をクエリに追加します。これにより、実行ごとに再コンパイルされます。オプティマイザは、動的SQLを使用しているように、述語をショートカットして削除するほどスマートです。

+0

これは私のクエリをはるかに速くしました(ありがとう!)、しかし、エラーメッセージをクリックすると、クエリのランダムな場所にまだ私をもたらします。実行されるSQL変数内のクエリの最後に 'option(recompile)'を追加します。 –

+0

複雑なクエリでは、エラーが発生した行番号が欺かれている可能性があります。また、https://connect.microsoft.com/SQLServer/feedback/details/857794/この既知の問題にぶつかる可能性があります。とにかく、これは少なくともパフォーマンスで助けてうれしかったです。 – dean

+0

私のクエリは次のように構成されています: 'declare @SQLText nvarchar(max)= N'BigQueryGoesHereオプション(再コンパイル) 'exec sys.sp_executesql @SQLText' これは正しくエラーを返しますか?クエリテキストを選択して標準SQLとして貼り付けると、正しい場所に移動します。 –

1

また、次のようにISNULL(NULLIFの構文を使用できます。ただし、パフォーマンスに悪影響を与える可能性があるため、注意して使用してください。

where 
    SomeColumn = ISNULL(NULLIF(@variable1,''),SomeColumn) and 
    SomeColumn2 = ISNULL(NULLIF(@variable2,''),SomeColumn2) and 
    and so on.. 
+0

私はこれを試しましたが、残念ながらクエリの速度が大幅に遅くなりました。 –

関連する問題