web-dev-qa-db-ja.com

存在する場合-繰り返しコードの防止を選択

注文リストを受け取り、それが特定のプレフィックスで始まることを確認します。たとえば、OrderNumberがABCで始まらない場合は、注文リストをユーザーにエラーとして表示します。私たちは存在を使用して、最初の存在を検索するために、多くのパフォーマンス時間を費やしたくありません。何も存在しない場合は、コードで他のタスクの実行を開始できます。

とにかくSQLで反復的なコードを取り除くためにありますか?コードをより効率的にするために、複数のテーブルでこのような多くのチェックを行っています。

if exists
(
    select *
    from dbo.OrdersImport
    where left(OrderNumber,3) <> 'ABC'
)
begin
    select OrderNumber as OrderErrorList
    from dbo.OrdersImport
    where left(OrderNumber,3) <> 'ABC'
end
else
1
user129291

残念ながら、コードの繰り返しを防止しようとすると、コードが多くなり、クエリが読みにくくなる可能性があります。しかし、これはあなたにとって有利であると思います-テストで1つまたは2つのテーブルを検索するだけでよく、すべての詳細を取得するためにさらにいくつかに結合する必要がある状況を考慮してください。これらの状況では、テストクエリを簡略化して、実行を高速化することもできます。

また、その間、WHEREステートメントを変更することも検討してください。述語で関数を使用すると、関数はSARG可能ではなくなり、そのような場合にインデックスを使用できなくなります。この例でのより良いアプローチはチェックすることです

WHERE OrderNumber LIKE 'ABC%'

オプティマイザが次のように何かに変換するので

OrderNumber >= 'ABC' AND OrderNumber < 'ABD'

インデックスの使用をサポートします。したがって、これはインデックススキャン(left()を使用)とインデックスシーク(LIKEを使用)になります。

4

残念ながら、(レガシーだけでなく)さまざまな理由により、SQLにはほとんどのクライアント言語が持つコード再利用オプションと機能のほとんどすべてがなく、それらの一部(スカラーUDFなど)には重大な問題があります。そのため、効果的なSQLプログラマーになりたい場合は、C#やVBなどのクライアント言語で考えているよりもはるかに多くのカットアンドペーストコードの再利用を行う必要があります。ネットまたはJava。

そうは言っても、あなたの例では冗長性を排除することができますが、それが実際に優れているかどうかにかかわらず、あなたは決める必要があります。

Declare @OrderErrorList Table(OrderNumber varchar(32));

Insert into @OrderErrorList 
select OrderNumber as OrderErrorList
from dbo.OrdersImport
where left(OrderNumber,3) <> 'ABC';

if exists
(
    select *
    from @OrderErrorList
)
begin
    select *
    from @OrderErrorList
end
else
2
RBarryYoung

とにかくSQLで反復的なコードを取り除くためにありますか?

いいえ、違います。 IFステートメントを使用せずに、次のようにクエリを再構成できますが、実際のクエリと違いはありません。

SELECT  *
FROM    dbo.OrdersImport o
WHERE   LEFT(OrderNumber, 3) <> 'ABC'
    AND EXISTS (
        SELECT *
        FROM dbo.OrdersImport
        WHERE LEFT(OrderNumber,3) <> 'ABC'
        AND ID = o.ID
        )
0
Russell Fox