【问题标题】:SSRS - Ignore SQL Variables in my querySSRS - 在我的查询中忽略 SQL 变量
【发布时间】:2013-04-09 18:48:54
【问题描述】:

我有一个在 SQL 中运行良好的查询。当我尝试将其引入 SSRS 时,报告要求提供 4 个参数。其中两个参数/变量实际上是基于其他两个参数的:

DECLARE @Q int       --SET @Q = 1 -- Quarter 
DECLARE @Year int    --SET @Year = 2013

DECLARE @STARTDATE varchar(10)
SELECT @STARTDATE = D FROM (
    select case @Q
        when 1 then '1/1/' + convert(varchar(10),@Year)
        when 2 then '4/1/' + convert(varchar(10),@Year)
        when 3 then '7/1/' + convert(varchar(10),@Year)
        when 4 then '10/1/' + convert(varchar(10),@Year)
    end as D
    ) sd

DECLARE @ENDDATE varchar(10)
SELECT @ENDDATE = D FROM (
    select case @Q
        when 1 then '3/31/' + convert(varchar(10),@Year)
        when 2 then '6/30/' + convert(varchar(10),@Year)
        when 3 then '9/30/' + convert(varchar(10),@Year)
        when 4 then '12/31/' + convert(varchar(10),@Year)
    end as D
    ) ed

--(ADDITIONAL SQL CONTINUES USING ALL 4 PARAMETERS) ...

如何让 SSRS 只询问前两个参数(@Q@Year)并忽略 @StartDate@EndDate,因为它们是在查询中计算的?

