查询DataCollector syscollector_collection_items XML

时间:2016-12-06 11:39:43

标签: sql sql-server xml

我正在尝试从MSDB上的表syscollector_collection_items中查询参数列上的XML。

我的问题是,当我查询下表时,

select 
--ci.parameters.value('(.)[5]','varchar(100)') AS [Parameters],
ci.parameters.query('(/)') AS [Parameters]
FROM
msdb.dbo.syscollector_collection_sets AS cs
INNER JOIN msdb.dbo.syscollector_collection_items AS ci ON ci.collection_set_id=cs.collection_set_id
INNER JOIN msdb.dbo.syscollector_collector_types AS ct ON ct.collector_type_uid = ci.collector_type_uid
WHERE cs.is_system <> 1
FOR XML AUTO

我得到了以下结果,

<cs>
  <Parameters>
    <ns:PerformanceCountersCollector xmlns:ns="DataCollectorType">
      <PerformanceCounters Objects="LogicalDisk" Counters="Avg. Disk sec/Read" Instances="_Total" />
      <PerformanceCounters Objects="LogicalDisk" Counters="Avg. Disk sec/Write" Instances="_Total" />
      <PerformanceCounters Objects="LogicalDisk" Counters="% Disk Time" Instances="_Total" />
    </ns:PerformanceCountersCollector>
  </Parameters>
</cs>
<cs>
  <Parameters>
    <ns:PerformanceCountersCollector xmlns:ns="DataCollectorType">
      <PerformanceCounters Objects="Processor" Counters="% Processor Time" Instances="_Total" />
      <PerformanceCounters Objects="Processor" Counters="% Privileged Time" Instances="_Total" />
    </ns:PerformanceCountersCollector>
  </Parameters>
</cs>

但我只是希望“对象”和“计数器”像表格一样。

例如:

Objects     | Counters

LogicalDisk | Avg. Disk sec/Read

LogicalDisk | Avg. Disk sec/Write

LogicalDisk | % Disk Time

Processor   | % Processor Time

Processor   | % Privileged Time

1 个答案:

答案 0 :(得分:0)

为什么使用FOR XML AUTO?这会将查询结果转换为XML。如果我正确地阅读了这一点,那么您正试图从XML中获取表格式数据......

试试这样:

select perfCounter.value('@Objects','nvarchar(max)') AS Objects
      ,perfCounter.value('@Counters','nvarchar(max)') AS Counters
FROM
msdb.dbo.syscollector_collection_sets AS cs
INNER JOIN msdb.dbo.syscollector_collection_items AS ci ON ci.collection_set_id=cs.collection_set_id
INNER JOIN msdb.dbo.syscollector_collector_types AS ct ON ct.collector_type_uid = ci.collector_type_uid
CROSS APPLY parameters.nodes(N'/*:cs/*:Parameters/*:PerformanceCountersCollector') AS A(perfCounterCollector)
CROSS APPLY perfCounterCollector.nodes(N'*:PerformanceCounters') AS B(perfCounter)
WHERE cs.is_system <> 1

您必须知道,此表中的参数在内容,形状和结构上有很大差异。

由于您希望将多个<ns:PerformanceCountersCollector>元素作为表格返回,而每个元素 - 再次 - 包含多个<PerformanceCounters> - 元素,我使用CROSS APPLY.nodes()来得到第一个列表,并 - 层次结构 - 再一个CROSS APPLY得到第二个列表。你需要的是属于第二个列表的属性值。

顺便说一下:我使用*:通配符命名空间。可能有必要明确这一点。如果你遇到任何问题,请回来......