如何根据值使用或忽略SQL存储过程中的参数

时间:2017-02-08 21:39:43

标签: sql asp.net

我在前端有几个带有项目值对的下拉列表。让我们在第一个ddl(动物)中说 - 狗有值1,猫 - 2,ANY - 0,在第二个ddl(颜色) - 黑色有值1,白色 - 2和ANY - 0。 / p>

此外,我想使用存储过程通过下拉列表中选择的值从db中选择数据。

因此,仅在值为!= 0时才应过滤结果。如果为0,则不应过滤结果。 我能想象的最好的解决方案是在代码端创建SELECT查询(没有SP):

string animalParam = ddl_animal.SelectedValue.Equals("0") ? "1 = 1" : $" animal_id={ddl_animal.SelectedValue}";
string colorParam = ddl_color.SelectedValue.Equals("0") ? "AND 1 = 1" : $"AND color={ddl_color.SelectedValue}";

string query = $"SELECT * FROM table WHERE {animalParam} {colorParam}";

但它足够好吗?或者有更好的方法来做到这一点,例如在SP方面?以某种方式使用默认值? 提前谢谢!

1 个答案:

答案 0 :(得分:1)

您的解决方案应该可行,但如果您愿意,也可以将逻辑移动到SQL中:

CREATE PROCEDURE dbo.FilterByColorAndAnimal
(
    @AnimalId INT = 0,
    @ColorId INT = 0
)
AS
BEGIN
    DECLARE @SQL = N'
        SELECT * 
        FROM table W
        WHERE 1 = 1'

    IF (@AnimalTypeId <> 0) SET @SQL = @SQL + ' AND animal_id = @AnimalId'
    IF (@ColorId <> 0) SET @SQL = @SQL + ' AND color_id = @ColorId'

    EXEC sp_executesql @SQL, '@AnimalId INT, @ColorId INT', @AnimalId, @ColorId
END
GO

备选方案:

  • 不要使用动态SQL,而是涉及OR的更复杂的查询

    SELECT * 
    FROM table W
    WHERE (@AnimalId = 0 OR animal_id = @AnimalId)
        AND (@ColorId = 0 OR color_id = @ColorId)
    
  • 将LINQ2SQL与EntityFramework一起使用

    var query = context.Table;
    int animalId = Convert.ToInt32(ddl_animal.SelectedValue);
    if (animalId != 0)
        query = query.Where(item => item.animal_id = animalId);
    int colorId = Convert.ToInt32(ddl_color.SelectedValue);
    if (colorId != 0)
        query = query.Where(item => item.color_id = colorId);
    

这将生成最有效的查询(类似于您的初始解决方案)。