【问题标题】:SSRS Report Parameters passed outSSRS 报告参数传递出去
【发布时间】:2017-01-04 14:58:43
【问题描述】:

我目前正在构建许多日志记录和分析工具来密切关注我们的 SQL 环境。我们目前使用的是 SQL Server 2014。

我想做的是检查白天传递给我们报告的所有参数。所有报表当前都在使用存储过程,因此在我的表中或基于表的 select 语句中,每次运行报表时都会输出带有参数的存储过程。

最后,我希望能够获取输出的语句并在 SSMS 中运行它,而无需使用报告。我一直在查看 ExceutionLogStorage 表和 ExecutionLog 视图,虽然它包含我需要的大部分信息,但参数并不处于易于使用的状态。

有人做过类似我描述的事情吗?

【问题讨论】:

    标签: reporting-services ssrs-2008 ssrs-2008-r2 ssrs-2012


    【解决方案1】:

    你需要在你原来的SP中添加日志部分,例如:

    Alter procedure a
    (@parameter)
    As
    Begin
    ..
    ..
    Insert into loggingTable(col)
    Values(@parameter)
    ..
    ..
    End 
    

    然后直接查询该 loggingTable 以获取使用参数的历史记录

    【讨论】:

    • 这假设存储过程只被报表执行调用
    • 嗨 Long,非常感谢您的回复,当所有参数已经存储在 ExecutionLogStorage 表中时,再次重新记录它们似乎很麻烦,即使它们不是以最容易使用的格式。我还有很多存储过程,我需要添加这个示例代码,这需要相当长的时间。
    • 希望这对您有所帮助:jegansubramaniam.blogspot.com/2012/02/…
    【解决方案2】:

    围绕该主题的 Google 搜索很快找到了以下 blog post 已被 OP 确定为有用并显示如下(此查询本身实际上是由 LONG 的以下答案链接到的工作的扩展)

      SELECT TOP 1 ParValue
      FROM (
        SELECT els.TimeEnd 
          , IIF(CHARINDEX('&' + 'ParameterName' + '=', ParsString) = 0, 'ParameterName',
            SUBSTRING(ParsString 
              , StartIndex
              , CHARINDEX('&', ParsString, StartIndex) - StartIndex)) AS ParValue
          FROM (SELECT ReportID, TimeEnd 
                , '&' + CONVERT(VARCHAR(MAX), Parameters) + '&' AS ParsString 
                , CHARINDEX('&' + 'ParameterName' + '=', '&' + CONVERT(VARCHAR(MAX), Parameters) + '&') 
                  + LEN('&' + 'ParameterName' + '=') AS StartIndex 
              FROM ExecutionLogStorage
              WHERE UserName='UserName' -- e.g. DOMAIN\Joe_Smith
              ) AS els 
            INNER JOIN [Catalog] AS c ON c.ItemID = els.ReportID
          WHERE c.Name = 'ReportName'
        UNION ALL
        SELECT CAST('2000-01-01' AS DateTime), 'ParameterName'
      ) i
      ORDER BY TimeEnd DESC;
    

    这两种方法虽然实际上只是给我们一个起点,因为它们(不同地)依赖于我们事先知道报告名称和参数名称。虽然我们可以快速对 Ken Bowman 的工作进行一些更改以使其针对所有报告的所有执行运行,但我们仍然存在查询硬编码参数名称的问题。

    执行报告所需的参数存储在参数列的目录表中。尽管该列的数据类型为 ntext,但它实际上存储的是 XML 字符串。这意味着我们可以使用XPath 查询来获取参数名称

    with
    CatalogData as (
        select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
        from Catalog
        where [Type] = 2),
    ReportParameters as (
        select ItemID, [Path], [Name], ParameterXml, p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
        from CatalogData
        cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
    select *
    from ReportParameters;
    

    执行此查询将列出服务器上的所有报告及其参数。现在我们只需要将它与 Ken Bowman 的查询结合起来。我采用了 CTE 方法

    with
    CatalogData as (
        select ItemID, [Path], [Name], cast(Parameter as xml) 'ParameterXml'
        from Catalog
        where [Type] = 2),
    ReportParameters as (
        select ItemID, [Path], [Name], p.value('Name[1]', 'nvarchar(256)') 'ParameterName'
        from CatalogData
        cross apply ParameterXml.nodes('/Parameters/Parameter') as Parameters(p))
    select
        els.TimeEnd
        , c.[Name]
        , rp.ParameterName
        , iif(
            charindex(
                '&' + rp.ParameterName + '=', ParametersString) = 0
                , rp.ParameterName, substring(ParametersString
                , StartIndex, charindex('&', ParametersString, StartIndex) - StartIndex
        )) 'ParameterValue'
    from (
        select
            ReportID
            , TimeEnd
            , rp.ParameterName
            , '&' + convert(varchar(max), Parameters) + '&' 'ParametersString'
            , charindex(
                '&' + rp.ParameterName + '=',
                '&' + convert(varchar(max), Parameters) + '&'
            ) + len('&' + rp.ParameterName + '=') 'StartIndex'
        from
        ExecutionLogStorage
        inner join ReportParameters rp on rp.ItemID = ReportID) AS els
    inner join [Catalog] c on c.ItemID = els.ReportID
    inner join ReportParameters rp on rp.ItemID = c.ItemID and rp.ParameterName = els.ParameterName;
    

    请注意,参数值作为 URL 的一部分传递给报告,因此您仍然需要摆脱文字空间编码等。此外,这(还...)不适用于多值参数。

    【讨论】:

    • 嗨,Paul,感谢您的回复,我确实在旅行中遇到了这段代码,并尝试运行它,但收效甚微,我删除了 where 子句以从我的 ExecutionLogStorage 中获取所有内容但继续返回一个名为 ParValue 的列,其记录值为 ParameterName。我还需要做些什么来完成这项工作,任何其他帮助都会很棒!
    • 所提供的查询是针对单个报告的最近执行的。要获取所有报告/执行,请删除“SELECT TOP 1 ParValue FROM (”,然后删除“WHERE c.Name...”子句之后的所有内容。您可能还会删除 UserName where 子句。当然我们是坚持使用每个报告中的参数名称。这些可以找到目录表的参数列。虽然 ntext 它实际上是 XML,所以可以查询。
    • 这是一个安静的早晨(员工/学生要到下周才能回来!),兴趣被激起了,所以我走得更远了。请参阅我修改后的答案以获取解决方案
    • 嗨,Paul,感谢您花时间协助解决此问题,我也与您的方向相同,但您的代码看起来更整洁。这确实是我想要的,但正如你所说,它不适用于多值参数,但它是一个很好的起点,会为我指明正确的方向,如果你想要完成代码的副本,请告诉我私信。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多