2

これらの列を持つ車のテーブルがあります。

ID
BrandID
ModelID
ColorID
ProductionYear
Price
IsSecondHand
.
.
.

ブランド、モデル、色などには独自のテーブルがあります。

ユーザーには幅広いフィルタリングオプションがあります。つまり、すべてのフィルターはオプションであり、ユーザーはブランド、モデル、色などを選択する場合と選択しない場合があります。製造年の範囲、価格の範囲を選択できます。また、フィルターによっては複数の値を持つものもあります。たとえば、ユーザーは赤または白の車を表示することを選択できます。または、複数のモデルをフィルタリングすることを選択できます。

結果を返すストアド プロシージャを作成したいと考えており、パフォーマンスの良い簡単なコードを作成する方法を見つけたいと考えています。手順で 1000 の if 句を使用したくありません。

何か案は?

4

2 に答える 2

3

クエリが多数の異なる列に依存する可能性がある場合、適切な単一の T-SQL ステートメントはありません。まともな実行計画のようなものを得るには、必要な正確な組み合わせを対象とする T-SQL が必要です。これを行う方法は、SQL を動的に構築することです。

次の 3 つのオプションがあります。

  • ストアド プロシージャ内で T-SQL を生成し、それを使用sp_ExecuteSQLして実行します (正しいパラメーター化とクエリ プランの再利用を維持します)。
  • そもそもストアド プロシージャを使用しないでください。C# で T-SQL を生成して実行します。
  • ORMを使用する

最初のオプションは実行可能ですが、苦痛です。T-SQL は、実際にはこれを意図したものではありません。しかし、あなたはそれを行うことができます。例(省略):

declare @tsql nvarchar(4000) = 'select * from foo ...'
if @name is not null
    set @tsql = @sql + ' and Name = @name'
if @region is not null
    set @tsql = @sql + ' and Region = @region'
-- ...
exec sp_executesql @tsql,
        N'@name nvarchar(50), @region int`,
        @name, @region

C#オプションはStringBuilder、必要な句とパラメータを追加するだけで、IMO-通常は経由ではるかに簡単です。

最後に、ORM (この場合は LINQ プロバイダー) を使用します。

IQueryable<Foo> foos = ctx.Foos;
if(name != null) foos = foos.Where(x => x.Name == name);
if(region != null) foos = foos.Where(x => x.Region == region);
// ...
于 2013-09-18T09:55:02.577 に答える
2

以下のようなストアドプロシージャを作成してみてください

    @BrandID INT,
    @ModelID INT
AS
    SELECT columns...
    FROM TABLE TB
    WHERE (@BrandID = 0 OR (TB.BrandID = @BrandID ))
      AND (@ModelID = 0 OR (TB.ModelID = @ModelID ))

コード ビハインドから SQL を生成することもできます。必要な条件だけを入れることができるので

アップデート

ユーザーが 1 つのパラメーターに対して複数の値を選択できる場合は、SQL IN 句またはテーブル値パラメーターのパラメーター化を使用することをお勧めします。

于 2013-09-18T09:51:09.120 に答える