SSRS报告参数传出

时间:2017-01-04 14:58:43

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

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

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

在一天结束时,我希望能够获取输出的语句并在SSMS中运行它,而不必使用该报告。我一直在查看ExceutionLogStorage表和ExecutionLog视图,虽然它有我需要的大部分信息,但参数不是一个易于使用的状态。

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

2 个答案:

答案 0 :(得分:0)

您需要在原始SP中添加日志记录部分,例如:

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

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

答案 1 :(得分:0)

围绕此主题的谷歌搜索很快将OP已经识别的以下blog post显示为有用且如下所示(此查询本身实际上是与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的工作进行一些更改以使其针对所有报告的所有执行运行,但我们仍然遇到查询硬编码参数名称的问题。

执行报告所需的参数存储在Parameter列的Catalog表中。尽管该列具有数据类型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的一部分传递给报表,因此您仍然需要删除文字空间编码等。此外,这(但......)不适用于多值参数。