Sql 处理表格参数中存在的不同条件,使其作为“和”而不是“或”

Sql 处理表格参数中存在的不同条件,使其作为“和”而不是“或”,sql,cross-join,Sql,Cross Join,我有一个页面,用户可以在其中动态添加搜索条件以过滤掉记录。 我将这些条件发送到TVP中的存储过程。 现在,我需要编写一个查询,将这些过滤器用作和,而不是OR 考虑一个student表的示例 ID Name Marks ----------- --------- ------- 2 bab 65 4 bad 75 6 baf 85 当我发送列和

我有一个页面,用户可以在其中动态添加搜索条件以过滤掉记录。 我将这些条件发送到TVP中的存储过程。 现在,我需要编写一个查询,将这些过滤器用作和,而不是OR

考虑一个student表的示例

ID          Name         Marks
----------- ---------    -------
2           bab          65
4           bad          75
6           baf          85
当我发送列和运算符的ID时,我得到了在TVP中存储proc的条件,但为了清楚起见,我在本例中使用了列名称和运算符

 Column     Operator    Value
----------- ---------   -------
Name        Contains    a
Marks       >=          75
现在我需要使用这个TVP从student表中过滤出记录,在这个示例中,student表的最后2行将显示给用户

有人能帮我写一个查询吗?我试着在学生表和TVP之间进行交叉连接,但查询是ORing而不是在TVP中对条件进行ANDing

示例查询:


您需要执行以下操作:

将初步查询创建为字符串,缺少where参数:query='select*from student where xxx order by name,marks'。我们将用适当的内容替换xxx。 为查询部分创建一个变量,其中_part= 使用光标遍历TVP中的每一行 对于TVP中的每一列、运算符、值,构建一个类似name+operator+value+'and'的字符串,并将其附加到where_部分。 处理完TVP中的所有行后,删除最后一个“and”,即“condition and condition and condition and”。 将查询中的“xxx”替换为where\u部分 跑exec@querytsql,其他数据库有不同的语法。有关存储过程中的动态sql,请参见和google。
无需在任何地方加入即可完成所需操作。你可能做错了。你能给我们看看你已经有的代码吗?我使用交叉连接的方法可能是错误的。如果方法本身是错误的,你能建议我解决这个问题的正确方法吗?@Irfy:添加了我方法的示例查询,你能建议我正确的方法吗?谢谢Irfy的方法,但是u建议的方法是使用游标和动态SQL,这会影响查询执行时间,因为不存在适用于动态SQL的查询计划缓存。在不使用动态SQL的情况下,我们能做些什么来解决这个问题吗?不,不幸的是不能。构建动态where子句的需求需要动态SQL查询。但是想想看:当用户首先必须手动和动态地构建查询时,您真的需要一个具有缓存查询计划的高性能查询吗?在我看来,性能损失是可以忽略的,因为查询将一次又一次地动态创建-无论如何,您都无法预测和缓存此类查询的计划。嗯。。我同意u和标记作为答案,再次感谢:如果您将以这种方式搜索的表的数量限制为1-2个表,并将这些表的列限制为几列,然后严格限制可用的运算符,以便只匹配几个预定义的用例,您可能会得到一个巨大的参数化查询缓存,您可以根据TVP内容选择并参数化这些查询。我想用tvp内容作为键的哈希表,但这会很难看,而且限制太多。另请参阅。我将尝试在另一个答案中详细说明一个抽象的可缓存解决方案
    DECLARE @tmpCond TABLE
(
    ColumnId SMALLINT,
    OperatorId SMALLINT,
    Value VARCHAR(10)
)

INSERT INTO @tmpCond
        ( ColumnId ,
          OperatorId ,
          Value
        )
VALUES  ( 1,1,'a')
        ,(2,2,'75')

SELECT * FROM dbo.Student A
CROSS JOIN @tmpCond B
WHERE 
    (B.ColumnId = 1 AND B.OperatorId = 1 AND A.NAME LIKE '%'+B.Value+'%')
    OR
    (B.ColumnId = 2 AND B.OperatorId = 2 AND A.Marks >= B.Value)