存储过程中的多个条件连接

时间:2018-03-06 22:22:51

标签: tsql sql-server-2016

我有一个搜索程序,我们正在从动态SQL转换。我们接近完成但我们有一个问题。

我们有一堆标准字段,可能由用户提供,也可能不提供。如果没有提供它们,我们想完全忽略该表。如果他们被提供,我们需要加入该表。

在动态SQL中,我们将构建一个大型动态SQL语句并将它们全部附加在一起以供执行。所以它想这样:

IF @bColorMatch = 1  
   SET @sqlFROM = @sqlFROM + '
            JOIN tProductColors ON tProducts.pid=tProductColors.pid  '

   SET @sqlWHERE = @sqlWHERE + '  
            AND tProductColors.pc_color like ''blue'' '   

现在我们已经淘汰了动态SQL,我们正在尝试这些方面。我知道我们不能这样做,但我们正在寻找类似于这种逻辑的东西。

SELECT 
    p.pid, p.model, pc.pc_color
FROM 
    tProducts
    CASE @bColorMatch
         WHEN 1
            THEN JOIN tProuductColors 
                ON tProducts.pid=tProductsColors.pcid
                   AND pc_Color like '%blue%'
    END

我知道我可以将ENTIRE语句放入一个大型交换机中,然后只写两个。一个变量为真时包含JOIN,何时变量为真。但是,一次调用中有十几个这些标准字段。循环这么多可能性是不切实际的。

我们只是将LEFT JOIN连接到所有表格,但是如果我们不必要,那么就会有很多开销。还有另一种解决方法吗?

1 个答案:

答案 0 :(得分:0)

您的动态示例似乎没有将pc_color添加到选择列表中。如果您不需要,则可以使用WHERE

创建EXISTS条件
SELECT p.pid, p.model
FROM tProducts p 
WHERE @bColorMatch = 0 OR EXISTS (
    SELECT NULL FROM tProuductColors
    WHERE pcid = p.pid
    AND pc_Color = 'blue'
)

我使用8 tProducts和8 tProuductColors设置了一个测试,以获得实际执行计划,@bColorMatch = 0时似乎没有开销。结果如下:

@bColorMatch = 0实际执行计划

@bColorMatch = 0 actual execution plan

@bColorMatch = 1实际执行计划

@bColorMatch = 1 actual execution plan