【问题标题】:SSRS: Change SQL Statement DynamicallySSRS:动态更改 SQL 语句
【发布时间】:2010-09-13 08:38:26
【问题描述】:

我在 SSRS 2005 中有一份基于与此类似的查询的报告:

SELECT * FROM MyTable (NOLOCK) 
WHERE col1 = 'ABC'
AND col2 LIKE '%XYZ%'

我需要能够根据用户是否选中复选框在查询中动态包含 WHERE 子句的 AND 部分。基本上,这是一个动态 SQL 语句,这就是问题所在。我尝试了几种方法都无济于事。这可能吗? SSRS 2005 是否支持动态 SQL?谢谢!

【问题讨论】:

    标签: sql-server tsql reporting-services reportingservices-2005


    【解决方案1】:

    查尔斯几乎答对了。

    应该是:

    SELECT * FROM MyTable (NOLOCK) 
    WHERE col1 = 'ABC'
       AND (@checked = 0 OR col2 LIKE '%XYZ%')
    

    这是 SQL 中用于条件谓词的经典“模式”。如果@checked = 0,那么它将返回与谓词其余部分匹配的所有行(col1 = 'ABC')。 SQL Server 甚至不会处理OR 的后半部分。

    如果是@checked = 1,那么它将评估OR 的第二部分并返回匹配col1 = 'ABC' AND col2 LIKE '%XYZ%' 的行

    如果您有多个条件谓词,可以使用此方法将它们链接在一起(而 IF 和 CASE 方法很快就会变得难以管理)。

    例如:

    SELECT * FROM MyTable (NOLOCK) 
    WHERE col1 = 'ABC'
        AND (@checked1 = 0 OR col2 LIKE '%XYZ%')
        AND (@checked2 = 0 OR col3 LIKE '%MNO%')
    

    不要使用动态 SQL,不要使用 IF 或 CASE。

    【讨论】:

    • 是的,我不能遵守动态 SQL,很难调试、维护或升级。如果您有大量可选参数,则会有一些小的性能改进,但即使有多达 30 个参数,我也能在不使用它的情况下获得良好的性能。
    • 更不用说从安全 PoV 来看它有多危险
    • 优秀的答案
    【解决方案2】:

    这个怎么样。 @checked 是你的位变量。

    SELECT * FROM MyTable (NOLOCK) 
    WHERE col1 = 'ABC'
    AND (@checked <> 0 and col2 LIKE '%XYZ%')
    

    编辑:另外,如果您不使用存储过程,请使用一个。

    【讨论】:

    • 检查为假(0)的情况下不起作用。在这种情况下,它不会返回任何匹配项,即使可能存在一些匹配项。
    • 您的回答很好,但是在我们无法在数据源上执行并且我们对数据具有只读访问权限的情况下,存储过程方法将不起作用。
    【解决方案3】:

    也许这对你有用:

    if @checked = 1
        select * from mytable (nolock) where col = 'ABC'
    else
        select * from mytable (nolock) where col = 'ABC' AND colw Like '%XYZ%'
    

    很抱歉,我不怎么使用 SSRS,但是如果您可以将复选框的值放入 @checked 参数中,这应该可以工作。

    您也可以使用 CASE WHEN 语句。

    【讨论】:

    • 在 SQL Server 中,这可能会导致查询计划重新编译,从而损害性能。如果您在自己的过程中使用此模式,请考虑拆分以便拥有主过程,主过程根据参数选择要调用的子过程 - 一个过程一个查询。
    【解决方案4】:
    SELECT * FROM MyTable (NOLOCK) 
    WHERE col1 = 'ABC'
    AND col2 LIKE CASE @checked WHEN 1 THEN '%XYZ%' ELSE col2 END
    

    【讨论】:

      【解决方案5】:

      这将在 SSRS 2000 中工作,但用作最后的手段。

      (错误的)伪代码

      ="SELECT * FROM MyTable (NOLOCK)
      WHERE col1 = 'ABC'"+
      iff(condition,true,"AND col2 LIKE '%XYZ%'","")
      

      查看Executing "Dynamic" SQL Queries。从 Hitchhiker's Guide to SQL Server 2000 Reporting Services

      【讨论】:

        【解决方案6】:

        执行此操作的一种方法是将 SSRS 查询生成为表达式。在 BIDS 报告设计器中,像这样设置您的查询:

        ="SELECT * FROM MyTable WITH (NOLOCK) WHERE col1 = 'ABC'" +
         Iif(Parameters!Checked.Value = true," AND col2 LIKE '%XYZ%'","")
        

        【讨论】:

          【解决方案7】:

          如果您可以使用存储过程,那么在此操作可能会更容易。传入你的参数。根据您的条件创建一个 SQL 字符串并对 sql 字符串执行 EXEC,您的存储过程将返回您需要的结果。

          【讨论】:

          • 您的回答很好,但是在我们无法在数据源上执行并且我们对数据具有只读访问权限的情况下,存储过程方法将不起作用。
          【解决方案8】:

          您也可以采取另一种方法,使用 Exec 函数:

          DECLARE @CommonSelectText varchar(2000)  
          DECLARE @CompleteSelectText varchar(2000)  
          SELECT @CommonSelectText = 'SELECT * FROM MyTable (nolock) Where Col = ''ABC'' '  
          
          IF @checked = 1   
              SELECT @CompleteSelectText = @CommonSelectText + ' AND ColW LIKE ''%XYZ%'' '  
          ELSE  
              SELECT @CompleteSelectText = @CommonSelectText  
          
          EXEC (@CompleteSelectText)  
          
          GO  
          

          注意使用两个撇号' 来标记引用的文本。

          【讨论】:

            猜你喜欢
            • 2017-08-23
            • 2014-09-08
            • 2018-02-28
            • 1970-01-01
            • 2013-04-30
            • 1970-01-01
            • 1970-01-01
            • 2020-09-09
            • 1970-01-01
            相关资源
            最近更新 更多