2012-09-19 26 views
2

我想解析這一點。我想爲每個事件記錄一條記錄,所以我需要一種方法分別查詢每個事件。t-sql XML解析出多個記錄與事件和數據和值

但我想它是這個樣子:

Event Name           || ID || Timestamp || process_utilization 
--------------------------------------------------------------------------------------------- 
scheduler_monitor_system_heal_ring_buffer_recorded || 0 || 0   || 33 

這裏的XML:

<events> 
    <session startTime="2012-09-06T10:48:15.373" droppedEvents="0" largestDroppedEvent="0"> 
    <RingBufferTarget truncated="0" processingTime="0" totalEventsProcessed="14" eventCount="14" droppedCount="0" memoryUsed="3994"> 
     <event name="scheduler_monitor_system_health_ring_buffer_recorded" package="sqlos" timestamp="2012-09-19T16:46:33.091Z"> 
     <data name="id"> 
      <type name="uint32" package="package0" /> 
      <value>0</value> 
     </data> 
     <data name="timestamp"> 
      <type name="uint64" package="package0" /> 
      <value>0</value> 
     </data> 
     <data name="process_utilization"> 
      <type name="uint32" package="package0" /> 
      <value>33</value> 
     </data> 
     </event> 
     <event name="resource_monitor_ring_buffer_recorded" package="sqlos" timestamp="2012-09-19T16:46:38.386Z"> 
     <data name="id"> 
      <type name="uint32" package="package0" /> 
      <value>0</value> 
     </data> 
     </event> 
    </RingBufferTarget> 
    </session> 
</events> 

編輯: 另外,如果時間可以倒流,看起來像這樣的行,即會就好了:

scheduler_monitor_system_heal_ring_buffer_recorded || id || 0 
scheduler_monitor_system_heal_ring_buffer_recorded || timestamp || 0 
scheduler_monitor_system_heal_ring_buffer_recorded || process_utilization|| 33 

編輯:(感謝馬克) 使用馬克的代碼,我得到了這是我想要的98% - 只需要事件名稱。

SELECT 
    DataName = Evt.value('@name[1]', 'varchar(50)'), 
    TypeName= Evt.value('type[1]/@name[1]', 'varchar(50)'), 
    DataValue = Evt.value('value[1]', 'varchar(50)'), 
    DataText = Evt.value('text[1]', 'varchar(50)') 
FROM 
    @input.nodes('/events/session/RingBufferTarget/event/data') as Tbl(Evt) 

返回:

id     uint32 0 NULL 
timestamp   uint64 0 NULL 
process_utilization uint32 33 NULL 
id     uint32 0 NULL 

(但是,很明顯,需要事件的名稱)

回答

2

假設你有一個名爲@input變量的XML,試試這個:

declare @input XML = '....(your XML here).....'; 

SELECT 
    EventName = Evt.value('(@name)[1]', 'varchar(50)'), 
    EventID = Evt.value('(data[@name="id"]/value)[1]', 'int'), 
    EventTimeStamp = Evt.value('(data[@name="timestamp"]/value)[1]', 'bigint'), 
    ProcessUtilization = Evt.value('(data[@name="process_utilization"]/value)[1]', 'int') 
FROM 
    @input.nodes('/events/session/RingBufferTarget/event') as Tbl(Evt) 

用您的示例XML,我得到的輸出爲:

EventName           EventID EventTimeStamp ProcessUtilization 
scheduler_monitor_system_health_ring_buffer_record  0   0    33 
resource_monitor_ring_buffer_recorded     0   NULL   NULL 
+0

Marc,這幾乎就是我想要的,並且將作爲後備工作。如果有30個「集合」,而不僅僅是id/timestamp/process_utilization?有沒有辦法讓它自動生成每一列,而不是爲每一列專門調用'(data [@ name =「id」]/value)[1]'? – mbourgon

+0

或者:多行將罰款,只要你可以將事件名稱綁定到他們。 – mbourgon

+0

此外,由於每個「數據」都會有一個名稱/類型/值,您是否可以將這些全部放在一列中?讓我繼續弄亂你的代碼,它可能只是一個小小的變化。 – mbourgon

2

很多很多非常感謝@Marc_S指出我正確的方向!馬克,如果有什麼方法可以讓你獲得信貸,請在這裏或其他地方添加一個答案,我會信任你。

SELECT 
    DataName = Evt.value('../@name[1]', 'varchar(50)'), 
    DataName = Evt.value('@name[1]', 'varchar(50)'), 
    TypeName= Evt.value('type[1]/@name[1]', 'varchar(50)'), 
    DataValue = Evt.value('value[1]', 'varchar(50)'), 
    DataText = Evt.value('text[1]', 'varchar(50)') 
FROM 
    @input.nodes('/events/session/RingBufferTarget/event/data') as Tbl(Evt) 
+1

+1很棒,可以幫助您找到適合您的解決方案! –