我目前正在构建一些日志记录和分析工具来密切关注我们的SQL环境。我们目前正在使用SQL Server 2014。
我想要做的是检查白天传递给我们报告的所有参数。所有报告当前都在使用存储过程,所以在我的表中或基于表的select语句输出存储过程时每次运行报告时都带有参数。
在一天结束时,我希望能够获取输出的语句并在SSMS中运行它,而不必使用该报告。我一直在查看ExceutionLogStorage表和ExecutionLog视图,虽然它有我需要的大部分信息,但参数不是一个易于使用的状态。
有没有人做过类似于我描述的事情?
答案 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的一部分传递给报表,因此您仍然需要删除文字空间编码等。此外,这(但......)不适用于多值参数。