注文リストを受け取り、特定のプレフィックスで始まることを検証します(たとえば、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つまたは2つのテーブルを検索するだけでよく、すべての詳細を取得するためにさらにいくつかに参加する必要がある状況を考慮に入れてください。このような状況では、テストクエリを簡略化して、実行を高速化することもできます。
その間、WHEREステートメントを変更することも検討してください。述語で関数を使用すると、それらはSARGableでなくなり、そのような場合にインデックスを使用できなくなります。この例でのより良いアプローチは、
WHERE OrderNumber LIKE "ABC%"
オプティマイザーが
これはインデックスの使用をサポートします。したがって、これはインデックススキャン(left()を使用)とインデックスシーク(LIKEを使用)になります。
回答
残念ながら、さまざまな理由(レガシーだけでなく)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
コメント
- 存在する代わりに@@ ROWCOUNTをチェックして、これをさらに単純化できますか?
- @mathewbはい。ただし、INSERT..SELECTの直後に実行する必要があります。別のステートメントを追加すると、突然正しく機能しなくなります。そのような地雷は避けようとしています。回避策は、@@ ROWCOUNTを変数に保存することですが、上記の場合よりも大幅に改善されることはありません。
回答
繰り返しコードを取り除くために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 )