【问题标题】:Filter sql server table rows using many filters使用许多过滤器过滤 sql server 表行
【发布时间】:2011-03-23 17:55:10
【问题描述】:

我有一个名为 Student 的表,其中包含很多外键,用于过滤学生(表行)。

这个表的结构是这样的:

  StudentId   GenderId  DegreeId   NatioanlityId
       1            2          2           3
       ....

由于学生可以说一种或多种语言,因此学生表链接到这样的语言表

      StudentId LangaugeId
        1         1
        1         2
        1         3

学生可以选择一门或多门考试科目:

      StudentId      ExamId
       1              1
       1              2
       .... 

在我的 asp.net 页面中,我想使用 ajax 通过复选框过滤学生 例如,具有 1 级的女性和男性性别的学生,说语言 1,2 ......我使用用户定义的表过滤存储过程中的行,我必须使用很多这样的 IF 语句 if(EXISTS(SELECT GenderId FROM @GenderTable))

         if(EXISTS(SELECT DegreeId FROM @DegreeTable))

         if(....)
        else
         if(...)

如何避免所有 IF 语句?我有超过 5 个过滤器。这很无聊。有人有什么想法吗?

提前致谢。

【问题讨论】:

  • 为什么你有一个“性别”的查找表?
  • 您是通过查询数据库生成复选框选项,还是在页面上硬连线?此外,对于语言,您似乎希望能够检查一种以上的语言。如果选中了多种语言,这是否意味着您要选择会说两种语言的学生?
  • 没错,乔尔。学生可以被一种或多种语言过滤。问题是可能没有性别检查:仅按语言过滤,如果检查性别,则检查学位,将存储过程中的过滤器与连接结合起来......你看到了吗?
  • @Joel :通过查询 DB。实际上,过滤器用于获取与我的过滤器匹配的学生数量。
  • 让我考虑一下。在我几年前参与的一个项目中,我们遇到了类似的 SQL 过滤问题,但你的问题有点复杂。 (我们必须处理多个过滤器,在某些过滤器中可能没有检查任何项目。但我认为我们不能在给定的过滤器中检查多个项目。)

标签: c# jquery asp.net sql-server tsql


【解决方案1】:

我假设您的查询返回了符合条件的学生列表?如果是这样的话,一种方法是按照这种格式构建一个 where 子句

Where 
    (@Param1 IS NULL OR Field1 = @Param1)
    AND (@Param2 IS NULL OR Field2 = @Param2)

这可能会变得丑陋,并且可能效果不佳,具体取决于可能使用的过滤器数量与使用的过滤器数量以及索引的构建方式。

另一种选择是使用动态 SQL。您可以在 .net 代码或 SQL 存储过程中生成它。基本上以如下方式结束:

Set @Query = /* base select statement */
If @Param1 IS NOT NULL
    Set @Query = @Query + 'AND Field1 = @Param1'
If @Param2 IS NOT NULL
    Set @Query = @Query + 'AND Field2 = @Param2'
Exec sp_executesql @Query, @ParamList, @Param1, @Param2

这可能会变得更难阅读和调试,但它通常会表现得更好,因为您只查看实际过滤的字段。但是,如果您使用动态 SQL,则需要注意一些关键点,注入攻击位于列表顶部。 http://www.sommarskog.se/dynamic_sql.html 是关于动态 SQL 应该和不应该做什么的好资源。

【讨论】:

  • 一个好的开始,但它不处理多值过滤器。例如,考虑您有一个过滤器的情况,它只选择那些会说英语和西班牙语的学生。对于给定的学生,您无法查看单个字段来确定他/她是否会说两种语言。
  • 没错,我忽略了这一点。我之前处理该要求的方法是在 .net 中构建一个分隔字符串,通过 SQL 中的拆分函数运行它,然后使用“内连接”或“IN”标准填充匹配的行。如果您的目标是找到拥有所有已检查项目而不是任何已检查项目但仍然可行的人,则变得更加狡猾。
  • @Joel 如果选择了多个语言,我可以使用用户定义的表格类型。
  • 感谢 Rozwel。动态 sql 的解决方案适合我的情况
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 2021-08-02
相关资源
最近更新 更多