【问题标题】:Get report parameters as URL string获取报告参数作为 URL 字符串
【发布时间】:2018-08-01 17:35:02
【问题描述】:

我有一个提供 SSRS 报告的应用程序。通过以下方式访问给定的报告:

https://reportserver.com/reportname

单击查看报告后,将使用用户定义的参数将回发提交到报告服务器。我需要抓取这些用户定义的参数并将它们解析为 URL 字符串。

想要的结果: https://reportserver.com/reportname?param1=foo&param2=bar

我找到了this doc,这让我接近了我需要的东西。这个方法应该允许我获取所有可见参数并自己解析它们,但我也需要隐藏参数

如何构建这个参数字符串?我们在前端使用 JavaScript/jQuery,因此可能会在 POST 之前抓取这个客户端,但我也没有找到这样做的方法。

【问题讨论】:

  • 你能解释一下你为什么要关注参数吗?是为了解决用户问题吗?你想看看哪些参数值被使用得最多?
  • 当然。我想为用户提供一种方法来使用他们的参数为报表添加书签,我正在使用一个按钮来实现这一点,该按钮是报表本身的 href 并附加了查询字符串。然后他们可以保存该链接以供将来使用。
  • 这里是使用 3 选项的报告中的执行日志示例。 github.com/SQL-Server-projects/Reporting-Services-examples/blob/…
  • 您可以设置报表以按当前用户过滤
  • 我还会使用功能帐户来运行数据集,因为用户无权查询报表服务器。

标签: javascript jquery asp.net vb.net reporting-services


【解决方案1】:

我让它工作了。公平警告:我是 ASP.NET 新手,所以这可能不是一个理想的解决方案。

我在报表查看器控件的代码后面添加了一个事件处理程序。这会查询执行日志,获取用户最近选择的参数。当单击一个名为“保存报告”的按钮时会触发它。如果您尝试使用 LoadPreRender 事件处理程序来处理此问题,它将在该行有机会插入数据库之前触发,从而为您提供用户第二个最近执行参数的结果。

定义按钮(.ascx 文件)

  <asp:LinkButton ID="SaveReportButton" runat="server" title="Save this Report"></asp:LinkButton>

将事件处理程序添加到代码后面(.ascx.vb 文件)

Protected Sub SaveReportButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveReportButton.Click
  Dim conn As New SqlConnection(<connection string here>)
  Dim cmd As New SqlCommand("SELECT TOP 1 Parameters FROM [ReportServer].[dbo].[ExecutionLogStorage] WHERE <qualify on user, timestamp, etc. here>", conn)
  cmd.Parameters.AddWithValue(<query parameter here>)
  conn.Open()
  Dim result = cmd.ExecuteScalar()

  ' Prevents NullReferenceException from result.ToString() in case no result is found
  If (result IsNot Nothing)

    ' Redirect based on parameter string retrieved from log
    Response.Redirect(HttpContext.Current.Request.Url.AbsoluteUri & "?" & result.ToString())

  End If
  conn.Close()
End Sub

点击按钮时从 JavaScript 调用回发

<li>
  <a href=\'javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(<reference SaveReportButton with appropriate arguments>)\' id="SaveReportButton" title="Save Report">
  Save Report
  </a>
</li>

WebForm_DoPostBackWithOptions()WebForm_PostBackOptions() 上的文档很少,但一位同事已经这样做了,所以我照做了 为了保持一致性,因为它有效。

