SQL Server存储过程多个条件

时间:2015-03-16 21:31:24

标签: sql sql-server linq tsql

我在C#中有这个LINQ,我必须转换为SQL查询。而且我不确定如何根据条件进行多重过滤:

var geofenceReport = companyContext.GeofenceSimpleReports.Where(x => x.EnterTime != null && x.ExitTime != null && x.MinutesInGeofence != null).AsQueryable();

if (model.GeofenceId != -1)
{
    geofenceReport = geofenceReport.Where(x => x.iGeofenceId == model.GeofenceId).AsQueryable();
}

if (model.AssetId != -1)
{
    geofenceReport = geofenceReport.Where(x => x.iAssetId == model.AssetId).AsQueryable();
}

if (model.CategoryId != -1)
{
    geofenceReport = geofenceReport.Where(x => x.iCategoryId == model.CategoryId).AsQueryable();
}

if (model.SiteId != -1)
{
    geofenceReport = geofenceReport.Where(x => x.iSiteId == model.SiteId).AsQueryable();
}

geofenceReport = geofenceReport
                   .Where(x => x.EnterTime >= model.StartDateTime && 
                          x.EnterTime <= model.EndDateTime) 
                   .AsQueryable();

所以这就是我在SQL中提出的:

我为AssetId创建了一个新类型:

USE myDatabase
GO

CREATE TYPE idTable AS TABLE (id INT)

然后在SQL中:

USE myDatabase
GO

CREATE PROCEDURE [dbo].[xPT_GetGeofenceSummaryReport]
    @iAssetIds idTable,
    @iGeofenceId INT,
    @iCategoryId INT,
    @iSiteId INT,
    @iAssetId INT
AS

IF @iAssetId != -1
    SELECT * FROM GeofenceSimpleReport WHERE iAssetId in (@iAssetIds)

IF @iGeofenceId != -1
    SELECT * FROM GeofenceSimpleReport where iGeofenceId = @iGeofenceId

IF @iCategoryId != -1
    SELECT * FROM GeofenceSimpleReport where iCategoryId = @iCategoryId

IF @iSiteId != -1
    SELECT * FROM GeofenceSimpleReport where iSiteId = @iSiteId

,此GeofenceSimpleReport是数据库视图。

但这不会起作用,因为它在逻辑上是错误的。这将从GeofenceSimpleReport中单独选择4个。

我需要从GeofenceSimpleReport读取所有过滤器。

我不想暂时将这些数据读入内存中的TABLE / LIST,因为有很多数据。

有没有办法像我在LINQ中那样动态编写这个查询?

1 个答案:

答案 0 :(得分:1)

您在程序上考虑这个问题,并通过一系列if语句,而不是将您的视图视为一组可以一次过滤的数据。

您可以过滤与EntryTime,ExitTime等相关的原始条件,然后为您提供可过滤值(而不是-1)的每个参数,然后确保Id与表中的该记录匹配。您为该值赋予-1的任何内容都将自动使AND语句为真。

我通过传递可以为空的参数来做这种事情 - 如果他们不是NULL然后我过滤它们 - 否则他们只评估到true并通过

USE myDatabase
GO

CREATE PROCEDURE [dbo].[xPT_GetGeofenceSummaryReport]
    @iAssetIds idTable,
    @iGeofenceId INT,
    @iCategoryId INT,
    @iSiteId INT,
    @iAssetId INT
AS
SELECT * 
   FROM GeofenceSimpleReport
   WHERE EnterTime IS NOT NULL 
   AND ExitTime IS NOT NULL
   AND MinutesInGeofence IS NOT NULL
   AND (@iAssetId = -1 OR iAssetId IN (@iAssetIds))
   AND (@iGeofenceId = -1 OR iGeofenceId = @iGeofenceId)
   AND (@iCategoryId = -1 OR iCategoryId = @ICategoryId)
   AND (@iSiteId = -1 OR iSiteId = @iSiteId)