{"id":501,"date":"2012-01-23T12:49:00","date_gmt":"2012-01-23T12:49:00","guid":{"rendered":"\/blogs\/bobb\/post\/XEvents-in-SQL-Server-2012-No-more-lazy-XML-in-event-harvesting-scripts.aspx"},"modified":"2012-01-23T12:49:00","modified_gmt":"2012-01-23T12:49:00","slug":"xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/","title":{"rendered":"XEvents in SQL Server 2012: No more &#8220;lazy XML&#8221; in event harvesting scripts"},"content":{"rendered":"<p>\nI&#39;ve said before how thrilled I am will the new extended event UI in SSMS for SQL Server 2012. However, you might be one of the early adopters who made up their own scripts to define extended event sessions, and use hardcoded scripts to harvest the results. So, you may run into this problem if you&#39;re using what I call &quot;lazy XML&quot; in the event harvesting script. Take, as an example, an extended event session defined as follows with 3 actions:\n<\/p>\n<p>\ncreate event session errorsession on server<br \/>\nadd event sqlserver.error_reported<br \/>\n(<br \/>\naction <br \/>\n(<br \/>\npackage0.callstack,&nbsp;&nbsp;&nbsp; <br \/>\nsqlserver.session_id,&nbsp;&nbsp; <br \/>\nsqlserver.sql_text&nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n)<br \/>\nwhere error = 547 and package0.counter &lt;= 3&nbsp; <br \/>\n)<br \/>\nadd target package0.ring_buffer<br \/>\nwith&nbsp;(max_dispatch_latency = 1 seconds)<br \/>\ngo\n<\/p>\n<p>\nIn previous versions, you could pretty much depend on the XML presenting the actions in order. So the following XML would return a subset of the event&nbsp;information in rows and columns.\n<\/p>\n<p>\nSELECT<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(data\/.)[1]<\/strong>&#39;, &#39;int&#39;) AS ErrorNumber,<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(action\/.)[2]<\/strong>&#39;, &#39;int&#39;) AS Session,<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(action\/.)[3]<\/strong>&#39;, &#39;nvarchar(max)&#39;) AS SQLStatement<br \/>\nfrom<br \/>\n(<br \/>\nselect CAST(xet.target_data as xml) as data<br \/>\nfrom sys.dm_xe_session_targets xet<br \/>\njoin sys.dm_xe_sessions xe<br \/>\non (xe.address = xet.event_session_address)<br \/>\nwhere xe.name = &#39;errorsession&#39;) events<br \/>\ncross apply Data.nodes (&#39;\/\/RingBufferTarget\/event&#39;) <br \/>\n&nbsp; AS Data2 (Results)\n<\/p>\n<p>\nThe XML above&nbsp;is based on the assumption that action 2 is the sqlserver.session_id and action 3 is the sqlserver.sql_text, because it doesn&#39;t check names, just blindly uses the ordinal number&nbsp;in XPath. It makes the XML easier to write and a bit faster to execute, but its &quot;lazy&quot; XML. This order of actions was a valid assumption in SQL Server 2008; its not valid in SQL Server 2012. The data fragment containing the action data appears like this:\n<\/p>\n<p>\n&nbsp;&nbsp;&nbsp; &lt;action name=&quot;sql_text&quot; package=&quot;sqlserver&quot;&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;type name=&quot;unicode_string&quot; package=&quot;package0&quot; \/&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;&nbsp; <br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DELETE pubs.dbo.jobs<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/value&gt;<br \/>\n&nbsp;&nbsp;&nbsp; &lt;\/action&gt;<br \/>\n&nbsp;&nbsp;&nbsp; &lt;action name=&quot;session_id&quot; package=&quot;sqlserver&quot;&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;type name=&quot;uint16&quot; package=&quot;package0&quot; \/&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;53&lt;\/value&gt;<br \/>\n&nbsp;&nbsp;&nbsp; &lt;\/action&gt;<br \/>\n&nbsp;&nbsp;&nbsp; &lt;action name=&quot;callstack&quot; package=&quot;package0&quot;&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;type name=&quot;callstack&quot; package=&quot;package0&quot; \/&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;..callstack elided&#8230;&lt;\/value&gt;<br \/>\n&nbsp;&nbsp;&nbsp; &lt;\/action&gt;\n<\/p>\n<p>\nSo now, sql_text (the third action defined) is the first action presented. The fragile harvesting script will break. So, to be one the safer side, if you have any such scripts change them to actually look for the element for want using a named XPath predicate, like this:\n<\/p>\n<p>\nSELECT<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(data[@name=&quot;error_number&quot;]\/.)[1]<\/strong>&#39;, &#39;int&#39;) AS ErrorNumber,<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(action[@name=&quot;session_id&quot;]\/.)[1]<\/strong>&#39;, &#39;int&#39;) AS Session,<br \/>\n&nbsp; Data2.Results.value (&#39;<strong>(action[@name=&quot;sql_text&quot;]\/.)[1]<\/strong>&#39;, &#39;nvarchar(max)&#39;) AS SQLStatement<br \/>\nfrom<br \/>\n(<br \/>\nselect CAST(xet.target_data as xml) as data<br \/>\nfrom sys.dm_xe_session_targets xet<br \/>\njoin sys.dm_xe_sessions xe<br \/>\non (xe.address = xet.event_session_address)<br \/>\nwhere xe.name = &#39;errorsession&#39;) events<br \/>\ncross apply Data.nodes (&#39;\/\/RingBufferTarget\/event&#39;) <br \/>\n&nbsp; AS Data2 (Results);\n<\/p>\n<p>\nNote that it&#39;s probably better to do this with the &quot;data&quot; items too (ErrorNumber in the query above), although you may be a little safer with these, as they have a defined schema per-event. But BOL does point out that events have a &quot;versioned&quot; schema.&nbsp;The actions can be defined in any order, so make your scripts more robust. Use XPath predicates. And if you&#39;re not on SQL Server 2012 yet, change your scripts now.\n<\/p>\n<p>\n@bobbeauch<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#39;ve said before how thrilled I am will the new extended event UI in SSMS for SQL Server 2012. However, you might be one of the early adopters who made up their own scripts to define extended event sessions, and use hardcoded scripts to harvest the results. So, you may run into this problem if [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,31,37],"tags":[],"class_list":["post-501","post","type-post","status-publish","format-standard","hentry","category-extended-events","category-sql-server-2012","category-sql-server-xml"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.9.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>XEvents in SQL Server 2012: No more &quot;lazy XML&quot; in event harvesting scripts - Bob Beauchemin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"XEvents in SQL Server 2012: No more &quot;lazy XML&quot; in event harvesting scripts - Bob Beauchemin\" \/>\n<meta property=\"og:description\" content=\"I&#039;ve said before how thrilled I am will the new extended event UI in SSMS for SQL Server 2012. However, you might be one of the early adopters who made up their own scripts to define extended event sessions, and use hardcoded scripts to harvest the results. So, you may run into this problem if [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/\" \/>\n<meta property=\"og:site_name\" content=\"Bob Beauchemin\" \/>\n<meta property=\"article:published_time\" content=\"2012-01-23T12:49:00+00:00\" \/>\n<meta name=\"author\" content=\"Bob Beauchemin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bob Beauchemin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/\",\"name\":\"XEvents in SQL Server 2012: No more \\\"lazy XML\\\" in event harvesting scripts - Bob Beauchemin\",\"isPartOf\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\"},\"datePublished\":\"2012-01-23T12:49:00+00:00\",\"dateModified\":\"2012-01-23T12:49:00+00:00\",\"author\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Extended Events\",\"item\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/extended-events\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"XEvents in SQL Server 2012: No more &#8220;lazy XML&#8221; in event harvesting scripts\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website\",\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/\",\"name\":\"Bob Beauchemin\",\"description\":\"SQL Server Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e\",\"name\":\"Bob Beauchemin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g\",\"caption\":\"Bob Beauchemin\"},\"sameAs\":[\"http:\/www.sqlskills.com\/blogs\/bobb\/\"],\"url\":\"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"XEvents in SQL Server 2012: No more \"lazy XML\" in event harvesting scripts - Bob Beauchemin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/","og_locale":"en_US","og_type":"article","og_title":"XEvents in SQL Server 2012: No more \"lazy XML\" in event harvesting scripts - Bob Beauchemin","og_description":"I&#39;ve said before how thrilled I am will the new extended event UI in SSMS for SQL Server 2012. However, you might be one of the early adopters who made up their own scripts to define extended event sessions, and use hardcoded scripts to harvest the results. So, you may run into this problem if [&hellip;]","og_url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/","og_site_name":"Bob Beauchemin","article_published_time":"2012-01-23T12:49:00+00:00","author":"Bob Beauchemin","twitter_misc":{"Written by":"Bob Beauchemin","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/","name":"XEvents in SQL Server 2012: No more \"lazy XML\" in event harvesting scripts - Bob Beauchemin","isPartOf":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website"},"datePublished":"2012-01-23T12:49:00+00:00","dateModified":"2012-01-23T12:49:00+00:00","author":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e"},"breadcrumb":{"@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/xevents-in-sql-server-2012-no-more-lazy-xml-in-event-harvesting-scripts\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/"},{"@type":"ListItem","position":2,"name":"Extended Events","item":"https:\/\/www.sqlskills.com\/blogs\/bobb\/category\/extended-events\/"},{"@type":"ListItem","position":3,"name":"XEvents in SQL Server 2012: No more &#8220;lazy XML&#8221; in event harvesting scripts"}]},{"@type":"WebSite","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#website","url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/","name":"Bob Beauchemin","description":"SQL Server Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sqlskills.com\/blogs\/bobb\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/62bfa986c5b5d28fcffd8b4fc409c73e","name":"Bob Beauchemin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sqlskills.com\/blogs\/bobb\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f80e6cc667410857fa6a21931dc528b8092f4d112bf7a8ff7c267674d44ee37?s=96&d=mm&r=g","caption":"Bob Beauchemin"},"sameAs":["http:\/www.sqlskills.com\/blogs\/bobb\/"],"url":"https:\/\/www.sqlskills.com\/blogs\/bobb\/author\/bobb\/"}]}},"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/comments?post=501"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/posts\/501\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/media?parent=501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/categories?post=501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/bobb\/wp-json\/wp\/v2\/tags?post=501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}