【问题讨论】:

    标签: sql reporting-services parameters


    【解决方案1】:

    为查询中未在查询中声明的任何变量添加查询 SSRS 数据集的参数。

    但是一旦添加它们,它们并不总是自动删除,因此您可能需要从数据集查询中手动删除它们。

    例如,这个查询只会为@ParamOne 创建参数:

    DECLARE @StartDate, @EndDate DATETIME
    
    SET @StartDate = 'January 1, 2013'
    SET @EndDate = 'February 1, 2013'
    
    SELECT
       UserName,
       Action,
       DateOccurred
    FROM
       myTable
    WHERE
       DateOccurred BETWEEN @StartDate AND @EndDate
    AND UserName = @ParamOne
    

    但 SSRS 可能对大小写很挑剔。确保它们在您的声明和变量的使用之间匹配。

    【讨论】:

    • 只是想知道变量的静态值是否会使 SSRS 将其作为参数忽略?
    • 不,声明。映射可以是SELECT @StartDate = periodStart, @EndDate = periodEnd FROM periods p WHERE p.ID = @PeriodID,而@PeriodID 可以是唯一提交的SSRS 参数。(但@StartDate 和@EndDate 必须在查询中声明。)
    • 我必须同意普拉文。我的查询 DECLARE 是变量,SSRS 仍然将它们视为参数。
    • 声明和所有用途之间的大小写是否匹配,您是否在创建参数后从数据集中删除了参数? (不仅将它们从报告参数列表中删除,还从数据集属性的“参数”选项卡中删除)
    • 大小写匹配。当我从参数列表和数据集中删除它们时,报告处理过程中出现错误。
    【解决方案2】:

    每当您在 SSRS 中添加 select 语句时,如果您粘贴到 select 语句中,它通常会默认为您添加参数,例如:

    select thing 
    from table 
    where item = @Parm1
    

    然后它应该在“报表数据”下的报表设计器屏幕上显示“参数”文件夹。如果带有该值的参数不存在,则需要添加它才能使您的主体工作。 SSRS 中的参数选择与 SQL 中的不同。您可以在它们自己的部分中定义它们。

    如果您希望它忽略两个参数,为什么必须包含它们?这似乎有点违反直觉。你有两个选择:

    1. 在声明变量的地方,将参数的“默认值”设置为静态值。

    2. 将变量设置为“允许空值”并处理空引用。

    编辑(下面有 CTE):

    在 SSRS 中你不这样做(一般来说,有时你可能想要一个表变量,这很好或其他静态变量):

    Declare @Var int;
    
    select thing
    from table
    where item = @Var
    

    你只需这样做:

    select thing
    from table
    where item = @Var
    

    然后,您将“参数”作为具有类型和确定性结果的自己的属性来处理。

    我会在 SSRS 的数据集中这样做:

    with dates as 
    (
    select 
    case @Q
        when 1 then '1/1/' + convert(varchar(10),@Year)
        when 2 then '4/1/' + convert(varchar(10),@Year)
        when 3 then '7/1/' + convert(varchar(10),@Year)
        when 4 then '10/1/' + convert(varchar(10),@Year)
    end as StartDate
    ,   case @Q
        when 1 then '3/31/' + convert(varchar(10),@Year)
        when 2 then '6/30/' + convert(varchar(10),@Year)
        when 3 then '9/30/' + convert(varchar(10),@Year)
        when 4 then '12/31/' + convert(varchar(10),@Year)
    end as EndDate
    )
    select things 
    from mainbodytable, dates  -- CTE reference
    where date between StartDate and EndDate -- referenced from CTE above
    

    确保您在“Parameters”文件夹下看到为“Q”和“Year”列出的参数,并将它们设置为整数。当用户运行报告时,它会询问这些值,只要它们是范围内的合法值,他们就会确定数据集。 EG:它们不是将返回空值的无效值。

    【讨论】:

    • 你如何在以后的查询中引用 StartDate 和 EndDate?
    • 你需要问自己两件事:1.如果我能自己获取信息,我真的需要一个变量吗?2.这个变量是否需要被看到或者它是否多余。查看使用 CTE 的更新示例......
    • 我还要补充一点,将 SSRS 视为具有多个变量的复杂 SQL Management Studio 表达式,麻烦多于其价值。 RDL 语言(SSRS 的 xml 结构)本质上是将参数视为输入。您可以制作隐藏的和确定性的,但您可以在不设置太多的情况下完成很多工作,或者在 SQL Server 上创建一个执行所有复杂内部逻辑的过程,并且只需要传递一个或两个参数。
    【解决方案3】:

    保留报表中的参数,但给它们一个默认值并将它们设置为隐藏。

    查询运行时,代码将覆盖 @STARTDATE@ENDDATE 值,因此默认值无关紧要。

    【讨论】:

      【解决方案4】:

      您是否将查询放入存储过程中? (如果你不是,你应该这样做,这只是一个好习惯)。如果您使用 proc,则可以只有两个输入变量,然后根据需要声明尽可能多的其他内部变量。

      【讨论】:

      • 我不打算创建存储过程,但如果我需要的话。
      • @ajspacemanspiff:这是最佳实践。尤其是当您想开始在数据库中搜索某些东西时(例如是否有任何东西使用某个表?),如果它在数据库端,则更容易找到这些东西。
      • 将查询留在报告中通常更可取:然后可以将报告从测试独立提升到生产,或者可以针对生产数据库运行报告的测试修订版。我倾向于尝试将 SQL 保留在报告中,但我知道两者都可以。
      • @JamieF:是​​的,您可以更轻松地推动新环境,但在 proc 中这是一种更好的做法。跟踪我在数据库方面出现的问题要容易得多(尝试进行一些数据库清理,你就会明白我的意思)。
      • 我还是不同意。根据我的经验,这使得数据库清理变得更加困难:您现在必须跟踪哪些报告正在使用哪些存储过程。
      【解决方案5】:

      将过程包装成nvarchar(max)变量然后执行:

      declare @statement nvarchar(max)
      set @statement='....
      '
      
      exec sys.execsql(@statement)
      

      【讨论】:

        【解决方案6】:

        我认为这是不可能的,因为 SSRS 创建了一个 dynamic 查询并将所有变量转换为参数。所以 AFAIK 唯一的选择是将查询包装在 stored procedure

        【讨论】:

        • 对不起,但我确定你错了。我经常在我的 SSRS 中的 SQL 查询中包含不是存储过程的变量。
        • 当你在查询中使用@ 符号时,我认为这是不可能的。你能告诉我一个这样的查询吗?
        • @praveen:我会给你一票。应该没有理由将报告查询隐藏到报告文件中。将其放入 proc 中是一种更好的做法。
        猜你喜欢
        • 1970-01-01
        • 2018-09-02
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多