【讨论】:

    【解决方案2】:

    我用 3 种不同的方式为带有参数的报告创建了 URL。前两者的结合可能会让您更接近解决您的问题。

    在报告属性中使用自定义代码。

    Public Function ShowParameterValues(ByVal parameter As Parameter) As String  
    Dim s as String = String.Empty 
        Try
           If parameter.IsMultiValue then  
              s = "Multivalue: "   
              For i as integer = 0 to parameter.Count-1  
                 s = s + CStr(parameter.Value(i)) + " "   
              Next  
           Else  
              s = "Single value: " + CStr(parameter.Value)  
           End If  
           Return s  
    
        Catch ex As Exception
            Return "error"
    
        End Try
    
    End Function  
    

    在报告中使用超链接。

    =Globals!ReportServerUrl + "/ReportServer?" 
     + Replace(Globals!ReportFolder, " ", "+") + "%2f" 
     + Replace(Globals!ReportName, " ", "+") + "&rs:Command=Render"
     + "&boolean_value=" + CStr(Parameters!boolean_value.Value)
     + "&single_value_parameter=" + Parameters!single_value_parameter.Value 
     + "&multi_value_parameter=" + Join(Parameters!multi_value_parameter.Value, "&multi_value_parameter=") 
     + IIf(IsNothing(Parameters!week_date_start.Value), "&week_date_start:isnull=True", "&week_date_start=" & Format(Parameters!week_date_start.Value, Variables!FormatDate.Value))
     + IIf(IsNothing(Parameters!week_date_end.Value), "&week_date_end:isnull=True", "&week_date_end=" & Format(Parameters!week_date_end.Value, Variables!FormatDate.Value))
    

    另外,我通常将其添加为报表变量,然后您可以为无需更改的页脚创建一个标准文本框。

    =Variables!UrlReportWithParameters.Value
    

    使用执行日志。查看专栏URL_Report_Filtered

    --Purpose:  to search the reporting services execution log
    
    DECLARE @all_value AS VARCHAR(10) = '<ALL>';
    DECLARE @LogStatus AS VARCHAR(50) = '<ALL>';
    DECLARE @ReportFolder AS VARCHAR(450) = 'Testing';
    DECLARE @ReportName AS VARCHAR(450) = '<ALL>';
    DECLARE @UserName AS VARCHAR(260) = '<ALL>';
    DECLARE @GroupByColumn AS VARCHAR(50) = 'Report Folder';
    DECLARE @StartDate AS DATETIME = NULL;
    DECLARE @EndDate AS DATETIME = NULL;
    
    WITH
    report_users 
    AS
    (
        SELECT 
              [UserID]
            , [UserName]
            , [SimpleUserName] = UPPER(RIGHT([UserName], (LEN([UserName])-CHARINDEX('\',[UserName])))) 
        FROM 
            [dbo].[Users]
    )
    ,
    report_catalog
    AS
    (
        SELECT    
              rpt.[ItemID]
            , rpt.[CreatedById]
            , rpt.[ModifiedById]
            , rpt.[Type]
            , rpt.[Name] 
            , [ReportName] = rpt.[Name] 
            , rpt.[Description]
            , rpt.[Parameter]
            , [CreationDate] = CONVERT(DATETIME, CONVERT(VARCHAR(11), rpt.[CreationDate], 13))
            , [ModifiedDate] = CONVERT(DATETIME, CONVERT(VARCHAR(11), rpt.[ModifiedDate], 13))
            , [ReportFolder] = SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2) 
            , rpt.[Path]
            , [URL_ReportFolder] = 'http://' + Host_Name() + '/Reports/Pages/Report.aspx?ItemPath=%2f'  + SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2)  + '&ViewMode=List'
            , [URL_Report] = 'http://' + Host_Name() + '/Reports/Pages/Report.aspx?ItemPath=%2f'  + SUBSTRING(rpt.[Path], 2, LEN(rpt.[Path])-LEN(rpt.[Name])-2)  + '%2f' + rpt.[Name]
            , [ReportDefinition] = CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), rpt.[Content]))  
            , [HostName] = Host_Name()
        FROM 
            [dbo].[Catalog] AS rpt
        WHERE 
            1=1
            AND rpt.[Type] = 2
    )
    SELECT 
        [GroupBy1] = 
            CASE  
                WHEN @GroupByColumn = 'Report Name' THEN rpt.[ReportName]
                WHEN @GroupByColumn = 'Report Folder' THEN rpt.[ReportFolder]
                WHEN @GroupByColumn = 'User Id' THEN usr.[SimpleUserName]
                ELSE '<N/A>' 
            END
        , rpt.[Path]
        , rpt.[ReportFolder]
        , rpt.[Name]
        , rpt.[URL_ReportFolder]
        , rpt.[URL_Report] 
        , [URL_Report_Filtered] = rpt.[URL_Report] + '&rs:Command=Render&' + CONVERT(VARCHAR(max), el.[Parameters])
        , [UserName] = usr.[SimpleUserName]
        , el.[Status]
        , el.[TimeStart]
        , el.[RowCount]
        , el.[ByteCount]
        , el.[Format]
        , el.[Parameters]
        , [TotalSeconds] = CONVERT(CHAR(8),DATEADD(ms,(el.[TimeDataRetrieval] + el.[TimeProcessing] + el.[TimeRendering]),0),108)
        , [TimeDataRetrieval] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeDataRetrieval],0),108) 
        , [TimeProcessing] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeProcessing],0),108)  
        , [TimeRendering] = CONVERT(CHAR(8),DATEADD(ms,el.[TimeRendering],0),108) 
        , [OrderbyDate] = CAST([TimeStart] AS DATETIME) 
    FROM 
        report_catalog AS rpt 
        LEFT JOIN [dbo].[ExecutionLog] AS el ON el.[ReportID] = rpt.[ItemID]
        LEFT JOIN report_users AS usr ON el.[UserName] = usr.[UserName]
    WHERE 
        1=1
        AND (@all_value IN(@LogStatus) OR el.[Status] IN(@LogStatus))
        AND (@all_value IN (@ReportFolder) OR rpt.[ReportFolder] IN(@ReportFolder))
        AND (@all_value IN(@ReportName) OR rpt.[ReportName] IN(@ReportName))
        AND (@all_value IN(@UserName) OR usr.[SimpleUserName] IN(@UserName))
        AND (@StartDate IS NULL OR CONVERT(DATETIME, CONVERT(VARCHAR(11), el.[TimeStart], 13)) >= @StartDate)
        AND (@EndDate IS NULL OR CONVERT(DATETIME, CONVERT(VARCHAR(11), el.[TimeStart], 13)) <= @EndDate)
    

    【讨论】:

    • 我们有超过 1200 份报告,因此很遗憾,无法为每个报告添加自定义代码。我尝试使用共享数据集查询执行日志,但执行日志在该数据集运行后更新。
    • 由于我要处理的报告数量庞大,我最终不得不处理这个服务器端。但是,您的回答非常好,我当然赞成。感谢您引导我朝着正确的方向前进!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多