<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQLServerPedia Syndication | SQL RNNR</title>
	<atom:link href="https://jasonbrimhall.info/category/sqlserverpedia-syndication/feed/" rel="self" type="application/rss+xml" />
	<link>https://jasonbrimhall.info</link>
	<description>1 DBA&#039;s Professional Blog</description>
	<lastBuildDate>Mon, 20 Apr 2020 20:20:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.9.13</generator>

<image>
	<url>https://jasonbrimhall.info/wp-content/uploads/2019/07/favicon.jpg</url>
	<title>SQLServerPedia Syndication | SQL RNNR</title>
	<link>https://jasonbrimhall.info</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Event Files on Linux</title>
		<link>https://jasonbrimhall.info/2019/07/09/event-files-on-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=event-files-on-linux</link>
					<comments>https://jasonbrimhall.info/2019/07/09/event-files-on-linux/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 10 Jul 2019 04:20:30 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5861</guid>

					<description><![CDATA[<p>For the most part, things work the way you might expect them to work in windows - except it is on Linux. Sure some things are different, but SQL Server itself, is largely the same.</p>
The post <a href="https://jasonbrimhall.info/2019/07/09/event-files-on-linux/">Event Files on Linux</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="258" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 258px) 85vw, 258px" /></a></p>
<h2>TSQL Tuesday</h2>
<p>The second Tuesday of the month is upon us once again. That means it is time for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<p>This month, just about every SQL Server Data professional is being asked to get out of their comfort zone and talk about Linux (there are some out there that are very comfortable with Linux, but the vast majority are not <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ).</p>
<p>This is a topic that is near and dear to the heart of our organizer Tracy Boggiano (<a href="https://tracyboggiano.com">b</a> | <a href="http://twitter.com/tracyboggiano">t</a>). In Tracy&#8217;s <a href="https://tracyboggiano.com/archive/2019/07/t-sql-tuesday-116-sql-on-linux/">invite</a>, she says &#8220;<em>While I know it takes a while to adopt new technologies; I was wondering what it would take for people to adopt SQL on Linux.  Alternating I’m offering up for you to blog about what everyone should know when working with SQL on Linux or anything else related to SQL running on Linux.</em>&#8221;</p>
<p>That pretty much leaves the door wide open, right?</p>
<h3><span style="font-size: 14.04px;"><b>Event Files</b></span></h3>
<p>For the most part, things work the way you might expect them to work in windows &#8211; except it is on Linux. Sure some things are different, but SQL Server itself, is largely the same. That similarity, for the most part, boils all the way down into Extended Events (XEvents) as well. There is one significant divergence, however. And that is when it comes to specifying your event_file target for a new session. Let&#8217;s dive into that just a bit.</p>
<p>Let&#8217;s take a common setup for an XEvent session.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
/* this method will fail. The session will create but the session cannot be started due to a non-existent directory 
However, if the directory exists in linux format, and permissions are in place, the session will start.
*/
IF EXISTS
	(
		SELECT
				  *
			FROM  sys.server_event_sessions
			WHERE name = 'PREEMPTIVE_OS_PIPEOPS'
	)
	DROP EVENT SESSION PREEMPTIVE_OS_PIPEOPS ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE\';
GO

CREATE EVENT SESSION [PREEMPTIVE_OS_PIPEOPS]
	ON SERVER
	ADD EVENT sqlos.wait_info_external(
		 WHERE ([wait_type] = 'PREEMPTIVE_OS_PIPEOPS')
		)
	ADD TARGET package0.event_file
		(SET filename = N'C:\Database\XE\PREEMPTIVE_OS_PIPEOPS.xel')
	WITH
		(
			MAX_MEMORY = 4096KB
		  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		  , MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);
GO
ALTER EVENT SESSION Preemptive_os_pipeops ON SERVER
STATE = START;
GO</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/xe_deepdive.png"><img loading="lazy" class="alignright wp-image-5865" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/xe_deepdive.png" alt="" width="134" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/xe_deepdive.png 208w, https://jasonbrimhall.info/wp-content/uploads/2019/07/xe_deepdive-157x300.png 157w, https://jasonbrimhall.info/wp-content/uploads/2019/07/xe_deepdive-26x50.png 26w" sizes="(max-width: 134px) 85vw, 134px" /></a>This will fail before the query really even gets out of the gate. Why? The proc xp_create_subdir cannot create the directory because it requires elevated permissions. The fix for that is easy enough &#8211; grant permissions to write to the Database directory after creating it while in sudo mode. I will get to that in just a bit. Let&#8217;s see what the errors would look like for now.</p>
<blockquote><p><span style="color: #ff0000;">Msg 22048, Level 16, State 1, Line 15</span><br />
<span style="color: #ff0000;">xp_create_subdir() returned error 5, &#8216;Access is denied.&#8217;</span><br />
<span style="color: #ff0000;">Msg 25602, Level 17, State 23, Line 36</span><br />
<span style="color: #ff0000;">The target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.event_file&#8221;, encountered a configuration error during initialization. Object cannot be added to the event session. The operating system returned error 5: &#8216;Access is denied.</span><br />
<span style="color: #ff0000;">&#8216; while creating the file &#8216;C:\Database\XE\PREEMPTIVE_OS_PIPEOPS_0_132072025269680000.xel&#8217;.</span></p></blockquote>
<p>Let&#8217;s resolve the folder issue. I will create the Database folder (from a console session on the server), and then I will take ownership of that folder.</p><pre class="urvanov-syntax-highlighter-plain-tag">$ sudo mkdir /Database/

$ sudo chown -R $User:$User /Database/

$ sudo chgrp mssql /Database/

$ chmod g=rwx /Database/</pre><p>From there, it is also advisable to grant permissions to this folder to the SQL group via the chgrp command. Once done, re-running the entire session creation will magically work &#8211; including that windows based create subdir proc.</p>
<h3><span style="font-size: 14.04px;"><b>Alternative #2</b></span></h3>
<p>Maybe we just want to do things via the default method. If so, we can do this and it just works.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
/* this method succeeds but uses the default log directory */
IF EXISTS
	(
		SELECT
				  *
			FROM  sys.server_event_sessions
			WHERE name = 'PREEMPTIVE_OS_PIPEOPS2'
	)
	DROP EVENT SESSION PREEMPTIVE_OS_PIPEOPS2 ON SERVER;
GO

CREATE EVENT SESSION [PREEMPTIVE_OS_PIPEOPS2]
	ON SERVER
	ADD EVENT sqlos.wait_info_external(
		 WHERE ([wait_type] = 'PREEMPTIVE_OS_PIPEOPS')
		)
	ADD TARGET package0.event_file
		(SET filename = N'PREEMPTIVE_OS_PIPEOPS.xel')
	WITH
		(
			MAX_MEMORY = 4096KB
		  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		  , MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);
GO</pre><p></p>
<h3>Alternative #3</h3>
<p>And of course, there is always this option. Unfortunately, this means keeping multiple session scripts in source control in order to maintain the differences between Windows and Linux as illustrated in these two examples.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
/* this method succeeds but requires the permissions to be modified just the same as in the first example */
IF EXISTS
	(
		SELECT
				  *
			FROM  sys.server_event_sessions
			WHERE name = 'PREEMPTIVE_OS_PIPEOPS3'
	)
	DROP EVENT SESSION PREEMPTIVE_OS_PIPEOPS3 ON SERVER;
GO

CREATE EVENT SESSION [PREEMPTIVE_OS_PIPEOPS3]
	ON SERVER
	ADD EVENT sqlos.wait_info_external(
		 WHERE ([wait_type] = 'PREEMPTIVE_OS_PIPEOPS')
		)
	ADD TARGET package0.event_file
		(SET filename = N'/Database/XE/PREEMPTIVE_OS_PIPEOPS3.xel') --this is correct and matches the same pattern that ssms uses when using linux filesystem
	WITH
		(
			MAX_MEMORY = 4096KB
		  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		  , MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);
GO</pre><p>With all three sessions now on the server, I can query my target paths to confirm the correct paths have been used.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ses.name AS SessionName, CASE WHEN ISNULL(xs.name,'') = ''
		THEN 'No' ELSE 'Yes' END AS ISStarted
		, xs.total_bytes_generated
		,REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, ses.event_session_id
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					LEFT OUTER JOIN sys.dm_xe_sessions xs
						ON xs.name = ses.name
				WHERE sesf.name = 'filename'
					AND ses.name LIKE 'PREEMPTIVE_OS_PIPEOPS%';</pre><p>This produces the following results for me.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles.png"><img loading="lazy" class="aligncenter size-large wp-image-5864" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles-1024x115.png" alt="" width="560" height="63" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles-1024x115.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles-300x34.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles-768x86.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles-50x6.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/07/linux_eventfiles.png 1866w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Perfect, everything looks to be working and properly configured. Well, except for that session that is using the default directory &#8211; gag.</p>
<p><a href="https://tracyboggiano.com/archive/2019/07/t-sql-tuesday-116-sql-on-linux/"><img loading="lazy" class="wp-image-2309 size-full alignright" style="border: none; color: #ff4500;" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="" width="150" height="150" /></a></p>
<h3>Wrapping it Up</h3>
<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to capably monitor the server for any issue be it small or large. This article demonstrated how to create an Event Session on SQL Server that is running on Linux. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5861" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/07/09/event-files-on-linux/">Event Files on Linux</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/07/09/event-files-on-linux/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Is That Database in Use?</title>
		<link>https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=is-that-database-in-use</link>
					<comments>https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 03 Jul 2019 13:09:48 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5504</guid>

					<description><![CDATA[<p>This article demonstrates how to use Extended Events to determine if a database is being used by someone or something.</p>
The post <a href="https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/">Is That Database in Use?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="258" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 258px) 85vw, 258px" /></a></p>
<p>Does anybody know who or what is using this database? Better yet, is the database being used by anything at all? Have you ever asked those types of questions of your staff in an environment you have inherited?</p>
<p>As silly as it might sound, these are legitimate questions. It is not uncommon to have a relic database hanging around after an application has long since been retired. The database just continues to live on via life support in the dark recesses of your database server. Everybody has forgotten about it yet it consumes precious resources to do little more than exist.</p>
<p>But how do you go about discovering if the database is truly required or if it is just chewing up space and cpu cycles? The answer is to start by discovering if there is any activity in the database at all. <a href="https://xevents.jasonbrimhall.info">Extended Events</a> is an ideal method to audit your database and discover if there is truly activity on the database or not.</p>
<p><span style="font-size: 14.04px;"><b>DB In Use?</b></span></p>
<p>Depending on the version of SQL Server you are using, the method is going to be a little bit different. Each method I use still relies on Extended Events (XE), they just require some slight changes and subtle nuances (particularly for those pesky 2008 and R2 instances out there). Let&#8217;s focus on the 2008 method this time around and we will revisit the updated version in a later article.</p>
<h3>2008/R2</h3>
<p>Let&#8217;s first start with the XE session that works well for discovering the frequency of use a database may be encountering.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* 2008R2 */
USE master;
GO
-- Create the Event Session
IF EXISTS (SELECT * FROM sys.server_event_sessions WHERE name = 'DBinUse')
	DROP EVENT SESSION DBinUse ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION DBinUse
	ON SERVER
	ADD EVENT sqlserver.database_transaction_begin
		( --Occurs when a database transaction begins. Count of transactions at the database level that "start"
		 ACTION
			 (
				 sqlserver.database_id
			   , sqlserver.database_context --action is deprecated in later versions
			 )
		)
	ADD TARGET package0.asynchronous_bucketizer
		(SET source_type = 1, source = N'sqlserver.database_id') --2008r2 requires that the package name be specified with the action
	WITH
		(
			MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);


/* start the session */
ALTER EVENT SESSION DBinUse ON SERVER STATE = START;
GO</pre><p>Inline with the script, I left some interesting notes. First, the note in the target section is of particular interest because it lays out a requirement for this kind of target in 2008/R2. When using the action source type, then the package name must be specified along with the action in two-part naming format.</p>
<p><b></b><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE.png"><img loading="lazy" class=" wp-image-5524 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE.png" alt="" width="223" height="166" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE.png 384w, https://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE-300x223.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE-50x37.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/07/DBINUSE-320x240.png 320w" sizes="(max-width: 223px) 85vw, 223px" /></a>Next, in the actions, I have a note about sqlserver.database_context. This particular action is deprecated in later versions. Do I need it in this session? No. I put it in there for additional troubleshooting/exploration.</p>
<p>Lastly, I have a note about the event name. I chose database_transaction_begin because this is fired when a database transaction starts. I don&#8217;t really care if the transaction completes. I just want to know if an attempt was made to use that database and the data therein.</p>
<p>If I comment out the deprecated action (database_context), I could actually use this session on later versions (as constructed) of SQL Server. It doesn&#8217;t matter that the asynchronous_bucketizer has been replaced by the histogram target, the session will still create and work properly. SQL Server knows to automatically update the deprecated targets with the appropriate target when creating an XE Session on a server.</p>
<p>Since this is 2008/R2, we have to use TSQL in order to parse the data. The following query will do that for us!</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH dbusepreprocess AS
	(SELECT
		 CAST([target_data] AS XML) AS target_data
	   , xes.event_name
		 --INTO #xmlpreprocess
		 FROM sys.dm_xe_session_targets			 AS xt
			 INNER JOIN sys.dm_xe_sessions		 AS xs
				 ON xs.address = xt.event_session_address
			 INNER JOIN sys.dm_xe_session_events xes
				 ON xes.event_session_address = xt.event_session_address
		 WHERE xs.name = N'DBInUse'
			   AND xt.target_name = N'asynchronous_bucketizer')
	SELECT
		d.name AS DBName
	  , summary.dbuse_count
	  , summary.event_name
		FROM
			(
				SELECT
					hist.target_data.value('(value)[1]', 'bigint')	AS database_id
				  , hist.target_data.value('(@count)[1]', 'bigint') AS dbuse_count
				  , pp.event_name
					FROM dbusepreprocess									   pp
						CROSS APPLY target_data.nodes('BucketizerTarget/Slot') AS hist(target_data)
			)						 summary
			RIGHT OUTER JOIN sys.databases d
				ON summary.database_id = d.database_id;</pre><p>After executing that query, I will see results listing the activity of each database since the session was started. Here&#8217;s an example.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/dbinuse_results.png"><img loading="lazy" class="aligncenter size-full wp-image-5525" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/dbinuse_results.png" alt="" width="387" height="174" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/dbinuse_results.png 387w, https://jasonbrimhall.info/wp-content/uploads/2019/07/dbinuse_results-300x135.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/dbinuse_results-50x22.png 50w" sizes="(max-width: 387px) 85vw, 387px" /></a></p>
<p>Here we can see there are indeed some databases that are still in use on this server. If we are looking to retire the instance, or migrate relevant databases to a new server, we have better information about how to go about planning that work. Based on this data, I would be able to retire the ProtossZealot database but would be required to do something with the ZergRush and BroodWar databases. In the case of the ProtossZealot database that is not being used, we now have evidence to present back to the team that the database is not used. It is now up to those insisting on keeping it around to justify its existence and document why it must remain in tact.</p>
<h3>Wrapping it Up</h3>
<p><a href="http://bit.ly/XE60Days"><img loading="lazy" class="alignright wp-image-4545" style="border: none; color: #ff4500;" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="185" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 185px) 85vw, 185px" /></a></p>
<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to capably monitor the server for any issue be it small or large. This article demonstrates how to use Extended Events to determine if a database is being used by someone or something. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
<p>In addition, through the power of XE, we were able to capture a quick glimpse into some internals related to the database engine. In this case, we were able to see autoshrink in action and discover the frequency that it runs on when enabled.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5504" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/">Is That Database in Use?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Join a List of Values</title>
		<link>https://jasonbrimhall.info/2019/07/02/join-a-list-of-values/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=join-a-list-of-values</link>
					<comments>https://jasonbrimhall.info/2019/07/02/join-a-list-of-values/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 02 Jul 2019 13:35:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5457</guid>

					<description><![CDATA[<p>There are multiple ways of retrieving data from a table when you have a list of values. This article explores the use of the table value constructor.</p>
The post <a href="https://jasonbrimhall.info/2019/07/02/join-a-list-of-values/">Join a List of Values</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle.png"><img loading="lazy" class="wp-image-5458 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle.png" alt="" width="262" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle.png 350w, https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle-144x144.png 144w, https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/06/values_puzzle-65x65.png 65w" sizes="(max-width: 262px) 85vw, 262px" /></a></p>
<p>There are multiple ways of retrieving data from a table when you have a list of values. Sometimes, the method is straight-forward and sometimes we just can&#8217;t see the right solution.</p>
<p>Some of the methods to retrieve data from a table (based on a list of values) might include one or multiple of the following: <a href="https://www.sqlservercentral.com/steps/join-operations-%E2%80%93-nested-loops">join</a> to another table, throwing an in clause at it, dumping the values into a temp table, sub-queries, and a <a href="https://docs.microsoft.com/en-us/sql/t-sql/queries/table-value-constructor-transact-sql?view=sql-server-2017">table value constructor</a>.</p>
<p>Let&#8217;s focus on the table value constructor. This one seems to trip a few people up from time to time. First off, what is it?</p>
<h2>Table Value Constructor</h2>
<p>The table value constructor is basically like a virtual table not too different from a <a href="https://jasonbrimhall.info/2016/07/14/sql-server-cte-back-to-basics/">CTE</a> or a subquery (in that they are all virtual tables of sorts). The table value constructor however can be combined with either of those other types and is a set of row expressions that get put into this virtual table in a single DML statement.</p>
<p>So, this virtual table contains a set of values that we define. Let&#8217;s go ahead and take a look at an example set of data that we can cultivate into a table value constructor.</p><pre class="urvanov-syntax-highlighter-plain-tag">VALUES
		(14)
	, (15)
	, (18)
	, (20)
	, (102)
	, (103)
	, (104)
	, (105)
	, (106)
	, (107)
	, (108)
	, (109)
	, (110)
	, (111)
	, (112)
	, (113)
	, (115)
	, (116)
	, (117)
	, (118)
	, (128)
	, (129)
	, (130)
	, (131)
	, (132)
	, (133)
	, (134)
	, (135)
	, (152)
	, (153)
	, (170)
	, (171)
	, (172)
	, (173)
	, (175)
	, (176)
	, (177)
	, (178)</pre><p>Now, let&#8217;s say that I want to get all of the trace events that might correlate to those specific values, all I need to do is add this list of values to a query in the appropriate place. First, let&#8217;s see what it looks like when I add it via a CTE.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH traceevents (EventID) AS
	(SELECT
			 *
		 FROM
			 (
				 VALUES
					 (14)
				   , (15)
				   , (18)
				   , (20)
				   , (102)
				   , (103)
				   , (104)
				   , (105)
				   , (106)
				   , (107)
				   , (108)
				   , (109)
				   , (110)
				   , (111)
				   , (112)
				   , (113)
				   , (115)
				   , (116)
				   , (117)
				   , (118)
				   , (128)
				   , (129)
				   , (130)
				   , (131)
				   , (132)
				   , (133)
				   , (134)
				   , (135)
				   , (152)
				   , (153)
				   , (170)
				   , (171)
				   , (172)
				   , (173)
				   , (175)
				   , (176)
				   , (177)
				   , (178)
			 ) AS it (EventID) )
	SELECT
					   te.EventID
					 , t.name  AS EventName
					 , tc.name AS Category
		FROM		   traceevents			te
			INNER JOIN sys.trace_events		t
				ON t.trace_event_id = te.EventID
			INNER JOIN sys.trace_categories tc
				ON t.category_id = tc.category_id;</pre><p>In this case, I have thrown the table value constructor into a CTE. There could be a few good reasons to do it this way such as it being easier to read or maybe some corporate style policy. For me, I like the readability and the tight grouping of the join clauses without needing to scroll. Running the query in this case would produce results similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig.png"><img loading="lazy" class="aligncenter size-full wp-image-5481" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig.png" alt="" width="829" height="725" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig.png 829w, https://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig-300x262.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig-768x672.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/07/trace_events_stig-50x44.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Now, what if I really prefer to not use a CTE? Easy enough, let&#8217;s look at this next example. I will use the same list of values as I search for various wait_types.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
	mv.name
  , mv.map_key
  , mv.map_value
	FROM
		(
			VALUES
				(14)
			  , (15)
			  , (18)
			  , (20)
			  , (102)
			  , (103)
			  , (104)
			  , (105)
			  , (106)
			  , (107)
			  , (108)
			  , (109)
			  , (110)
			  , (111)
			  , (112)
			  , (113)
			  , (115)
			  , (116)
			  , (117)
			  , (118)
			  , (128)
			  , (129)
			  , (130)
			  , (131)
			  , (132)
			  , (133)
			  , (134)
			  , (135)
			  , (152)
			  , (153)
			  , (170)
			  , (171)
			  , (172)
			  , (173)
			  , (175)
			  , (176)
			  , (177)
			  , (178)
		)								it (itemid)
		INNER JOIN sys.dm_xe_map_values mv
			ON mv.map_key = it.itemid
	WHERE mv.name = 'wait_types';</pre><p>Notice here that I have a little bit of a different query. I only have one table to join to after the table value constructor. That said, it works just the same as the CTE example. Once the data is constructed, I alias it like a table, then I define the column names. This query will now return results similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor.png"><img loading="lazy" class="aligncenter size-full wp-image-5485" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor.png" alt="" width="726" height="724" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor.png 726w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor-144x144.png 144w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor-65x65.png 65w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Both of these examples have been pretty easy in building a single attribute array for the table value constructor. What if we had the need for multiple columns in our list of data?</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
	mv.name
  , mv.map_key
  , mv.map_value
  , it.WaitStatus
	FROM
		(
			VALUES
				(14,'Active')
			  , (15,'Active')
			  , (18,'Active')
			  , (20,'Active')
			  , (102,'Active')
			  , (103,'Active')
			  , (104,'Active')
			  , (105,'Active')
			  , (106,'Active')
			  , (107,'Active')
			  , (108,'Benign')
			  , (109,'Benign')
			  , (110,'Active')
			  , (111,'Active')
			  , (112,'Active')
			  , (113,'Active')
			  , (115,'Active')
			  , (116,'Active')
			  , (117,'Active')
			  , (118,'Active')
			  , (128,'Active')
			  , (129,'Benign')
			  , (130,'Benign')
			  , (131,'Benign')
			  , (132,'Benign')
			  , (133,'Active')
			  , (134,'Active')
			  , (135,'Active')
			  , (152,'Active')
			  , (153,'Active')
			  , (170,'Active')
			  , (171,'Active')
			  , (172,'Active')
			  , (173,'Active')
			  , (175,'Active')
			  , (176,'Active')
			  , (177,'Active')
			  , (178,'Active')
		)								it (itemid,WaitStatus)
		INNER JOIN sys.dm_xe_map_values mv
			ON mv.map_key = it.itemid
	WHERE mv.name = 'wait_types';</pre><p>Notice the addition of an extra value (separated by a comma) within each set of parenthesis and the additional column definition added after the alias for the table value constructor. This is a pretty simple modification. Upon execution, I can expect results such as the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign.png"><img loading="lazy" class="aligncenter size-full wp-image-5491" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign.png" alt="" width="910" height="712" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign.png 910w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign-300x235.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign-768x601.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/07/waits_tablevalconstructor_benign-50x39.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png"><img loading="lazy" class="wp-image-4327 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png" alt="" width="283" height="207" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png 770w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-300x219.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-768x562.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-50x37.png 50w" sizes="(max-width: 283px) 85vw, 283px" /></a>The Wrap</h2>
<p>Being able to take a list of data and construct it into a virtual table for further querying and data analysis is a pretty cool thing to do. The setup and syntax are fairly simple &#8211; it just takes a bit of practice and effort.</p>
<p>This article demonstrated three different examples of using a table value constructor to join a list of data to other tables. See what other kinds of examples you can come up with and share them.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5457" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/07/02/join-a-list-of-values/">Join a List of Values</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/07/02/join-a-list-of-values/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Detail Job History &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2019/06/27/detail-job-history-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=detail-job-history-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2019/06/27/detail-job-history-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 27 Jun 2019 13:25:09 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5434</guid>

					<description><![CDATA[<p>With this script, I have the ability to quick show which step is failing, what the command is for that step, what kind of process is running on that step, any passwords (in the event of an SSIS password), and of course the failure frequency. This is golden information at the fingertips. There is no need to click through the GUI to gather this information. You can get it quickly and easily in one fell swoop.</p>
The post <a href="https://jasonbrimhall.info/2019/06/27/detail-job-history-back-to-basics/">Detail Job History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png"><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="171" height="241" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 171px) 85vw, 171px" /></a></p>
<p>Recently, I covered the need to understand job failure frequency and knowing the value of your SQL Agent jobs. You can read the specifics in the article &#8211; <a href="http://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/">here</a>.</p>
<p>Sometimes, just knowing the frequency of the job failure is good enough. Sometimes, more information is helpful. Having more information is particularly helpful when meeting with the business to discuss the validity of the job in question.</p>
<p>What do you do in times like this? The most basic answer to that question is &#8211; get more data. But that barely scratches the surface. The real question being asked there is how do you go about gathering that data?</p>
<p>There are two methods to gather the data &#8211; the hard way and the easy way. Do you like to work hard? Or would you rather work more efficiently?</p>
<h2>Efficiency Matters</h2>
<p>As was discussed in the previous <a href="http://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/">article</a>, I prefer to do things just a little bit less manually where possible. The consistency of a script matters, but it also is just so much faster than doing things the hard, manual, iterative way. So let&#8217;s build a little bit on the script from the previous article.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH jobhist AS
	(SELECT
			   jh.job_id
			 , jh.run_date
			 , jh.run_status
			 , jh.step_id
			 , ROW_NUMBER() OVER (PARTITION BY jh.job_id, jh.run_status ORDER BY jh.run_date DESC) AS rownum
		 FROM  dbo.sysjobhistory jh
		 WHERE jh.step_id = 0)
   , agglastsixty AS
	(SELECT
						sjh.job_id
					  , sjh.run_status
					  , COUNT(*) AS RunCount
		 FROM			dbo.sysjobhistory sjh
			 INNER JOIN jobhist			  jh
				 ON jh.job_id = sjh.job_id
					AND jh.run_status = sjh.run_status
					AND jh.step_id = sjh.step_id
		 WHERE			CONVERT(DATE, CONVERT(VARCHAR, sjh.run_date)) &gt; DATEADD(
																				   d
																				 , -60
																				 , CONVERT(DATE, CONVERT(VARCHAR, jh.run_date))
																			   )
						AND jh.rownum = 1
		 GROUP BY		sjh.job_id
					  , sjh.run_status)
   , aggtotal AS
	(SELECT
						sjh.job_id
					  , sjh.run_status
					  , COUNT(*) AS RunCount
		 FROM			dbo.sysjobhistory sjh
			 INNER JOIN jobhist			  jh
				 ON jh.job_id = sjh.job_id
					AND jh.run_status = sjh.run_status
					AND jh.step_id = sjh.step_id
		 WHERE			jh.rownum = 1
		 GROUP BY		sjh.job_id
					  , sjh.run_status)
	SELECT
							j.name										 AS JobName
						  , sc.name										 AS CategoryName
						  --	  , sp.name										 AS OwnerName
						  --	  , j.owner_sid
						  , j.date_created
						  , j.enabled
						  , CONVERT(DATE, CONVERT(VARCHAR, oa.run_date)) AS RunDate
						  , CASE oa.run_status
								WHEN 0
									 THEN 'Failed'
								WHEN 1
									 THEN 'Succeeded'
								WHEN 2
									 THEN 'Retry'
								WHEN 3
									 THEN 'Canceled'
								WHEN 4
									 THEN 'In Progress'
							END											 AS run_status
						  , als.RunCount								 AS Last60StatusCount
						  , agt.RunCount								 AS TotalStatusCount
						  , js.subsystem								 AS JobStepSubsystem
						  , js.command
						  , CASE
								WHEN js.subsystem = 'SSIS'
									 AND js.command LIKE '%DECRYPT%'
									 THEN LTRIM(RTRIM(SUBSTRING(
																   js.command
																 , CHARINDEX('/DECRYPT', js.command, 1) + 9
																 , CHARINDEX('/', js.command, CHARINDEX('/DECRYPT', js.command, 1) + 1)
																   - CHARINDEX('/DECRYPT', js.command, 1) - 9
															   )
													 )
											   )
								ELSE 'N/A'
							END											 AS PkgPassword
						  , CASE
								WHEN js.subsystem = 'SSIS'
									 AND js.command LIKE '%FILE%'
									 THEN LTRIM(RTRIM(SUBSTRING(
																   js.command
																 , CHARINDEX('/FILE', js.command, 1) + 9
																 , CHARINDEX('\""', js.command, CHARINDEX('/FILE', js.command, 1) + 1)
																   - CHARINDEX('/FILE', js.command, 1) - 9
															   )
													 )
											   )
								ELSE 'N/A'
							END											 AS PkgPath
						  , spr.name									 AS ProxyName
						  , spr.credential_id
		FROM				dbo.sysjobs			  j
			LEFT JOIN		jobhist				  oa
				ON oa.job_id = j.job_id
			LEFT OUTER JOIN agglastsixty		  als
				ON als.job_id = oa.job_id
				   AND als.run_status = oa.run_status
			LEFT OUTER JOIN aggtotal			  agt
				ON agt.job_id = oa.job_id
				   AND agt.run_status = oa.run_status
			INNER JOIN		sys.server_principals sp
				ON j.owner_sid = sp.sid
			INNER JOIN		dbo.syscategories	  sc
				ON j.category_id = sc.category_id
			INNER JOIN		dbo.sysjobsteps		  js
				ON js.job_id = j.job_id
			LEFT JOIN		dbo.sysproxies		  spr
				ON js.proxy_id = spr.proxy_id
		WHERE				oa.rownum = 1
		--AND oa.run_status = 0
		ORDER BY			RunDate DESC;</pre><p>And here is a sample of the output.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus.png"><img loading="lazy" class="aligncenter size-large wp-image-5437" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus-1024x104.png" alt="" width="560" height="57" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus-1024x104.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus-300x30.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus-768x78.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/jobdetailstatus-50x5.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>With this script, I have the ability to quick show which step is failing, what the command is for that step, what kind of process is running on that step, any passwords (in the event of an SSIS password), and of course the failure frequency. This is golden information at the fingertips. There is no need to click through the GUI to gather this information. You can get it quickly and easily in one fell swoop.</p>
<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png"><img loading="lazy" class="wp-image-5179 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png" alt="" width="169" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png 223w, https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent-43x50.png 43w" sizes="(max-width: 169px) 85vw, 169px" /></a>The Wrap</h2>
<p>An important part of any DBAs job is to ensure database related jobs are running prim and proper. Sometimes that just doesn&#8217;t happen. When jobs are being overlooked, it is useful to be able to gather data related to consistency of job success or failure. This script will help you in your investigation efforts. In addition, I also recommend this <a href="http://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/">article</a> in your agent job audit efforts.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5434" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/27/detail-job-history-back-to-basics/">Detail Job History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/27/detail-job-history-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Database File Changes</title>
		<link>https://jasonbrimhall.info/2019/06/25/database-file-changes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-file-changes</link>
					<comments>https://jasonbrimhall.info/2019/06/25/database-file-changes/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 25 Jun 2019 13:07:32 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5440</guid>

					<description><![CDATA[<p>Data professionals around the globe are frequently finding themselves occupied with figuring out why and when a file (data or log) for a database has changed in size. Whether that change is a growth or shrink, or if the change was expected to happen or not.</p>
The post <a href="https://jasonbrimhall.info/2019/06/25/database-file-changes/">Database File Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="258" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 258px) 85vw, 258px" /></a></p>
<p>Data professionals around the globe are frequently finding themselves occupied with figuring out why and when a file (data or log) for a database has changed in size. Whether that change is a growth or shrink, or if the change was expected to happen or not.</p>
<p>I have written previously about the <a href="http://www.sqlservercentral.com/articles/Log+growth/69476/">need to monitor</a> these changes and <a href="https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/">how to do it</a> more efficiently (there is even a <a href="https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/">fail-safe</a> that occasionally works. As SQL Server improves, so does our ability to capture these types of events.</p>
<p>Given that SQL Server has undergone many enhancements, let&#8217;s take a look at the enhancements related to capturing the database file size changes.<a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><br />
</a></p>
<p><span style="font-size: 14.04px;"><b>Database File Related Events</b></span></p>
<p>If you read the articles mentioned previously, you will have encountered a previous article that include an Extended Event session that can be used for tracking file changes. That session is really good enough in most cases. One major change that I would suggest off the top is the asynchronous file target. While that target will work on all editions of SQL Server since 2008, the name of the target was changed in SQL Server 2012 to event_file. No big deal there. The XEM file is also no longer necessary, so that piece can just be wiped out.</p>
<p>That said, what else has changed? Let&#8217;s cover some deprecated events that may get you frustrated if you encounter them. The following events should be avoided because they will do nothing (a couple of them have been covered in this <a href="https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">previous article</a>).</p>
<ul style="list-style-type: circle;">
<li><strong>sqlserver.databases_log_growth</strong> &#8211; <em>Databases log growth</em></li>
<li><strong>sqlserver.databases_log_file_size_changed</strong> &#8211; <em>Databases log file size changed</em></li>
<li><strong>sqlserver.databases_data_file_size_changed</strong> &#8211; <em>Databases data file size change</em></li>
<li><strong>sqlserver.auto_shrink_log</strong> &#8211; <em>Auto shrink log ended</em>.</li>
</ul>
<p>Each of the preceding events have been replaced by a single event called database_file_size_change.</p>
<p>And then there is this one that I can&#8217;t seem to get to generate any events but it might possibly still be valid. In short, don&#8217;t be surprised one way or the other if it does something.</p>
<ul style="list-style-type: circle;">
<li><strong>sqlserver.auto_shrink_log_caught_exception</strong> &#8211; <em>Auto shrink log caught an exception</em>.</li>
</ul>
<p><img loading="lazy" class="wp-image-4545 alignright" style="border: none; color: #ff4500;" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="185" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 185px) 85vw, 185px" /></p>
<p>Great, we have some events we can avoid. Now let&#8217;s look at some events we should consider.</p>
<ul>
<li><strong>sqlserver.database_file_size_change</strong> &#8211; <em>Occurs when any of the data or log files for a database changes size. Use this event to monitor changes to the size of database files</em>.</li>
<li><strong>sqlserver.databases_shrink_data_movement</strong> &#8211; <em>Databases shrink data movement</em></li>
<li><strong>sqlserver.databases_log_file_used_size_changed</strong> &#8211; <em>Databases log file used size changed (<strong>this one gets noisy &#8211; use judiciously</strong>).</em></li>
<li><strong>sqlserver.databases_log_shrink</strong> &#8211; <em>Databases log shrink</em></li>
</ul>
<p>Now that we have some events that are viable as well as some events to avoid, let&#8217;s put a session together.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AuditFileSizev2' )
	DROP EVENT SESSION AuditFileSizev2
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION [AuditFileSizev2] ON SERVER
ADD EVENT sqlserver.database_file_size_change ( --good
	ACTION ( sqlserver.database_id, sqlserver.session_id,
	sqlserver.database_name, sqlserver.client_hostname, sqlserver.sql_text,
	sqlserver.nt_username, sqlserver.username, sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.context_info,
	sqlserver.client_connection_id )
	),
ADD EVENT sqlserver.databases_shrink_data_movement ( --good
	ACTION ( sqlserver.database_id, sqlserver.session_id,
	sqlserver.database_name, sqlserver.client_hostname, sqlserver.sql_text,
	sqlserver.nt_username, sqlserver.username, sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.context_info,
	sqlserver.client_connection_id )
	),
ADD EVENT sqlserver.databases_log_file_used_size_changed ( --good --this is a very chatty event and may be left off
	ACTION ( sqlserver.database_id, sqlserver.session_id,
	sqlserver.database_name, sqlserver.client_hostname, sqlserver.sql_text,
	sqlserver.nt_username, sqlserver.username, sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.context_info,
	sqlserver.client_connection_id )
	),
ADD EVENT sqlserver.databases_log_shrink ( --good
	ACTION ( sqlserver.database_id, sqlserver.session_id,
	sqlserver.database_name, sqlserver.client_hostname, sqlserver.sql_text,
	sqlserver.nt_username, sqlserver.username, sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.context_info,
	sqlserver.client_connection_id )
	)
ADD TARGET package0.event_file (  SET filename = 'C:\Database\XE\AuditFileSizev2.xel'
												, max_file_size = 5
												, max_rollover_files = 4 )
WITH ( MAX_MEMORY = 4 MB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, TRACK_CAUSALITY = ON
		, MAX_DISPATCH_LATENCY = 1 SECONDS
		, STARTUP_STATE = ON );
GO</pre><p>All we need to do at this juncture is test the session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges.png"><img loading="lazy" class="aligncenter size-large wp-image-5443" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges-1024x147.png" alt="" width="560" height="80" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges-1024x147.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges-300x43.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges-768x110.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/audit_dbfilechanges-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Let&#8217;s drill into the database_file_size_change event and take a closer look.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto.png"><img loading="lazy" class="aligncenter size-large wp-image-5444" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto-1024x281.png" alt="" width="560" height="154" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto-1024x281.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto-300x82.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto-768x210.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/dbfile_change_auto-50x14.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>There are a few things going on with this event. As previously mentioned, this event captures multiple different types of size related events. If you now look at the sections that I have circled in red, you will note that there is a flag that tracks if the event was an automatic size change. It doesn&#8217;t matter if it was a growth or shrink, both can be automatic. The way we can tell if it was an automatic shrink is due to the negative value in the size_change_kb field.</p>
<p>Next up, we have the green highlighted section. I have three distinct timestamps circled and separated by a dotted red line. Note the time difference between each of the groups. Each group of events is separated by 30 minutes. As it turns out, if you have Autoshrink enabled on your database, the timer is a 30 minute interval. Yes! <a href="https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options?view=sql-server-2017">Autoshrink</a> just so happened to be enabled on this database &#8211; for testing purposes.</p>
<h3>Wrapping it Up</h3>
<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to capably monitor the server for any issue be it small or large. This article demonstrated how to use Extended Events to monitor for file size changes and the same principles can be applied to any of the waits you may need to investigate. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
<p>In addition, through the power of XE, we were able to capture a quick glimpse into some internals related to the database engine. In this case, we were able to see autoshrink in action and discover the frequency that it runs on when enabled.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5440" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/25/database-file-changes/">Database File Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/25/database-file-changes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Job History &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=job-history-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 20 Jun 2019 12:57:09 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5429</guid>

					<description><![CDATA[<p>An important part of any DBAs job is to ensure database related jobs are running prim and proper. Sometimes that just doesn't happen. When jobs are being overlooked, it is useful to be able to gather data related to consistency of job success or failure. This script will help you in your investigation efforts.</p>
The post <a href="https://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/">Job History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png"><img loading="lazy" class="wp-image-4327 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png" alt="" width="238" height="174" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png 770w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-300x219.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-768x562.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-50x37.png 50w" sizes="(max-width: 238px) 85vw, 238px" /></a></p>
<p>How necessary is that SQL Server Agent job that you have running on the server? I ask that question of my clients on a routine basis.</p>
<p>Sometimes, I will ask that question as a routine part of a health check for the server. Others, it might be due to a migration or upgrade that is required for the server. Generally, the answer to the question will be one of two things: a) &#8220;Yes it is necessary.&#8221; or b) &#8220;What is that job doing?&#8221;.</p>
<p>Believe it or not, both answers will typically spawn more questions. You see, I don&#8217;t usually ask that question unless the job is failing on a regular basis. You wouldn&#8217;t believe how many jobs exist out there that are scheduled and just fail every time as well.</p>
<p>When I encounter a situation like this, it means it is time to have a discussion. In order to have that discussion, one needs to have done a bit of homework in order to better understand the situation. For me, part of this homework involves running the numbers and figuring out the frequency of the job&#8217;s failure or success.</p>
<h2>Data Gathering</h2>
<p>For me, I like to understand how often a job has executed and what is the frequency of failure for that quantity of executions. If I see a job that has not succeeded successfully in 60 consecutive executions, it is probably a safe bet that the job is not needed. Why? Well, if nobody has noticed the job hasn&#8217;t been working for that long, the likelihood of the job providing any use to the business is slim to none. In this case, I would present a case to the business as to why it should be removed.</p>
<p>But, how do I get to that point? Well, you could go through the job history for each job one by one and run some manual analytics. Or, you could take advantage of a script. I prefer the script route because it is faster, more reliable and a lot less mundane.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH jobhist AS
	(SELECT
			   jh.job_id
			 , jh.run_date
			 , jh.run_status
			 , jh.step_id
			 , ROW_NUMBER() OVER (PARTITION BY jh.job_id, jh.run_status ORDER BY jh.run_date DESC) AS rownum
		 FROM  dbo.sysjobhistory jh
		 WHERE jh.step_id = 0)
   , agglastsixty AS
	(SELECT
						sjh.job_id
					  , sjh.run_status
					  , COUNT(*) AS RunCount
		 FROM			dbo.sysjobhistory sjh
			 INNER JOIN jobhist			  jh
				 ON jh.job_id = sjh.job_id
					AND jh.run_status = sjh.run_status
					AND jh.step_id = sjh.step_id
		 WHERE			CONVERT(DATE, CONVERT(VARCHAR, sjh.run_date)) &gt; DATEADD(
																				   d
																				 , -60
																				 , CONVERT(DATE, CONVERT(VARCHAR, jh.run_date))
																			   )
						AND jh.rownum = 1
		 GROUP BY		sjh.job_id
					  , sjh.run_status)
   , aggtotal AS
	(SELECT
						sjh.job_id
					  , sjh.run_status
					  , COUNT(*) AS RunCount
		 FROM			dbo.sysjobhistory sjh
			 INNER JOIN jobhist			  jh
				 ON jh.job_id = sjh.job_id
					AND jh.run_status = sjh.run_status
					AND jh.step_id = sjh.step_id
		 WHERE			jh.rownum = 1
		 GROUP BY		sjh.job_id
					  , sjh.run_status)
	SELECT
							j.name										 AS JobName
						  , sc.name										 AS CategoryName
						  , sp.name										 AS OwnerName
						  , j.owner_sid
						  , j.date_created
						  , j.enabled
						  , CONVERT(DATE, CONVERT(VARCHAR, oa.run_date)) AS RunDate
						  , CASE oa.run_status
								WHEN 0
									 THEN 'Failed'
								WHEN 1
									 THEN 'Succeeded'
								WHEN 2
									 THEN 'Retry'
								WHEN 3
									 THEN 'Canceled'
								WHEN 4
									 THEN 'In Progress'
							END											 AS run_status
						  , als.RunCount								 AS Last60StatusCount
						  , agt.RunCount								 AS TotalStatusCount
		FROM				dbo.sysjobs			  j
			LEFT OUTER JOIN		jobhist				  oa
				ON oa.job_id = j.job_id
			LEFT OUTER JOIN agglastsixty		  als
				ON als.job_id = oa.job_id
				   AND als.run_status = oa.run_status
			LEFT OUTER JOIN aggtotal			  agt
				ON agt.job_id = oa.job_id
				   AND agt.run_status = oa.run_status
			INNER JOIN		sys.server_principals sp
				ON j.owner_sid = sp.sid
			INNER JOIN		dbo.syscategories	  sc
				ON j.category_id = sc.category_id
		WHERE				oa.rownum = 1
		ORDER BY			RunDate DESC;</pre><p>Running that script against my sandbox, I may see something such as the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus.png"><img loading="lazy" class="aligncenter size-large wp-image-5431" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus-1024x138.png" alt="" width="560" height="75" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus-1024x138.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus-300x41.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus-768x104.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/agentstatus-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Here you will note that the &#8220;wtf&#8221; job has two entries. One entry for &#8220;Succeeded&#8221; (in green) and one entry for &#8220;Failed&#8221; (in red). Each row receiving counts for number of executions.</p>
<p>This is the type of information I can use in a meeting to discuss with the business. This is no longer a discussion of opinion, but rather one that is now based on facts and data. It now becomes very easy to demonstrate to the business that a job has failed 60/60 times and nobody noticed it or cared enough about the consistent failures to do anything about it. Imagine if the failing job happens to be the database backups. I wonder what the action items for that job failure might include.</p>
<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png"><img loading="lazy" class="wp-image-5179 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png" alt="" width="169" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png 223w, https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent-43x50.png 43w" sizes="(max-width: 169px) 85vw, 169px" /></a>The Wrap</h2>
<p>An important part of any DBAs job is to ensure database related jobs are running prim and proper. Sometimes that just doesn&#8217;t happen. When jobs are being overlooked, it is useful to be able to gather data related to consistency of job success or failure. This script will help you in your investigation efforts. In addition, I also recommend this <a href="http://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/">article</a> in your agent job audit efforts.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5429" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/">Job History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/20/job-history-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Public Role Permissions &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2019/06/17/public-role-permissions-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=public-role-permissions-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2019/06/17/public-role-permissions-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 17 Jun 2019 13:10:40 +0000</pubDate>
				<category><![CDATA[DatabaseMasters Syndication]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5415</guid>

					<description><![CDATA[<p>If you are being serious in your role, then the amount of times you grant permissions to the public role should either be a) never, b) when you want to have a data breach, or c) you are testing in a sandbox to improve your skills.</p>
The post <a href="https://jasonbrimhall.info/2019/06/17/public-role-permissions-back-to-basics/">Public Role Permissions – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/tag/back-to-basics/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>Permissions in the database environment is such an important task. Setting permissions correctly is paramount to a successful audit and one of your best defenses against improper/unwanted access. Yet, in spite of the importance, security is often overlooked, neglected, improperly configured or just flat out ignored. Let&#8217;s not forget the times that security is intentionally misconfigured so certain individuals are permitted a backdoor access.</p>
<p>Security, just like performance tuning, is a perpetual (and sometimes iterative) task. There is no excuse for setting your security and forgetting it. It must be routinely reviewed.</p>
<p>While performing a script review for a client, I was reminded of the need to also review their security setup. The reminder was more of a slap in the face as I noticed that the developer had built in some permissions assignments for some upgrade scripts. Unfortunately, we were not permitted to alter any of the scripts due to them being from a third party vendor (and that vendor refused as well to fix the problems with the scripts but I digress).</p>
<h2>What could be wrong with this?</h2>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">GRANT REFERENCES,
      SELECT,
      INSERT,
      DELETE,
      UPDATE,
      ALTER,
      VIEW CHANGE TRACKING,
      VIEW DEFINITION,
      CONTROL
ON [dbo].[tblRptWeeklyCorporateBookingListing]
TO  PUBLIC;

GO</pre><p>I want you to digest that for just a moment. This is an example of the permissions this particular vendor insists on setting for the public role. What could possibly be wrong with that? Let&#8217;s examine a couple of the permissions like &#8220;Control&#8221; and &#8220;View Change Tracking&#8221;.</p>
<p><strong>View Change Tracking</strong></p>
<p>This permission is an elevated permission that is required in order to use the <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-functions/change-tracking-functions-transact-sql?view=sql-server-2017">change tracking functions</a>. This permission is necessary for the following reasons:</p>
<ol>
<li>Change tracking records contain the PK value for rows that have been deleted. If sensitive information was deleted that a user should not be able to access, the user would be able to reverse engineer the data from the change tracking data.</li>
<li>A user may be denied access to a column that contains sensitive data. If data in the column is changed, the data would be stored in the change tracking and a user can determine the values that were updated for the sensitive data.</li>
</ol>
<p><strong>Control</strong></p>
<p>I am going to take this one direct from the <a href="https://docs.microsoft.com/en-us/sql/relational-databases/security/permissions-database-engine?view=sql-server-2017">Microsoft documentation</a>.</p>
<blockquote><p><strong><span style="text-decoration: underline;">Confers ownership-like capabilities on the grantee</span></strong>. The grantee effectively has all defined permissions on the securable. A principal that has been granted CONTROL can also grant permissions on the securable. Because the SQL Server security model is hierarchical, CONTROL at a particular scope implicitly includes CONTROL on all the securables under that scope. For example, CONTROL on a database implies all permissions on the database, all permissions on all assemblies in the database, all permissions on all schemas in the database, and all permissions on objects within all schemas within the database.</p></blockquote>
<p>Now digest that a bit. Once digested, consider what the <a href="http://jasonbrimhall.info/2011/12/20/public-role-and-security/">public role</a> does to user access in a database. The public role permissions are inherited by all users of the database whether the users have been granted the permission or not. You should only grant permissions to the public role that you really honestly believe that <strong>ALL</strong> users should have. If you are being serious in your role, then the amount of times you grant permissions to the public role should either be a) never, b) when you want to have a data breach, or c) you are testing in a sandbox to improve your skills.</p>
<h2>Check for Perms</h2>
<p>When you are uncertain of which permissions have been assigned to the public role, or you just haven&#8217;t reviewed your permissions real-estate in some time, it is best to pull out a script and start the process. As luck would have it, I have a few scripts that can help with that (<a href="http://jasonbrimhall.info/?s=permissions">here</a> or <a href="http://jasonbrimhall.info/2010/03/19/security-audit/">here</a>) and I have a new one that I am sharing now.</p>
<p>Let&#8217;s start with a basic query that will display all of the permissions assigned to the public role in a specific database.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
	sp.state_desc
  , sp.permission_name
  , s.name AS SchemaName
  , o.name
	FROM sys.database_permissions	 sp
		LEFT JOIN sys.all_objects	 o
			ON sp.major_id = o.object_id
		LEFT OUTER JOIN sys.schemas	 s
			ON s.schema_id = o.schema_id
		JOIN sys.database_principals u
			ON sp.grantee_principal_id = u.principal_id
	WHERE u.name = 'public'
		  AND o.name IS NOT NULL
		  AND o.is_ms_shipped = 0
	ORDER BY o.name;</pre><p>There is nothing super special about this query. Looking at it, it is querying the permissions for the public role specifically. I display where the permission is a &#8220;Deny&#8221; or &#8220;Grant&#8221;. Then we list the permission name and then the schema and the object.</p>
<p>Let&#8217;s take that script and evolve it now. I am going to plan for the worst and expect that some permissions have been applied that shouldn&#8217;t have by some vendor upgrade script (because &#8211; well, history). Since I am expecting the worst, I am going to add some script generating code that will revoke the unwanted permissions. And still expecting the worst would be that revoking the permissions will break something, I will also add some code that can generate the appropriate &#8220;Grant&#8221; statements.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
	sp.state_desc
  , sp.permission_name
  , s.name			   AS SchemaName
  , o.name
  , 'REVOKE ' + sp.permission_name COLLATE Latin1_General_CI_AS_KS_WS + ' ON [' + s.name + '].[' + o.name
	+ '] FROM PUBLIC;' AS RevokeStmnt
  , 'GRANT ' + sp.permission_name COLLATE Latin1_General_CI_AS_KS_WS + ' ON [' + s.name + '].[' + o.name
	+ '] TO PUBLIC;'   AS GrantStmnt
	FROM sys.database_permissions		sp
		LEFT OUTER JOIN sys.all_objects o
			ON sp.major_id = o.object_id
		LEFT OUTER JOIN sys.schemas		s
			ON s.schema_id = o.schema_id
		JOIN sys.database_principals	u
			ON sp.grantee_principal_id = u.principal_id
	WHERE u.name = 'public'
		  AND o.name IS NOT NULL
		  AND o.is_ms_shipped = 0
	ORDER BY o.name;</pre><p>That looks better. I have a way of identifying the unwanted permissions as well as an easy script I can execute to remove the unwanted permissions. Note the use of the collate in the final two columns. As it turns out, permission_name from sys.database_permissions has a column collation of Latin1_General_CI_AS_KS_WS. Since I ran into some errors (shown below), it is easier to direct the DB engine to use the collation that matches the permission_name column.</p>
<blockquote><p><span style="color: #ff0000;">Msg 451, Level 16, State 1, Line 11</span><br />
<span style="color: #ff0000;">Cannot resolve collation conflict between &#8220;SQL_Latin1_General_CP850_CS_AS&#8221; and &#8220;Latin1_General_CI_AS_KS_WS&#8221; in add operator occurring in SELECT statement column 5.</span><br />
<span style="color: #ff0000;">Msg 451, Level 16, State 1, Line 11</span><br />
<span style="color: #ff0000;">Cannot resolve collation conflict between &#8220;SQL_Latin1_General_CP850_CS_AS&#8221; and &#8220;Latin1_General_CI_AS_KS_WS&#8221; in add operator occurring in SELECT statement column 6.</span></p></blockquote>
<p>Alas, this is still not quite as efficient of a script as I would like. I may have hundreds of databases on the instance and need to evaluate all of them. Time for the bigger guns.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* now do it for all databases */
DECLARE
     @DBName  SYSNAME
	 ,@SQL VARCHAR(2048);

DECLARE @PermsTab AS TABLE (DBName VARCHAR(128),PermissionState VARCHAR(20), PermissionName VARCHAR(128), SchemaName VARCHAR(128), ObjName VARCHAR(128), RevokeStmnt VARCHAR(256), GrantStmnt VARCHAR(256))
 
DECLARE pubperms CURSOR
  LOCAL STATIC FORWARD_ONLY READ_ONLY
     FOR SELECT d.name
		FROM sys.databases d
		WHERE d.state_desc  NOT IN ('SUSPECT','OFFLINE')

		OPEN pubperms;
 
FETCH NEXT FROM pubperms INTO @DBName;
 
WHILE @@FETCH_STATUS = 0
BEGIN

SET @SQL = 'SELECT
	''[' + @DBName + ']''
	,sp.state_desc
  , sp.permission_name
  , s.name			   AS SchemaName
  , o.name
  , ''REVOKE '' + sp.permission_name COLLATE Latin1_General_CI_AS_KS_WS + '' ON ['' + s.name + ''].['' + o.name
	+ ''] FROM PUBLIC;'' AS RevokeStmnt
  , ''GRANT '' + sp.permission_name COLLATE Latin1_General_CI_AS_KS_WS + '' ON ['' + s.name + ''].['' + o.name
	+ ''] TO PUBLIC;''   AS GrantStmnt
	FROM [' + @DBName + '].sys.database_permissions		sp
		LEFT OUTER JOIN [' + @DBName + '].sys.all_objects o
			ON sp.major_id = o.object_id
		LEFT OUTER JOIN [' + @DBName + '].sys.schemas		s
			ON s.schema_id = o.schema_id
		JOIN [' + @DBName + '].sys.database_principals	u
			ON sp.grantee_principal_id = u.principal_id
	WHERE u.name = ''public''
		  AND o.name IS NOT NULL
		  AND o.is_ms_shipped = 0
	ORDER BY o.name;'

	--PRINT @SQL;

INSERT INTO @PermsTab
	(
		DBName
	  , PermissionState
	  , PermissionName
	  , SchemaName
	  , ObjName
	  , RevokeStmnt
	  , GrantStmnt
	)
EXECUTE (@SQL)

FETCH NEXT FROM pubperms INTO @DBName;

END
 
CLOSE pubperms;
DEALLOCATE pubperms;

SELECT DBName
	 , PermissionState
	 , PermissionName
	 , SchemaName
	 , ObjName
	 , RevokeStmnt
	 , GrantStmnt
	FROM @PermsTab;</pre><p>That will take care of all of the permissions for the public role in all of the databases, with a slight caveat. I am only checking against that objects that are not flagged as is_ms_shipped. Now, isn&#8217;t there also a public role at the server scope? Indeed there is! Let&#8217;s also capture those permissions.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sp.state_desc, sp.permission_name, sp.class_desc, sp.major_id, sp.minor_id, e.name
FROM sys.server_permissions AS sp
  INNER JOIN sys.server_principals AS l
    ON sp.grantee_principal_id = l.principal_id
  LEFT OUTER JOIN sys.endpoints AS e
    ON sp.major_id = e.endpoint_id
WHERE l.name = 'public';</pre><p>Now, I feel many times better about what could possibly be going wrong with the public role.</p>
<p>If you are in a tightly controlled environment or you are just sick of people doing this sort of thing to your servers, there are more extreme measures that can be taken. You can read about it <a href="https://blogs.technet.microsoft.com/fort_sql/2010/02/04/remove-public-and-guest-permissions/">here</a> or <a href="https://www.stigviewer.com/stig/microsoft_sql_server_2012_database/2014-06-23/finding/V-41398">here</a>.</p>
<h2>The Wrap</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon.png"><img loading="lazy" class="wp-image-5194 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png" alt="" width="226" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png 226w, https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji-50x45.png 50w" sizes="(max-width: 226px) 85vw, 226px" /></a>It is amazing what some people will do that just doesn&#8217;t make sense. Granting permissions to the public role is one of these cases. That behavior also explains why there are documents and procedures for hardening the public role (<a href="https://www.sswug.org/basitaalishanmasood-al-farooq/sql-server/hardening-sql-server-installation/">here</a> and <a href="https://www.stigviewer.com/stig/microsoft_sql_server_2012_database/2014-06-23/finding/V-41398">here</a>).</p>
<p>If necessary, I recommend locking down your public role. It will make your job a little easier and give you better rest at night.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5415" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/17/public-role-permissions-back-to-basics/">Public Role Permissions – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/17/public-role-permissions-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Get the Source of PREEMPTIVE_OS_PIPEOPS Waits</title>
		<link>https://jasonbrimhall.info/2019/06/13/get-the-source-of-preemptive_os_pipeops-waits/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-the-source-of-preemptive_os_pipeops-waits</link>
					<comments>https://jasonbrimhall.info/2019/06/13/get-the-source-of-preemptive_os_pipeops-waits/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 13 Jun 2019 12:42:48 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5400</guid>

					<description><![CDATA[<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to capably monitor the server for any issue be it small or large. This article demonstrated how to use Extended Events to monitor for a specific wait_type and the same principles can be applied to any of the waits you may need to investigate.</p>
The post <a href="https://jasonbrimhall.info/2019/06/13/get-the-source-of-preemptive_os_pipeops-waits/">Get the Source of PREEMPTIVE_OS_PIPEOPS Waits</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>A client reached out to me for help about a wait_type they were seeing. That&#8217;s not terribly uncommon, but the specific wait_type was something that was fairly obscure.</p>
<p>Every day, they could see the delta on this wait_type continue to climb higher and <a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="258" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 258px) 85vw, 258px" /></a>higher. The problem was not in their ability to capture the deltas for the biggest wait_types. The problem as it were, was in figuring out what exactly was the root cause of their biggest wait_type.</p>
<p>What was the wait_type? Well, the obscure wait_type was called <a href="https://www.sqlskills.com/help/waits/preemptive_os_pipeops/">PREEMPTIVE_OS_PIPEOPS</a>. What causes this wait? As it turns out, this is a generic wait that is caused by SQL pipe related activities such as <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/xp-cmdshell-server-configuration-option?view=sql-server-2017">xp_cmdshell</a>.</p>
<p>Knowing this much information however does not get us to the root cause of this particular problem for this client. How do we get there? This is another case for Extended Events (XEvents).</p>
<h3>Tracking Pipe Ops</h3>
<p>Knowing which wait_type needs attention is most of the battle in figuring out what precisely is causing the specific wait. The second piece of the puzzle is to understand whether the wait is an internal or external. This is essential because a different event is triggered depending on whether the wait is internal or external. There will be more on that in a future article.</p>
<p>Since I happen to know already that the PREEMPTIVE_OS_PIPEOPS wait is an external wait, then I also know that I will want to use the sqlos.wait_info_external. The downside to this method is that conventional wisdom teaches us that we must use the integer value for the wait in order to monitor for it. To find that integer value, one can query the sys.dm_xe_map_values dmv. Since the values of many of the waits change from CU to CU, then one should validate this value on every server instead of using the same value on all servers without regard.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
	FROM sys.dm_xe_map_values ws
	WHERE ws.map_value = 'PREEMPTIVE_OS_PIPEOPS'
	AND ws.name = 'wait_types';</pre><p>Depending on which server I run that code on, I may receive different results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys.png"><img loading="lazy" class="aligncenter size-full wp-image-5403" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys.png" alt="" width="869" height="126" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys.png 869w, https://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys-300x43.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys-768x111.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/preemptive_pipeops_mapkeys-50x7.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>As you can see, I have a small sample showing five different values for this specific wait. Using the wrong value on the wrong server could result in a bit of hair tugging since nothing may be trapped.</p>
<p>Due to this potential for change, writing a script to monitor for the session gets a little bit trickier and a lot more dynamic &#8211; for now.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO

DECLARE @XelFilePath VARCHAR(256) = 'C:\Database\XE\'; --be sure to include the trailing slash as shown here


/* why?
 well as it turns out, many wait_types change from CU to CU of SQL Server
 */

-- Create the Event Session
EXECUTE xp_create_subdir @XelFilePath;
GO

DECLARE 	@mapkey VARCHAR(4)
	, @XESessionName VARCHAR(128) = 'PREEMPTIVE_OS_PIPEOPS'
	,@SQLString VARCHAR(4096)
	,@XelFilePath VARCHAR(256) = 'C:\Database\XE\';

SELECT @mapkey = ws.map_key
	FROM sys.dm_xe_map_values ws
	WHERE ws.map_value = 'PREEMPTIVE_OS_PIPEOPS'
	AND ws.name = 'wait_types';
	
SET @SQLString = 'IF EXISTS
	(
		SELECT
				  *
			FROM  sys.server_event_sessions
			WHERE name = ''' + @XESessionName + '''
	)
	DROP EVENT SESSION ' + @XESessionName + ' ON SERVER;
--GO
'

SET @SQLString = @SQLString + '

CREATE EVENT SESSION [' + @XESessionName + ']
	ON SERVER
	ADD EVENT sqlos.wait_info_external
		(ACTION
			 (
				 package0.callstack
			   , package0.collect_system_time
			   , package0.event_sequence
			   , sqlserver.client_app_name
			   , sqlserver.client_connection_id
			   , sqlserver.client_hostname
			   , sqlserver.context_info
			   , sqlserver.database_id
			   , sqlserver.database_name
			   , sqlserver.nt_username
			   , sqlserver.server_principal_name
			   , sqlserver.session_id
			   , sqlserver.session_nt_username
			   , sqlserver.sql_text
			   , sqlserver.username
			 )
		 WHERE ([wait_type] = ('+ @mapkey + ')) --PREEMPTIVE_OS_PIPEOPS
		)
	ADD TARGET package0.event_file
		(SET filename = N''' + @XelFilePath + 'PREEMPTIVE_OS_PIPEOPS.xel'')
	WITH
		(
			MAX_MEMORY = 4096KB
		  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		  , MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);
--GO

ALTER EVENT SESSION ' + @XESessionName + ' ON SERVER
STATE = START;
--GO
'
PRINT @SQLString;
EXECUTE (@SQLString)</pre><p>After executing that script, the session will be created with the appropriate wait_type as well as the session will be started. To verify it is working, then I can execute a query that will use xp_cmdshell.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results.png"><img loading="lazy" class="aligncenter size-full wp-image-5404" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results.png" alt="" width="991" height="102" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results.png 991w, https://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results-300x31.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results-768x79.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/waits_results-50x5.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a>With that information in hand, we now have a tool that will help us identify the root cause of this wait climbing to the top of the waits list. Once I am able to identify the root cause, then I can start applying an appropriate fix (or do nothing if the situation deems that necessary).</p>
<p>But what about this map_key that keeps on changing with updates to SQL Server? Surely there is a better method than figuring out the integer value. As luck would have it, conventional wisdom is wrong in this case. There is a much easier method of creating this event session. So much easier in fact that I don&#8217;t need to worry about the map_key value. All I need to know is the wait_type I wish to monitor. So let&#8217;s look at a better version of the script.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS
	(
		SELECT
				  *
			FROM  sys.server_event_sessions
			WHERE name = 'PREEMPTIVE_OS_PIPEOPS'
	)
	DROP EVENT SESSION PREEMPTIVE_OS_PIPEOPS ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE\';
GO

CREATE EVENT SESSION [PREEMPTIVE_OS_PIPEOPS]
	ON SERVER
	ADD EVENT sqlos.wait_info_external
		(ACTION
			 (
				 package0.callstack
			   , package0.collect_system_time
			   , package0.event_sequence
			   , sqlserver.client_app_name
			   , sqlserver.client_connection_id
			   , sqlserver.client_hostname
			   , sqlserver.context_info
			   , sqlserver.database_id
			   , sqlserver.database_name
			   , sqlserver.nt_username
			   , sqlserver.server_principal_name
			   , sqlserver.session_id
			   , sqlserver.session_nt_username
			   , sqlserver.sql_text
			   , sqlserver.username
			 )
		 WHERE ([wait_type] = 'PREEMPTIVE_OS_PIPEOPS')
		)
	ADD TARGET package0.event_file
		(SET filename = N'C:\Database\XE\PREEMPTIVE_OS_PIPEOPS.xel')
	WITH
		(
			MAX_MEMORY = 4096KB
		  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		  , MAX_DISPATCH_LATENCY = 5 SECONDS
		  , TRACK_CAUSALITY = ON
		  , STARTUP_STATE = ON
		);
GO</pre><p><img loading="lazy" class=" wp-image-4545 alignright" style="border: none; color: #ff4500;" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="191" height="191" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 191px) 85vw, 191px" /></p>
<p>This will yield the same results as the first script, but without the dynamic sql and with a more friendly script for the DBA to understand. This method is actually employed in the system_health system default session if you ever decide to peruse that session.<a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><br />
</a></p>
<h3>Wrapping it Up</h3>
<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to capably monitor the server for any issue be it small or large. This article demonstrated how to use Extended Events to monitor for a specific wait_type and the same principles can be applied to any of the waits you may need to investigate. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5400" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/13/get-the-source-of-preemptive_os_pipeops-waits/">Get the Source of PREEMPTIVE_OS_PIPEOPS Waits</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/13/get-the-source-of-preemptive_os_pipeops-waits/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Note to Self</title>
		<link>https://jasonbrimhall.info/2019/06/11/note-to-self/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=note-to-self</link>
					<comments>https://jasonbrimhall.info/2019/06/11/note-to-self/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Jun 2019 12:39:09 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5392</guid>

					<description><![CDATA[<p>Not only should you pay respect to those giving of their time, but you should spend a little time to also give back to the community. I will say it again, the more you give of yourself to help others learn your trade, the more you will personally learn and grow in your professional and personal self. It is an investment well worth taking.</p>
The post <a href="https://jasonbrimhall.info/2019/06/11/note-to-self/">Note to Self</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>TSQL Tuesday</h2>
<p>The second Tuesday of the month is upon us once again. That means it is time for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<h2>Sands of Time</h2>
<p>This month, MOHAMMAD DARAB<span class="TweetAuthor-decoratedName"><span class="TweetAuthor-name TweetAuthor-name--flex Identity-name customisable-highlight" title="Malathi Mahadevan" data-scribe="element:name"> (<a href="https://mohammaddarab.com" target="_blank" rel="noopener noreferrer">b</a> | <a href="https://twitter.com/mwdarab" target="_blank" rel="noopener noreferrer">t</a>)</span></span> <a href="https://mohammaddarab.com/t-sql-tuesday-115-dear-20-year-old-self/">invites us</a> to do the 40 yr. old self reflection. You know that age that is almost as dreadful to reach as the righteous age of 50? From there age only gets better &#8211; or at least I have been told that. I have done a couple of articles similar to this in past TSQLTuesdays. Similar yet still different just enough. Check out my article on <a href="http://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/">passion</a>,  or this on one <a href="http://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/">influence</a>.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/note.png"><img loading="lazy" class="wp-image-5393 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/note.png" alt="" width="235" height="227" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/note.png 298w, https://jasonbrimhall.info/wp-content/uploads/2019/06/note-50x48.png 50w" sizes="(max-width: 235px) 85vw, 235px" /></a>The problem with this particular challenge is the request to write a note to your 20 yr. old self. Well, maybe not an extreme problem other than the time travel part. As luck would have it, I recently discussed the topic with my grandmother. There was a lot of wisdom in what she taught me as we discussed the topic and I must admit, I was in agreement prior to even broaching the topic with her.</p>
<h3>Passing Notes</h3>
<p>Here is basically what my note to myself would say: &#8220;Self, you are doing good. Keep it up!&#8221;</p>
<p>That is even if I chose to send myself a note. You see, I would not want to change how things have happened. Life experience is good &#8211; both the good and the bad. All of it is necessary to grow and develop. Just like <a href="https://getyarn.io/yarn-clip/1d75530f-8294-4192-a206-1f5729f3d23c">Mater&#8217;s dents</a>, each experience is valuable and shouldn&#8217;t be changed.</p>
<p>Now, what if I were to create a note of advice for other more junior level professionals that I might be mentoring? That is a different story. My note to them would be simple &#8211; &#8220;Listen to me.&#8221; Maybe not so literally &#8220;me&#8221; and maybe more precisely as advice to listen to anybody who is giving their time to present, mentor, blog, or write (articles, books, etc). They are imparting of their experience and time and you should respect that and take advantage of it.</p>
<p>Not only should you pay respect to those giving of their time, but you should spend a little time to also give back to the community. Why? Well, I covered that pretty well in this article <a href="http://jasonbrimhall.info/2018/05/08/giving-back/">here</a>. I will say it again, the more you give of yourself to help others learn your trade, the more you will personally learn and grow in your professional and personal self. It is an investment well worth taking.</p>
<p>&nbsp;</p>
<h3>Wrapping it Up</h3>
<p>I don&#8217;t believe in trying to alter who I have become with any sort of visit back to my past self. The changes could cause me to change my path and not end up where I have reached due to personal growth and experience. Trial and error is good for growth. Everybody needs to learn that for themselves and cannot be forced into it. Just learn to grow and be patient with anybody you may mentor.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5392" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/11/note-to-self/">Note to Self</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/11/note-to-self/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Easy Open Event Log Files</title>
		<link>https://jasonbrimhall.info/2019/06/07/easy-open-event-log-files/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=easy-open-event-log-files</link>
					<comments>https://jasonbrimhall.info/2019/06/07/easy-open-event-log-files/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 07 Jun 2019 20:15:13 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5381</guid>

					<description><![CDATA[<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to better service the needs of the developers when the developers need access to the trace data.</p>
The post <a href="https://jasonbrimhall.info/2019/06/07/easy-open-event-log-files/">Easy Open Event Log Files</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="258" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 258px) 85vw, 258px" /></a>One of the beauties of using a tool such as Extended Events (XEvents) is the versatility and ease of use. XEvents can be used for so many things to help an aspiring DBA or Developer do their job better.</p>
<p>There has long been a sticking point about allowing various people access to production servers. Part of the sticking point is the developer who believes that access to read and evaluate trace files is mandatory on prod (yes I have heard many times where this has been used effectively by developers to gain prod access). But is that prod access truly necessary? Without an adequate method to provide the developer access to the trace data, the DBA loses confidence (from management) and standing ground for their side of the argument. How can a middle ground be met?</p>
<h3>XEvents to the Rescue</h3>
<p>With the use of XEvent tracing, a DBA is given a new realm of possibilities. This particular realm of possibilities becomes available when the XEvent trace (session) is created using a file target. Through the use of a file target, and the flexibility of XEvents, I have shown the beginnings of how a developer might be able to <a href="http://jasonbrimhall.info/2015/12/30/log-files-different-sources/" class="broken_link">access the trace data easily</a>.</p>
<p>That is merely the beginning though. There are a few more layers to making life easier for both the developer and DBA in regards to fetching event trace data. This article will show a few methods that will help make life just a bit easier.</p>
<p>Let&#8217;s start with the basics. After an XEvent session is created, it is important to know where the event file is being stored. If you don&#8217;t happen to know where it is, that is not a problem. The file source is easy enough to find and I have detailed it in <a href="http://jasonbrimhall.info/2019/05/20/event-log-file-paths/">this article</a>.</p>
<h3>Method 1</h3>
<p>As shown in the previous article, the first quick method to open an XEvent trace file is from within SSMS as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files.png"><img loading="lazy" class="aligncenter size-large wp-image-5384" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files-1024x540.png" alt="" width="560" height="295" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files-1024x540.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files-300x158.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files-768x405.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files-50x26.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/06/merge_xel_files.png 1925w" sizes="(max-width: 560px) 85vw, 560px" /></a>After clicking on &#8220;Merge Extended Event Files&#8230;&#8221;, a new window titled &#8220;Merge Extended Event Files&#8221; will open. From the new window, follow the following steps.<img loading="lazy" class="aligncenter size-large wp-image-5383" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge-1024x726.png" alt="" width="560" height="397" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge-1024x726.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge-300x213.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge-768x545.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/06/open_xelfiles_merge.png 1875w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<h3>Method 2</h3>
<p>Now, that is an extremely simple method to open and view a trace file for XEvents. That said, would you believe there are other equally easy methods? Let&#8217;s look at the next method that is very simple as well.</p>
<p>As was previously mentioned, you will need to know the file location first and then navigate to that location. So let&#8217;s do that. My common location is C:\Database\XE. Once navigated to the folder, I need to choose my file to be opened and follow the prompts as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu.png"><img loading="lazy" class="aligncenter size-large wp-image-5386" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu-1024x708.png" alt="" width="560" height="387" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu-1024x708.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu-300x208.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu-768x531.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu.png 1093w" sizes="(max-width: 560px) 85vw, 560px" /></a>A new window will pop up. By default, SSMS will be showing. If not, you can select SSMS and enable the option to always use SSMS for this file type by clicking the check box before clicking OK.<img loading="lazy" class="aligncenter size-large wp-image-5385" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2-978x1024.png" alt="" width="560" height="586" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2-978x1024.png 978w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2-287x300.png 287w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2-768x804.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2-48x50.png 48w, https://jasonbrimhall.info/wp-content/uploads/2019/06/xel_contextmenu2.png 983w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<h3>Method 3</h3>
<p>If the prior two methods feel unreasonably easy, then there is this next method that will spice things up a bit. It does require a bit of coordination. Once you have identified the file <a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class="size-full wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="256" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 256px) 85vw, 256px" /></a>to be opened, you can elect to perform a <a href="https://en.wikipedia.org/wiki/Drag_and_drop">drag and drop operation</a> of the file onto SSMS. Once done properly, the file will open in SSMS and you can start evaluating the data.</p>
<h3>Method 4</h3>
<p>This is as equally simplistic as the previous method but requires just a scoch less coordination. This method involves a double-click method. A double-click on the file will open the file up in SSMS.</p>
<h3>Method 5</h3>
<p>If you paid close attention to the screenshots in method 2, you will have noticed that there was a menu option called &#8220;Open&#8221; that I did not discuss. If you select open from the context menu at that point, then the xel file will open in SSMS just like any of the other methods mentioned thus far.</p>
<h3>Wrapping it Up</h3>
<p>Extended Events is a powerful tool with plenty of ease of use and flexibility. This flexibility allows the DBA to better service the needs of the developers when the developers need access to the trace data. This article demonstrated another use for Extended Events. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://xevents.jasonbrimhall.info">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5381" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/07/easy-open-event-log-files/">Easy Open Event Log Files</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/07/easy-open-event-log-files/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Implicit Conversion Insights with XE</title>
		<link>https://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=implicit-conversion-insights-with-xe</link>
					<comments>https://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 05 Jun 2019 12:56:19 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5367</guid>

					<description><![CDATA[<p>Seldom does a DBA have the opportunity to get out in front of infrequent or random errors such as implicit conversions. More often than not, it is the privilege of the DBA to find out about the problem after the fact from a developer or, worse yet, an end-user.</p>
The post <a href="https://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/">Implicit Conversion Insights with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png"><img loading="lazy" class="wp-image-5360 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png" alt="" width="260" height="195" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png 500w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-300x225.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-320x240.png 320w" sizes="(max-width: 260px) 85vw, 260px" /></a>Implicit</h2>
<p>In a <a href="http://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/">recent article</a>, I covered a little bit about <a href="https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine?view=sql-server-2017">implicit conversions</a> and an error that may crop up from time to time. It is one thing to understand what an error means, it is an entirely different problem to understand what is causing the error in the first place.</p>
<p>Seldom does a DBA have the opportunity to get out in front of infrequent or random errors such as implicit conversions. More often than not, it is the privilege of the DBA to find out about the problem after the fact from a developer or, worse yet, an end-user.</p>
<p>What if there was an easy method to track when these errors occurred? Even better, it would be ideal to understand what query caused the error as well as which types of queries are merely causing implicit conversion warnings. Even better, what if you had a way to understand which type of conversion problem is at hand.</p>
<h2>Implicit Playground</h2>
<p>To start this playground, let&#8217;s begin with a simple query based on the AdventureWorks database.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
		  emp.BusinessEntityID
		, NationalIDNumber
		, LoginID
	FROM  HumanResources.Employee emp
	WHERE NationalIDNumber = 112457891;
GO</pre><p>This query will yield a plan similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator.png"><img loading="lazy" class="aligncenter size-large wp-image-5370" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator-1024x238.png" alt="" width="560" height="130" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator-1024x238.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator-300x70.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator-768x178.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_operator-50x12.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If I hover the select operator, I will see a little window like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning.png"><img loading="lazy" class="aligncenter size-large wp-image-5371" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning-1024x689.png" alt="" width="560" height="377" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning-1024x689.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning-300x202.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning-768x516.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning-50x34.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/06/convert_implicit_warning.png 1404w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I have a few items highlighted in this window. In the larger red box, I am outlining much of the type conversion warning. Inside of that, there is a blue box highlighting the &#8220;convert_implicit&#8221; warning. If I look further into the error message, there is text about query plan choice and &#8220;CardinalityEstimate&#8221; or &#8220;SeekPlan&#8221; for the different convert_implicit warnings. Another way of looking at it is as follows.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties.png"><img loading="lazy" class="aligncenter size-large wp-image-5372" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties-1024x265.png" alt="" width="560" height="145" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties-1024x265.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties-300x78.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties-768x198.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/implicit_convert_properties-50x13.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This seems a lot more friendly than that little context window. Here we have an easy to follow layout of what is happening. As I drill down into the warnings, I can see there are three convert_implicit warnings and they all trigger a &#8220;planaffectingconvert&#8221; type of warning. As we look closer at this, I can see there are two distinct types of convert issues.</p>
<p>There is one for the conversion from nvarchar to int in the HumanResources.Employee table for the NationalIDNumber field (<strong><span style="color: #339966;">green</span></strong>).</p>
<p>Two warnings that state that an index seek has been disabled due to the conversions ( <strong><span style="color: #ff9900;">orange</span> </strong>and <strong><span style="color: #cc99ff;">purple</span></strong>).</p>
<p>Curious to see what all of the possible &#8220;ConvertIssue&#8221; values could be for these implicit conversions? That is easy enough with the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT mv.name, mv.map_value, mv.map_key
	FROM  sys.dm_xe_map_values mv
	WHERE mv.name = 'plan_affecting_convert_type';</pre><p>Which shows us the following results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes.png"><img loading="lazy" class="aligncenter size-full wp-image-5373" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes.png" alt="" width="914" height="289" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes.png 914w, https://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes-300x95.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes-768x243.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/06/planaffectingconverttypes-50x16.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>That is a grand total of three. Having covered the cause of two of these already, all that is <a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class=" wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="231" height="231" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 231px) 85vw, 231px" /></a>left is the type called &#8220;unknown&#8221;. I think we can safely presume that the cause of this one is something else that is undocumented and hence &#8220;unknown&#8221;.</p>
<p>So far, so good. We have seen how these warnings can crop up in execution plans. We have also seen how to query the for the &#8220;ConvertIssue&#8221; types or &#8220;plan_affecting_convert_type&#8221; from the Extended Events (XE) maps system DMV.</p>
<p>Right about now, the light bulb should be popping up for you. If we can query the XE metadata for the different convert issue types, then does that mean there is a way we can use XE to track these things and review them at our own convenience? Yes there is!</p>
<h3>XE</h3>
<p>Without further adieu, let&#8217;s look at an XE session that can be useful in discovering more information in regards to implicit conversions in the database environment.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT		*
			FROM	sys.server_event_sessions
			WHERE name = 'ImplicitConvertError' )
	DROP EVENT SESSION ImplicitConvertError ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION [ImplicitConvertError]
	ON SERVER
	ADD EVENT sqlserver.error_reported
	( ACTION ( sqlserver.sql_text
			, sqlserver.nt_username
			, sqlserver.server_principal_name
			, sqlserver.client_hostname
			, package0.collect_system_time
			, package0.event_sequence
			, sqlserver.database_id
			, sqlserver.database_name
			, sqlserver.username
			, sqlserver.session_nt_username
			, sqlserver.client_app_name
			, sqlserver.session_id
			, sqlserver.context_info
			, sqlserver.client_connection_id )
	WHERE ( [error_number] = ( 257 )))
--fee free to uncomment these next few events if you wish to receive a ton more information
--, ADD EVENT sqlserver.module_end
--( ACTION ( ssqlserver.sql_text
--		, sqlserver.nt_username
--		, sqlserver.server_principal_name
--		, sqlserver.client_hostname
--		, package0.collect_system_time
--		, package0.event_sequence
--		, sqlserver.database_id
--		, sqlserver.database_name
--		, sqlserver.username
--		, sqlserver.session_nt_username
--		, sqlserver.client_app_name
--		, sqlserver.session_id
--		, sqlserver.context_info
--		, sqlserver.client_connection_id ))
--, ADD EVENT sqlserver.rpc_starting
--( ACTION ( sqlserver.sql_text
--		, sqlserver.nt_username
--		, sqlserver.server_principal_name
--		, sqlserver.client_hostname
--		, package0.collect_system_time
--		, package0.event_sequence
--		, sqlserver.database_id
--		, sqlserver.database_name
--		, sqlserver.username
--		, sqlserver.session_nt_username
--		, sqlserver.client_app_name
--		, sqlserver.session_id
--		, sqlserver.context_info
--		, sqlserver.client_connection_id ))
--, ADD EVENT sqlserver.sql_statement_completed
--( ACTION ( sqlserver.sql_text
--		, sqlserver.nt_username
--		, sqlserver.server_principal_name
--		, sqlserver.client_hostname
--		, package0.collect_system_time
--		, package0.event_sequence
--		, sqlserver.database_id
--		, sqlserver.database_name
--		, sqlserver.username
--		, sqlserver.session_nt_username
--		, sqlserver.client_app_name
--		, sqlserver.session_id
--		, sqlserver.context_info
--		, sqlserver.client_connection_id ))
--, ADD EVENT sqlserver.sql_statement_starting
--( ACTION ( sqlserver.sql_text
--		, sqlserver.nt_username
--		, sqlserver.server_principal_name
--		, sqlserver.client_hostname
--		, package0.collect_system_time
--		, package0.event_sequence
--		, sqlserver.database_id
--		, sqlserver.database_name
--		, sqlserver.username
--		, sqlserver.session_nt_username
--		, sqlserver.client_app_name
--		, sqlserver.session_id
--		, sqlserver.context_info
--		, sqlserver.client_connection_id ))
, ADD EVENT sqlserver.plan_cache_cache_hit
( ACTION ( sqlserver.sql_text
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.client_hostname
		, package0.collect_system_time
		, package0.event_sequence
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.username
		, sqlserver.session_nt_username
		, sqlserver.client_app_name
		, sqlserver.session_id
		, sqlserver.context_info
		, sqlserver.client_connection_id ))
, ADD EVENT sqlserver.plan_cache_cache_attempt
( ACTION ( sqlserver.sql_text
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.client_hostname
		, package0.collect_system_time
		, package0.event_sequence
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.username
		, sqlserver.session_nt_username
		, sqlserver.client_app_name
		, sqlserver.session_id
		, sqlserver.context_info
		, sqlserver.client_connection_id ))
, ADD EVENT sqlserver.plan_affecting_convert
( ACTION ( sqlserver.sql_text
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.client_hostname
		, package0.collect_system_time
		, package0.event_sequence
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.username
		, sqlserver.session_nt_username
		, sqlserver.client_app_name
		, sqlserver.session_id
		, sqlserver.context_info
		, sqlserver.client_connection_id )
WHERE ( [package0].[equal_boolean]([sqlserver].[is_system], ( 0 ))
		AND [sqlserver].[database_id] &gt; ( 4 )))
, ADD EVENT sqlserver.sp_cache_remove
( ACTION ( sqlserver.client_app_name
		, sqlserver.sql_text )
WHERE ( [sqlserver].[is_system] = ( 0 )))
, ADD EVENT sqlserver.uncached_sql_batch_statistics
( ACTION ( sqlserver.sql_text
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.client_hostname
		, package0.collect_system_time
		, package0.event_sequence
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.username
		, sqlserver.session_nt_username
		, sqlserver.client_app_name
		, sqlserver.session_id
		, sqlserver.context_info
		, sqlserver.client_connection_id )
WHERE ( [sqlserver].[is_system] = ( 0 )))
	ADD TARGET package0.event_file
(	SET filename = N'C:\Database\XE\ImplicitConvertError.xel', max_rollover_files = ( 5 ))
	WITH ( MAX_MEMORY = 4096KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 3 SECONDS
		, MAX_EVENT_SIZE = 0KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO</pre><p>This session is pretty comprehensive with the ability to be very much like a fire-hose session if the commented out events are uncommented prior to session creation. Running this on a busy server ( less than 1 minute) for a client with a third party vendor application produces results that look like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/06/session_results_implicit.png"><img loading="lazy" class="aligncenter size-full wp-image-5374" src="http://jasonbrimhall.info/wp-content/uploads/2019/06/session_results_implicit.png" alt="" width="607" height="211" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/06/session_results_implicit.png 607w, https://jasonbrimhall.info/wp-content/uploads/2019/06/session_results_implicit-300x104.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/06/session_results_implicit-50x17.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>As we can see here, the session is trapping when I have any of those pesky implicit conversion errors (<strong><span style="color: #ff0000;">red</span> </strong>box outline) as mentioned in the <a href="http://bit.ly/2MvoNxg">previous article</a>, as well as the convert_implicit warnings (<strong><span style="color: #cc99ff;">purple</span> </strong>box outline) that were demonstrated in the execution plans in this article.</p>
<p>How am I trapping the implicit conversion error? That is done via the following piece of the event session shown above.</p><pre class="urvanov-syntax-highlighter-plain-tag">ADD EVENT sqlserver.error_reported
	( ACTION ( sqlserver.sql_text
			, sqlserver.nt_username
			, sqlserver.server_principal_name
			, sqlserver.client_hostname
			, package0.collect_system_time
			, package0.event_sequence
			, sqlserver.database_id
			, sqlserver.database_name
			, sqlserver.username
			, sqlserver.session_nt_username
			, sqlserver.client_app_name
			, sqlserver.session_id
			, sqlserver.context_info
			, sqlserver.client_connection_id )
	WHERE ( [error_number] = ( 257 ))) --implicit conversion error</pre><p>Error number 257 is the message id for the implicit conversion error. When filtering on that ID for this event, then I will receive only the implicit errors that match that number.</p>
<p>As for the implicit conversion warnings, we have the following that accomplishes that requirement.</p><pre class="urvanov-syntax-highlighter-plain-tag">, ADD EVENT sqlserver.plan_affecting_convert
( ACTION ( sqlserver.sql_text
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.client_hostname
		, package0.collect_system_time
		, package0.event_sequence
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.username
		, sqlserver.session_nt_username
		, sqlserver.client_app_name
		, sqlserver.session_id
		, sqlserver.context_info
		, sqlserver.client_connection_id )
WHERE ( [package0].[equal_boolean]([sqlserver].[is_system], ( 0 ))
		AND [sqlserver].[database_id] &gt; ( 4 )))</pre><p>The event, plan_affecting_convert should seem eerily familiar at this point. We have seen terminology like that in the execution plans as well as in the query for the map values.</p>
<p>The combination of these events will provide great insight into the issues revolving around any implicit conversions you may be having in your database environment.</p>
<h3>Wrapping it Up</h3>
<p>Implicit conversions are a fail-safe for when bad design or code (or both) crops up in your environment. When this fail-safe is being used in your environment, it is helpful to gain further insights via Extended Events. This article demonstrated another use for Extended Events. If you are in need of a little tune-up for your XE skiils, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5367" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/">Implicit Conversion Insights with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Implicit Conversion Fail</title>
		<link>https://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=implicit-conversion-fail</link>
					<comments>https://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 31 May 2019 19:09:48 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5358</guid>

					<description><![CDATA[<p>Implicit conversions are not uncommon in the computing world and can be viewed as kind of a fail-safe for when we don't quite follow decent practices when designing the database or when writing queries or both.</p>
The post <a href="https://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/">Implicit Conversion Fail</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png"><img loading="lazy" class="wp-image-5360 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png" alt="" width="260" height="195" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion.png 500w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-300x225.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_conversion-320x240.png 320w" sizes="(max-width: 260px) 85vw, 260px" /></a>Implicit</h2>
<p>Every now and again, you may run into an error about implicit conversions in your queries. <a href="https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine?view=sql-server-2017">Implicit conversions</a> are not uncommon in the computing world and can be viewed as kind of a fail-safe for when we don&#8217;t quite follow decent practices when designing the database or when writing queries or both.</p>
<p>Despite this little fail-safe, there are times when a nasty little error will pop up and cause a bit of consternation.</p>
<blockquote><p><span style="color: #ff0000;">Implicit conversion from data type %ls to %ls is not allowed. Use the CONVERT function to run this query.</span></p></blockquote>
<h2>What Went Wrong</h2>
<p>Unlike many other errors in SQL Server, this error message makes some sense. The major components of what is wrong are present and you are given a decent idea of what the conversion attempt is that failed. When this particular error happens, you can bet that there are issues with some TSQL code somewhere for sure. In addition, you can bet there is likely a problem with the database design as well. Yay! More work for your back burner.</p>
<p>First, this error comes with an error id of 257 and we can see the <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/messages-for-errors-catalog-views-sys-messages?view=sql-server-2017">message text</a> via the following query. This id is important for when we want to monitor for this problem in the future.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
	FROM sys.messages m
	WHERE m.message_id = 257
	AND m.language_id = 1033;</pre><p>Let&#8217;s see how we can recreate this problem.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @BeginDate DATE = '2019-01-01',
        @EndDate DATE = '2019-12-31';
/* quick and easy method to create a test table with millions of rows if needed */
SELECT TOP 100
       ImplicitID = IDENTITY(INT, 1, 1),
       ImplicitInt = ABS(CHECKSUM(NEWID())) % 50000 + 1,
       ImplicitDate = DATEADD(DAY, RAND(CHECKSUM(NEWID())) * (1 + DATEDIFF(DAY, @EndDate, @BeginDate)), @EndDate)
INTO #ImplicitTest
FROM master.dbo.syscolumns t1,
     master.dbo.syscolumns t2;

ALTER TABLE #ImplicitTest ADD PRIMARY KEY CLUSTERED (ImplicitID);

SELECT *
FROM #ImplicitTest dq
WHERE ISNULL(dq.ImplicitID, GETDATE()) = '5/17/2020';

DROP TABLE #ImplicitTest;</pre><p>Which will produce the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate.png"><img loading="lazy" class="aligncenter size-full wp-image-5361" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate.png" alt="" width="818" height="381" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate.png 818w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate-300x140.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate-768x358.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/05/implicit_recreate-50x23.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>This is a prime example of a bad query producing an error. Obviously, I am using the wrong data type to try and query the temp table. The ImplicitID column is an integer and I am trying to query it using a date. The quick fix, would be to query the appropriate date column if I must use a date in my query, or i can use an integer to query the ImplicitID column.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
FROM #ImplicitTest dq
WHERE dq.ImplicitDate &gt; '5/17/2019';</pre><p>After this minor tweak, now the query will work and I start to see results. Given the random nature of the data in this query, the results will vary from batch to batch.</p>
<h3>Wrapping it Up</h3>
<p>Implicit conversions are a fail-safe for when bad design or code (or both) crops up in your environment. Sometimes, this fail-safe is inadequate and needs further assistance. Sometimes, that may be an explicit conversion and sometimes that means an appropriate rewrite of the query to use the appropriate columns and data types in the queries. This was an introductory article into the world of implicit conversions. There will be a follow-up or two about implicit conversions and monitoring for them. In preparation for the upcoming articles, I recommend reading a bit on <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a> to get up to date. For other basics related articles, feel free to <a href="http://jasonbrimhall.info/tag/back-to-basics/">read here</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5358" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/">Implicit Conversion Fail</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/05/31/implicit-conversion-fail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mass Backup All Sessions</title>
		<link>https://jasonbrimhall.info/2019/05/23/mass-backup-all-sessions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mass-backup-all-sessions</link>
					<comments>https://jasonbrimhall.info/2019/05/23/mass-backup-all-sessions/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 23 May 2019 22:27:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5347</guid>

					<description><![CDATA[<p>Migrating Extended Event Sessions from one server to another should be a simple task. So simple, one would think there was no need to give it a second thought, right?</p>
The post <a href="https://jasonbrimhall.info/2019/05/23/mass-backup-all-sessions/">Mass Backup All Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/crane.png"><img loading="lazy" class="wp-image-3079 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/crane.png" alt="" width="243" height="221" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/crane.png 614w, https://jasonbrimhall.info/wp-content/uploads/2015/10/crane-300x273.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/crane-50x46.png 50w" sizes="(max-width: 243px) 85vw, 243px" /></a>Migrating Extended Event Sessions from one server to another should be a simple task. So simple, one would think there was no need to give it a second thought, right?</p>
<p>Well, I have previously written about this topic, you are welcome to <a href="http://jasonbrimhall.info/2015/10/05/backing-up-sessions/">read it here</a>. The article discusses quite a bit about scripting out your XE Sessions. One thing lacking in that article is the ability to script out every session on a server.</p>
<p>If you are still not using Extended Events, I recommend checking out this <a href="http://bit.ly/XE60Days">library of articles</a> that will cover just about all of the basics concerning Extended Events.</p>
<h3>New and Improved</h3>
<p>What about scripting out all of the sessions in SSMS? Surely there is an easy way to do that, right? Well, you might think that. Let me step through the problem that I have seen in SSMS (and unfortunately it is not consistent).</p>
<p>First, from Object Explorer Details (or F5), let&#8217;s try to script a single session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2.png"><img loading="lazy" class="aligncenter size-large wp-image-5353" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2-1024x729.png" alt="" width="560" height="399" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2-1024x729.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2-300x214.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2-768x547.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptXEsession_objectexplv2.png 1145w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>When scripting a single session from the &#8220;Object Explorer Details&#8221;, I have several sub-menus that allow me to script the session to a &#8220;New Query Editor Window&#8221;. Now, let&#8217;s see what happens when trying to script multiple sessions.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2.png"><img loading="lazy" class="aligncenter size-large wp-image-5352" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2-1024x737.png" alt="" width="560" height="403" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2-1024x737.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2-300x216.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2-768x553.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexplv2.png 1111w" sizes="(max-width: 560px) 85vw, 560px" /></a>With several sessions selected, I try yet again to script the sessions and I get an unwanted result. Notice that the &#8220;Script Session as&#8221; option is grayed out and unusable. However, if I try it again (several times or maybe just once, your mileage may vary and it seems to not be relevant to version of SSMS), I may see something like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success.png"><img loading="lazy" class="aligncenter size-large wp-image-5350" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success-1024x591.png" alt="" width="560" height="323" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success-1024x591.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success-300x173.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success-768x444.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success-50x29.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/ssms_scriptmultiXEsession_objectexpl_success.png 1832w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Tada! Luck was with me and it finally worked that time. So, what should I do to be able to consistently script all of sessions? Well, that comes with an enhancement to the script I presented in the <a href="http://bit.ly/1Ohjefn">prior article here</a>.</p>
<p>Lets just dive straight into the new script.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET NOCOUNT ON;

DECLARE
	@statement	   VARCHAR(MAX)
  , @statement1	   VARCHAR(MAX)
  , @statement2	   VARCHAR(MAX)
  , @sessionname   VARCHAR(128)				 --	= 'AlwaysOn_health'						 -- 'system_health'
  , @csessionname  VARCHAR(128)
  , @XeFilePath	   VARCHAR(256)
  , @IsDefaultPath TINYINT
											 /* order of events scripted is different 
default order of creation is different than if scripted from the gui
the gui scripts by alpha order of package then event
while original creation has order by event_id only
*/
  , @eventorder	   VARCHAR(64) = 'original'; --'original' for order based on original script, --'ssms' for order based on ssms guy scripter 

DECLARE xessions CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY FOR
	SELECT
				 ses.name
		FROM	 sys.server_event_sessions ses
		WHERE	 ses.name = ISNULL(@sessionname, ses.name)
		ORDER BY ses.name;

OPEN xessions;

FETCH NEXT FROM xessions
INTO
	@csessionname;

DECLARE @ErrorLog VARCHAR(256) = CONVERT(VARCHAR(256), SERVERPROPERTY('ErrorLogFileName'));
DECLARE @ErrorPath VARCHAR(256) = LEFT(@ErrorLog, LEN(@ErrorLog) - CHARINDEX('\', REVERSE(@ErrorLog)) + 1);

WHILE @@FETCH_STATUS = 0
	BEGIN
		IF EXISTS
			(
				SELECT
								   1
					FROM		   sys.server_event_sessions	   ses
						INNER JOIN sys.server_event_session_fields sesf
							ON ses.event_session_id = sesf.event_session_id
					WHERE		   sesf.name = 'filename'
								   AND ses.name = @csessionname
			)
			BEGIN
				IF
					(
						SELECT
										   CHARINDEX('\', CONVERT(VARCHAR(256), sesf.value))
							FROM		   sys.server_event_sessions	   ses
								INNER JOIN sys.server_event_session_fields sesf
									ON ses.event_session_id = sesf.event_session_id
							WHERE		   sesf.name = 'filename'
										   AND ses.name = @csessionname
					) &gt; 0
					BEGIN
						SELECT
										   @XeFilePath
							= LEFT(CONVERT(VARCHAR(256), sesf.value), LEN(CONVERT(VARCHAR(256), sesf.value))
																	  - CHARINDEX(
																					 '\'
																				   , REVERSE(CONVERT(
																										VARCHAR(256)
																									  , sesf.value
																									)
																							)
																				 ) + 1)
							FROM		   sys.server_event_sessions	   ses
								INNER JOIN sys.server_event_session_fields sesf
									ON ses.event_session_id = sesf.event_session_id
							WHERE		   sesf.name = 'filename'
										   AND ses.name = @csessionname;
					END;
				ELSE
					BEGIN
						IF
							(
								SELECT				TOP 1
													LEFT(t2.file_name, LEN(t2.file_name) - CHARINDEX('\', REVERSE(t2.file_name)) + 1) AS XEFilePath
									FROM
													(
														SELECT
																		   REPLACE(CONVERT(NVARCHAR(128), sesf.value), '.xel', '*.xel') AS targetvalue
																		 , ses.name														AS SessionName
															FROM		   sys.server_event_sessions	   ses
																INNER JOIN sys.server_event_session_fields sesf
																	ON ses.event_session_id = sesf.event_session_id
															WHERE		   sesf.name = 'filename'
																		   AND ses.name = @csessionname
													)																	cte1
										CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue, NULL, NULL, NULL) t2
							) IS NOT NULL
							BEGIN
								SELECT
									@XeFilePath
									=
									(
										SELECT				TOP 1
															LEFT(t2.file_name, LEN(t2.file_name)
																			   - CHARINDEX('\', REVERSE(t2.file_name)) + 1) AS XEFilePath
											FROM
															(
																SELECT
																				   REPLACE(CONVERT(NVARCHAR(128), sesf.value), '.xel', '*.xel') AS targetvalue
																				 , ses.name														AS SessionName
																	FROM		   sys.server_event_sessions	   ses
																		INNER JOIN sys.server_event_session_fields sesf
																			ON ses.event_session_id = sesf.event_session_id
																	WHERE		   sesf.name = 'filename'
																				   AND ses.name = @csessionname
															)								 cte1
												CROSS APPLY sys.fn_xe_file_target_read_file(
																							   cte1.targetvalue
																							 , NULL
																							 , NULL
																							 , NULL
																						   ) t2
									);
							END;
						ELSE
							BEGIN
								SELECT
									@XeFilePath = @ErrorPath;
								SELECT
									@XeFilePath
								  , @ErrorPath;
							END;

					END;
			END;

		IF @ErrorPath = @XeFilePath
			BEGIN
				SET @IsDefaultPath = 1;
			END;
		ELSE
			BEGIN
				SET @IsDefaultPath = 0;
			END;
		SELECT
				  @statement
			= 'USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = ' + ses.name + ' )
	DROP EVENT SESSION ' + ses.name + ' 
    ON SERVER;
GO
'
			FROM  sys.server_event_sessions ses
			WHERE ses.name = @csessionname;

		IF @IsDefaultPath = 1
			BEGIN
				SET @statement = @statement + '';
			END;
		ELSE
			BEGIN
				SET @statement = @statement + '
EXECUTE xp_create_subdir '''	 + @XeFilePath + ''';
GO
'				;
			END;
		SELECT
				  @statement = @statement + '
CREATE EVENT SESSION ['	 + ses.name + '] ON SERVER
	'
			FROM  sys.server_event_sessions ses
			WHERE ses.name = @csessionname;

		WITH presel AS
			(SELECT
								ses.name											 AS SessionName
							  , sese.event_id
							  , sese.package
							  , 'ADD EVENT ' + sese.package + '.' + sese.name + ' (' AS EventName
							  , CASE
									WHEN ISNULL(sese.predicate, '') = ''
										 THEN ')'
									ELSE 'WHERE ' + sese.predicate + ' )'
								END													 AS SQLPredicate
							  , CASE
									WHEN ISNULL(sesf.EventSetOps, '') = ''
										 THEN ''
									ELSE 'SET ' + sesf.EventSetOps + ''
								END													 AS SETOperation
				 FROM			sys.server_event_sessions		ses
					 INNER JOIN sys.server_event_session_events sese
						 ON ses.event_session_id = sese.event_session_id
					 LEFT OUTER JOIN
								(
									SELECT	 DISTINCT
											 ST2.event_session_id
										   , ST2.object_id
										   , SUBSTRING(
												 (
													 SELECT
																		', ' + ST1.name + '=' + '(' + CONVERT(VARCHAR(60), ST1.value) + ')' AS [text()]
														 FROM			sys.server_event_session_fields ST1
															 INNER JOIN sys.server_event_session_events sese
																 ON sese.event_session_id = ST1.event_session_id
																	AND sese.event_id = ST1.object_id
														 WHERE			ST1.event_session_id = ST2.event_session_id
																		AND ST1.object_id = ST2.object_id
														 ORDER BY		ST1.object_id
													 FOR XML PATH('')
												 )
											   , 3
											   , 8000
													  ) [EventSetOps]
										FROM sys.server_event_session_fields ST2
								)								sesf
						 ON sese.event_session_id = sesf.event_session_id
							AND sese.event_id = sesf.object_id
				 WHERE			ses.name = @csessionname)
		   , actpresel AS
			(SELECT
								ses.name					   AS SessionName
							  , sesa.event_session_id
							  , sesa.event_id
							  , sesa.package + '.' + sesa.name AS ActPack
				 FROM			sys.server_event_session_events	 sese
					 INNER JOIN sys.server_event_session_actions sesa
						 ON sese.event_session_id = sesa.event_session_id
							AND sese.event_id = sesa.event_id
					 INNER JOIN sys.server_event_sessions		 ses
						 ON sesa.event_session_id = ses.event_session_id
				 WHERE			ses.name = @csessionname)
		   , pstuff AS
			(SELECT
						  p.SessionName
						, p.event_id
						, 'ACTION ( 
				' +		STUFF((
								  SELECT
											', ' + pin.ActPack + '
				'
									  FROM	actpresel pin
									  WHERE pin.SessionName = p.SessionName
											AND pin.event_id = p.event_id
								  FOR XML PATH(''), TYPE
							  ).value('.', 'varchar(max)')
							, 1
							, 2
							, ''
							 ) + '
			)'			AS ActionPack
				 FROM	  actpresel p
				 GROUP BY p.SessionName
						, p.event_id)
		SELECT
			@statement1 = @statement + STUFF((
												 SELECT
																		 ', ' + CAST(p.EventName + '
		'														 + p.SETOperation + '
		'														 + CASE
																	   WHEN ISNULL(ps.ActionPack, '') = ''
																			THEN ''
																	   ELSE ps.ActionPack
																   END + '
		'														 + p.SQLPredicate + '
'													 AS VARCHAR(MAX)) AS EventStatement
													 FROM				 presel p
														 LEFT OUTER JOIN pstuff ps
															 ON p.SessionName = ps.SessionName
																AND p.event_id = ps.event_id
													 ORDER BY			 p.event_id
												 --ORDER BY p.package, p.EventName 
												 FOR XML PATH(''), TYPE
											 ).value('.', 'varchar(max)')
										   , 1
										   , 2
										   , ''
											)
		  , @statement2 = @statement + STUFF((
												 SELECT
																		 ', ' + CAST(p.EventName + '
		'														 + p.SETOperation + '
		'														 + CASE
																	   WHEN ISNULL(ps.ActionPack, '') = ''
																			THEN ''
																	   ELSE ps.ActionPack
																   END + '
		'														 + p.SQLPredicate + '
'													 AS VARCHAR(MAX)) AS EventStatement
													 FROM				 presel p
														 LEFT OUTER JOIN pstuff ps
															 ON p.SessionName = ps.SessionName
																AND p.event_id = ps.event_id
													 ORDER BY			 p.package
																	   , p.EventName
												 FOR XML PATH(''), TYPE
											 ).value('.', 'varchar(max)')
										   , 1
										   , 2
										   , ''
											);

		IF @eventorder = 'original'
			BEGIN
				SET @statement = @statement1;
			END;
		IF @eventorder = 'ssms'
			BEGIN
				SET @statement = @statement2;
			END;

		SELECT
			@statement
			= @statement
			  + STUFF(
			(
				SELECT
								   ', ' + '
ADD TARGET '										+ sest.package + '.' + sest.name
								   + CASE
										 WHEN ISNULL(ca.setop, '') = ''
											  THEN ' 
'
										 ELSE '
			(SET ' +								ca.setop + ' )
'
									 END
					FROM		   sys.server_event_sessions		ses
						INNER JOIN sys.server_event_session_targets sest
							ON ses.event_session_id = sest.event_session_id
						CROSS APPLY
								   (
									   SELECT
										   STUFF(
			(
				SELECT
								   ', ' + CAST(sesf.name AS VARCHAR(128)) + ' = '
								   + CASE
										 WHEN ISNUMERIC(CAST(sesf.value AS VARCHAR(128))) = 1
											  THEN '( ' + CAST(sesf.value AS VARCHAR(128)) + ' )
							'
										 ELSE 'N''' + CAST(sesf.value AS VARCHAR(128)) + '''
						'
									 END AS setop
					FROM		   sys.server_event_session_fields	sesf
						INNER JOIN sys.server_event_sessions		sesi
							ON sesi.event_session_id = sesf.event_session_id
						INNER JOIN sys.server_event_session_targets sesti
							ON sesf.object_id = sesti.target_id
							   AND sesi.event_session_id = sesti.event_session_id
					WHERE		   sest.target_id = sesti.target_id
								   AND sest.event_session_id = sesti.event_session_id
				FOR XML PATH(''), TYPE
			).value('.', 'varchar(max)')
		  , 1
		  , 2
		  , ''
												)
								   )								AS ca(setop)
					WHERE		   ses.name = @csessionname
				FOR XML PATH(''), TYPE
			).value('.', 'varchar(max)')
		  , 1
		  , 2
		  , ''
					 );

		SELECT
				  @statement
			= @statement
			  + CAST('WITH ( MAX_MEMORY = ' + CAST(ses.max_memory AS VARCHAR(20)) + ' KB
		,EVENT_RETENTION_MODE = '		   + ses.event_retention_mode_desc + '
		, MAX_DISPATCH_LATENCY = '		   + CAST(ses.max_dispatch_latency / 1000 AS VARCHAR(20))
					 + ' SECONDS
		, MAX_EVENT_SIZE = '			   + CAST(ses.max_event_size AS VARCHAR(20))
					 + ' KB
		, MEMORY_PARTITION_MODE = '		   + ses.memory_partition_mode_desc + '
		, TRACK_CAUSALITY = '			   + CASE ses.track_causality
												 WHEN 1
													  THEN 'ON'
												 ELSE 'OFF'
											 END + '
		, STARTUP_STATE = '				   + CASE ses.startup_state
												 WHEN 1
													  THEN 'ON'
												 ELSE 'OFF'
											 END + '
	);'		AS VARCHAR(1024))
			FROM  sys.server_event_sessions ses
			WHERE ses.name = @csessionname;

		PRINT @statement;

		FETCH NEXT FROM xessions
		INTO
			@csessionname;
	END;

CLOSE xessions;
DEALLOCATE xessions;</pre><p>This is a rather lengthy script, so I won&#8217;t explain the entire thing. That said, this script will produce the exact XE Session as it was written when you deployed it to the server. In addition, the script will ensure the destination directory for the event_file target is created as a part of the script.</p>
<p>I can definitely hear the gears of thought churning as you ponder about this whole scenario. Surely, you have all of your XE Sessions stored in source control so there is no need whatsoever for this little script. Then again, that would be in an ideal environment. Sadly, source control is seldom considered for XE Sessions. Thus, it is always good to have a backup plan.</p>
<h3>Why</h3>
<p>Sadly, I had the very need of migrating a ton of sessions from one server to another recently and the methods in SSMS just wouldn&#8217;t work. There was no source control in the environment. Building out this little script saved me tons of time in migrating all of the sessions for this server and also provided me with a good script to place in source control.</p>
<h3>Conclusion</h3>
<p>In the article today, I have provided an excellent tool for backing up all of your XE sessions on the server. This script will help create the necessary scripts for all of your XE Sessions (or even just a single session if you like) in order to migrate the sessions to a new server or place them in source control.</p>
<p>To read more about Extended Events, I recommend <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">this series of articles</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5347" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/05/23/mass-backup-all-sessions/">Mass Backup All Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/05/23/mass-backup-all-sessions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Event Log File Paths</title>
		<link>https://jasonbrimhall.info/2019/05/20/event-log-file-paths/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=event-log-file-paths</link>
					<comments>https://jasonbrimhall.info/2019/05/20/event-log-file-paths/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 20 May 2019 22:30:00 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5327</guid>

					<description><![CDATA[<p>How does one consistently find the correct path to the Extended Event Log file (XEL file)? This article shows a thorough method to capture that information for all sessions on the server.</p>
The post <a href="https://jasonbrimhall.info/2019/05/20/event-log-file-paths/">Event Log File Paths</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/stonepath.png"><img loading="lazy" class="wp-image-5328 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/stonepath.png" alt="" width="223" height="219" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/stonepath.png 260w, https://jasonbrimhall.info/wp-content/uploads/2019/05/stonepath-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/stonepath-65x65.png 65w" sizes="(max-width: 223px) 85vw, 223px" /></a>How does one consistently find the correct path to the Extended Event Log file (XEL file)?</p>
<p>This is a topic that I ventured into some time ago. The previous article can be read <a href="http://jasonbrimhall.info/2016/08/24/finding-the-right-path/">here</a>. In that article I covered some of the various trouble spots with capturing the file path for various XE log files. One of the main problems being that there is frequently an inconsistency in where XE logs may actually be stored.</p>
<p>Using what was shown in that previous article, I have some improvements and minor tweaks to fill some gaps I hadn&#8217;t completed in the <a href="http://bit.ly/2c6jLpl">previous script</a>.</p>
<p>If you are still not using Extended Events, I recommend checking out this <a href="http://bit.ly/XE60Days">library of articles</a> that will cover just about all of the basics concerning Extended Events.</p>
<h3>New and Improved</h3>
<p>First, lets just dive straight into the new script.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ErrorPath VARCHAR(256) = CONVERT(VARCHAR(256), SERVERPROPERTY('ErrorLogFileName'));
DECLARE
	@SessionName  VARCHAR(128) = NULL --'AlwaysOn_health'
  , @csessionname VARCHAR(128);

CREATE TABLE #SessionPaths
	(
		SessionName VARCHAR(128)
	  , XEFilePath	VARCHAR(256)
	  , SelectPhase VARCHAR(24)
	);

DECLARE xessions CURSOR LOCAL STATIC FORWARD_ONLY READ_ONLY FOR
	SELECT
				 ses.name
		FROM	 sys.server_event_sessions ses
		WHERE	 ses.name = ISNULL(@SessionName, ses.name)
		ORDER BY ses.name;

OPEN xessions;

FETCH NEXT FROM xessions
INTO
	@csessionname;

WHILE @@FETCH_STATUS = 0
	BEGIN

		IF EXISTS
			(
				SELECT
								   1
					FROM		   sys.server_event_sessions	   ses
						INNER JOIN sys.server_event_session_fields sesf
							ON ses.event_session_id = sesf.event_session_id
					WHERE		   sesf.name = 'filename'
								   AND ses.name = @csessionname
			)
			BEGIN
				IF
					(
						SELECT
										   CHARINDEX('\', CONVERT(VARCHAR(256), sesf.value))
							FROM		   sys.server_event_sessions	   ses
								INNER JOIN sys.server_event_session_fields sesf
									ON ses.event_session_id = sesf.event_session_id
							WHERE		   sesf.name = 'filename'
										   AND ses.name = @csessionname
					) &gt; 0
					BEGIN
						INSERT INTO #SessionPaths
							(
								SessionName
							  , XEFilePath
							  , SelectPhase
							)
							SELECT
											   ses.name													 AS SessionName
											 , LEFT(CONVERT(VARCHAR(256), sesf.value), LEN(CONVERT(VARCHAR(256), sesf.value))
																					   - CHARINDEX(
																									  '\'
																									, REVERSE(CONVERT(
																														 VARCHAR(256)
																													   , sesf.value
																													 )
																											 )
																								  ) + 1) AS XEFilePath
											 , 'Phase1'
								FROM		   sys.server_event_sessions	   ses
									INNER JOIN sys.server_event_session_fields sesf
										ON ses.event_session_id = sesf.event_session_id
								WHERE		   sesf.name = 'filename'
											   AND ses.name = @csessionname;
					END;
				ELSE
					BEGIN
						INSERT INTO #SessionPaths
							(
								SessionName
							  , XEFilePath
							  , SelectPhase
							)
							SELECT				DISTINCT
												cte1.SessionName
											  , CASE
													WHEN RIGHT(LEFT(cte1.targetvalue, LEN(cte1.targetvalue)
																					  - CHARINDEX('\', REVERSE(cte1.targetvalue)) + 1), 1) = '\'
														 THEN LEFT(cte1.targetvalue, LEN(cte1.targetvalue)
																					 - CHARINDEX('\', REVERSE(cte1.targetvalue)) + 1)
													ELSE LEFT(@ErrorPath, LEN(@ErrorPath) - CHARINDEX('\', REVERSE(@ErrorPath)) + 1)
												END AS XEFilePath
											  , CASE
													WHEN RIGHT(LEFT(t2.file_name, LEN(t2.file_name)
																				  - CHARINDEX('\', REVERSE(t2.file_name)) + 1), 1) = '\'
														 THEN 'Phase2'
													ELSE 'FailSafe'
												END
								FROM
												(
													SELECT
																	   REPLACE(CONVERT(NVARCHAR(128), sesf.value), '.xel', '*.xel') AS targetvalue
																	 , ses.name														AS SessionName
														FROM		   sys.server_event_sessions	   ses
															INNER JOIN sys.server_event_session_fields sesf
																ON ses.event_session_id = sesf.event_session_id
														WHERE		   sesf.name = 'filename'
																	   AND ses.name = @csessionname
												)																	cte1
									OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue, NULL, NULL, NULL) t2;

					END;


			END;

		FETCH NEXT FROM xessions
		INTO
			@csessionname;
	END;
CLOSE xessions;
DEALLOCATE xessions;

SELECT
		 *
	FROM #SessionPaths sp;

DROP TABLE #SessionPaths;</pre><p>One of the things I wanted to accomplish with this update was to find the correct path for all of the sessions on the server. As mentioned in the previous article, sometimes there are complications with that. Due to the way log files can be specified for an XE session, behaviors can be a bit funky sometimes when trying to parse the correct paths. Due to those problems, I couldn&#8217;t quite short-cut the logic in the previous script and had to do the less desirable thing and create a cursor.</p>
<p>In addition to the cursor, I threw in a fix for when a full path is not declared for the session (at the time of creation) and the session was subsequently never started. In these odd cases, the script had been returning an empty result set and thus was not working properly. Now, it is fixed and here is an example of the output.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3.png"><img loading="lazy" class="aligncenter size-large wp-image-5329" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3-1024x312.png" alt="" width="560" height="171" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3-1024x312.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3-300x91.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3-768x234.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/05/filepaths_v3.png 1332w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The third column in this result set is purely for informational purposes so I could determine at which point the file path was being derived. For the 30+ sessions running on my test instance, most paths are resolved via the first select. In the image, that is denoted by the label &#8220;Phase1&#8221; and circled in red. The system_health session happened to be running, but did not have a full path declared so it fell into the &#8220;Phase2&#8221; resolution group and is circled in blue. The last group includes those cases where a path could not be resolved for any number of reasons so they fall to the &#8220;FailSafe&#8221; grouping and an example is circled in green in the image.</p>
<h3>Why</h3>
<p>Truth be told, there is a method to short cut this script and get the results faster but I felt it would be less accurate. I could obviously just default to the &#8220;FailSafe&#8221; group automatically if a full path is not defined in the session creation. Would that be accurate though? Most of the time it would be accurate, but then there are the edge cases where occasionally we forget that something has changed. One such case of this is if after the session is created, you decide the SQL Server log files needs to be moved from the default path (this is where the XEL files default to if no path is defined)?</p>
<p>I have run across multiple scenarios where the logs were required (both technical as well as political) to be <a href="http://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/">moved from the default location</a>. Ideally, this move occurs prior to server startup. When the log file path is changed, the logs are not moved automatically to the new location. This, for me, is a case where it is best to be thorough rather than snake bit. I also like to document these things so I can compare them later if necessary.</p>
<p>Alternatively, here is the just good enough to pass muster version of that script.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* or the "good enough" version */
DECLARE @ErrorPath VARCHAR(256) = CONVERT(VARCHAR(256), SERVERPROPERTY('ErrorLogFileName'));

SELECT	DISTINCT
		cte1.SessionName
	  , CASE
			WHEN RIGHT(LEFT(cte1.targetvalue, LEN(cte1.targetvalue) - CHARINDEX('\', REVERSE(cte1.targetvalue)) + 1), 1) = '\'
				 THEN LEFT(cte1.targetvalue, LEN(cte1.targetvalue) - CHARINDEX('\', REVERSE(cte1.targetvalue)) + 1)
			ELSE LEFT(@ErrorPath, LEN(@ErrorPath) - CHARINDEX('\', REVERSE(@ErrorPath)) + 1)
		END AS XEFilePath
	  , CASE
			WHEN RIGHT(LEFT(cte1.targetvalue, LEN(cte1.targetvalue) - CHARINDEX('\', REVERSE(cte1.targetvalue)) + 1), 1) = '\'
				 THEN 'Quick'
			ELSE 'FailSafe'
		END
	FROM
		(
			SELECT
							   REPLACE(CONVERT(NVARCHAR(128), sesf.value), '.xel', '*.xel') AS targetvalue
							 , ses.name														AS SessionName
				FROM		   sys.server_event_sessions	   ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE		   sesf.name = 'filename'
		) cte1;</pre><p>&nbsp;</p>
<h3>Conclusion</h3>
<p>In the article today, I have shown some of the internals to retrieving file paths for Extended Event Sessions. I dove into metadata to pull out the path for the session and discussed some concerns for some of these methods. In the end, you have a few viable options to help retrieve the file path in a more consistent fashion.</p>
<p>To read more about Extended Events, I recommend <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">this series of articles</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5327" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/05/20/event-log-file-paths/">Event Log File Paths</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/05/20/event-log-file-paths/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Puzzles and Daily Trivia</title>
		<link>https://jasonbrimhall.info/2019/05/14/puzzles-and-daily-trivia/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=puzzles-and-daily-trivia</link>
					<comments>https://jasonbrimhall.info/2019/05/14/puzzles-and-daily-trivia/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 14 May 2019 21:18:36 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5312</guid>

					<description><![CDATA[<p>One of my favorite database automations is to send trivia style questions daily. This helps me to mentor and assess other dba talent within an organization without being too aggressive. Not only can a database be used for automation but it can also be used for numerous other automations. Beyond being highly useful for automation and training, there is also the possibility of using TSQL to solve puzzles like Sudoku puzzles.</p>
The post <a href="https://jasonbrimhall.info/2019/05/14/puzzles-and-daily-trivia/">Puzzles and Daily Trivia</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>TSQL Tuesday</h2>
<p>The second Tuesday of the month comes to us a little early this month. That means it is time again for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<h2>The Why?</h2>
<p>This month, Matthew Mcgiffen<span class="TweetAuthor-decoratedName"><span class="TweetAuthor-name TweetAuthor-name--flex Identity-name customisable-highlight" title="Malathi Mahadevan" data-scribe="element:name"> (<a href="https://matthewmcgiffen.com/" target="_blank" rel="noopener noreferrer">b</a> | <a href="https://twitter.com/MattMcgiffen" target="_blank" rel="noopener noreferrer">t</a>)</span></span> <a href="https://matthewmcgiffen.com/2019/05/07/t-sql-tuesday-114-puzzle-party/">invites us</a> to come to a little puzzle party for our TSQL Tuesday party. Bring your favorite brain teaser, puzzle, questions, or interesting and complex TSQL problems/solutions.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/01/db_puzzlepiece.png"><img loading="lazy" class="wp-image-4959 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2010/01/db_puzzlepiece.png" alt="" width="134" height="150" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/01/db_puzzlepiece.png 384w, https://jasonbrimhall.info/wp-content/uploads/2010/01/db_puzzlepiece-267x300.png 267w, https://jasonbrimhall.info/wp-content/uploads/2010/01/db_puzzlepiece-45x50.png 45w" sizes="(max-width: 134px) 85vw, 134px" /></a>This ties pretty nicely into the topic from last month (well at least for me). If you recall, last month Todd asked all of us to share some of our uses for <a href="https://toddkleinhans.wordpress.com/2019/04/04/t-sql-tuesday-113-what-do-you-use-databases-for/">databases in our personal lives</a>. I submitted my article <a href="http://jasonbrimhall.info/2019/04/09/passion-challenges-and-sql-2/">here</a>, but forgot about one of my favorite uses for a database in my personal life &#8211; a daily trivia set about SQL Server.</p>
<p>So, why not elaborate on that database a bit today. Almost like a two for one. However, there is one little quick departure I want to make. My first puzzle solved with TSQL was written about many moons ago and can be found <a href="http://jasonbrimhall.info/2011/08/23/tsql-sudoku-ii/">here</a>.</p>
<h3>TSQL Challenges</h3>
<p>A long time ago, Jacob Sebastian ran regular challenges involving TSQL to get you to think about ways to solve problems using TSQL. The site is no longer available, but challenge #97 was about solving Sudoku puzzles. Here is my <a href="http://jasonbrimhall.info/2011/08/23/tsql-sudoku-ii/">solution</a> to that particular challenge. A little TSQL and a bit of the black arts and there is a nifty little solution. Even though I have this little trick in the bag, I still solve the Sudoku puzzles the hard way.</p>
<p>What a nice little stroll down memory lane there. That solution alone could satisfy the <a href="http://jasonbrimhall.info/wp-content/uploads/2019/05/qotd_db.png"><img loading="lazy" class=" wp-image-5320 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/05/qotd_db.png" alt="" width="189" height="265" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/05/qotd_db.png 275w, https://jasonbrimhall.info/wp-content/uploads/2019/05/qotd_db-214x300.png 214w, https://jasonbrimhall.info/wp-content/uploads/2019/05/qotd_db-36x50.png 36w" sizes="(max-width: 189px) 85vw, 189px" /></a>request for this TSQL Tuesday. Alas, we won&#8217;t stop there!</p>
<h3>QOTD</h3>
<p>Several years ago, I put together a little database to help with daily trivia questions. The database is a simple design and had a primary function to help teach SQL Server facts and internals to those with varying levels of DBA experience as well as helpdesk members. That said, the topic of questions doesn&#8217;t have to be SQL specific &#8211; it was my primary use.</p>
<p>With just a few tables and a few procs, I have a database that I can use to create questions, track responses from participants, and email questions and answers to participants on a daily basis &#8211; automatically. If I run out of questions, I just add more to the table. Nothing super complex there.</p>
<p>What this offers me is a mechanism to mentor multiple people without the burnout and while also gauging their true interest level in improving their SQL skill set.</p>
<h3>Wrapping it Up</h3>
<p>One of my favorite database automations is to send trivia style questions daily. This helps me to mentor and assess other dba talent within an organization without being too aggressive. Not only can a database be used for automation but it can also be used for numerous other automations. Beyond being highly useful for automation and training, there is also the possibility of using TSQL to solve puzzles like Sudoku puzzles.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5312" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/05/14/puzzles-and-daily-trivia/">Puzzles and Daily Trivia</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/05/14/puzzles-and-daily-trivia/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Database Offline &#8211; Redux</title>
		<link>https://jasonbrimhall.info/2019/04/15/database-offline-redux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-offline-redux</link>
					<comments>https://jasonbrimhall.info/2019/04/15/database-offline-redux/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 15 Apr 2019 13:13:07 +0000</pubDate>
				<category><![CDATA[DatabaseMasters Syndication]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5302</guid>

					<description><![CDATA[<p>A database can be offline at the time that you take over responsibility of the database. You will be asked when it was taken offline. This script will help you get a reasonable deduction for that offline event in the absence of better data.</p>
The post <a href="https://jasonbrimhall.info/2019/04/15/database-offline-redux/">Database Offline – Redux</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-5303 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/04/db_red_unplugged.png" alt="" width="302" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/04/db_red_unplugged.png 858w, https://jasonbrimhall.info/wp-content/uploads/2019/04/db_red_unplugged-300x203.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/04/db_red_unplugged-768x519.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/04/db_red_unplugged-50x34.png 50w" sizes="(max-width: 302px) 85vw, 302px" /></a></p>
<p>I have written a couple articles showing how to <a href="http://jasonbrimhall.info/2018/11/13/audit-database-offline-events/">audit database offline events via the default trace</a> as well as via <a href="http://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/">Extended Events</a>. These are great for a more proactive approach. Sometimes the proactive approach is just not plausible for the given circumstances. A good example of this is when you inherit servers (e.g. new client, new project, new job) and there are databases on the server that were taken offline prior to your inheritance.</p>
<p>In a situation like this, you need to find out when the databases were taken offline, but you are somewhat limited by the data available to you for your research purposes. The default trace has rolled beyond the retention point for your server for events that were trapped. Setting up an Extended Events session would be less than helpful given the databases are already offline. So we must find an alternative to finding approximately when the databases were taken offline.</p>
<h2>Alternatives</h2>
<p>If your predecessor leaves you with a database that has been taken offline and no documentation about it, there is an alternative to find the approximate time it was taken offline &#8211; using TSQL. Granted, you could explore the file system and make the same sort of guess based on the file modified date. Data people generally prefer some sort of script and a script that is native to their language (tsql).</p>
<p>So, let&#8217;s take a look at a viable option for figuring out the mystery behind your database that has been set offline with no good info surrounding it.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* requires that the DB have had at least one full backup*/
DECLARE @Numdays INT = 1; 
--minute, d for days

SELECT
				   d.name					 AS DBName
				 , mf.name					 AS filelogicalname
				 , d.create_date
				 , mf.differential_base_time AS DBOfflineDate --utc time
	FROM		   sys.master_files mf
		INNER JOIN sys.databases	d
			ON mf.database_id = d.database_id
	WHERE		   mf.differential_base_time &lt; DATEADD(DAY,@Numdays * -1,GETUTCDATE())
		AND d.state_desc = 'offline'
	ORDER BY	   mf.differential_base_time;</pre><p>Running this query, I see the following on my test server:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles.png"><img loading="lazy" class="aligncenter size-large wp-image-5307" src="http://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles-1024x121.png" alt="" width="560" height="66" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles-1024x121.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles-300x36.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles-768x91.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles-50x6.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles.png 1326w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Note that this query uses GETUTCDATE. The differential_base_time column in sys.master_files is in UTC time. Thus, in order to compare properly, we need to ensure we use a UTC datestamp for comparison. Also, of note, this query doesn&#8217;t work if there is no full database backup for the database in question. Who doesn&#8217;t backup their databases though, right? No seriously, you really should.</p>
<p>Since this is my test server and I am well prepared, I just so happen to have an <a href="http://bit.ly/2FpLz6u">XEvent session</a> running that tracks the offline events that I can use to compare the results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe.png"><img loading="lazy" class="aligncenter size-large wp-image-5308" src="http://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe-1024x269.png" alt="" width="560" height="147" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe-1024x269.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe-300x79.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe-768x202.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/04/offline_masterfiles_xe-50x13.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Yes, there is a bit of variance in the actual database offline event and the differential_base_time column. This variance is due to timing of the backup and the actual offline event. Again, this is about finding an approximate time of when the database was taken offline as a viable alternative when other data is not really available.</p>
<h2>Conclusion</h2>
<p>We all aspire to having a perfect database environment where nothing surprising or unexpected happens. Unfortunately, that is the desire of dreams and fairy tales. The unexpected will happen. A database can be offline at the time that you take over responsibility of the database. You will be asked when it was taken offline. This script will help you get a reasonable deduction for that offline event in the absence of better data.</p>
<p>Extended Events is a powerful tool to help in troubleshooting and tuning your environment. I recommend investing a little time in reading the <a href="http://bit.ly/XE60Days">60 day series</a> about Extended Events. This is not a short series but is designed to provide an array of topics to help learn the tool over time. Don&#8217;t forget to go back and read the companion article showing how to <a href="http://bit.ly/2qISjlL">audit these events via the default trace</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5302" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/04/15/database-offline-redux/">Database Offline – Redux</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/04/15/database-offline-redux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Making Databases Personal</title>
		<link>https://jasonbrimhall.info/2019/04/09/making-databases-personal/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=making-databases-personal</link>
					<comments>https://jasonbrimhall.info/2019/04/09/making-databases-personal/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 09 Apr 2019 19:33:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5292</guid>

					<description><![CDATA[<p>If you can use a database to create automation routines to help sustain your work life, you can certainly do the same to sustain your personal life. Databases are an essential piece of both my personal and professional life.</p>
The post <a href="https://jasonbrimhall.info/2019/04/09/making-databases-personal/">Making Databases Personal</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>TSQL Tuesday</h2>
<p>The second Tuesday of the month comes to us a little early this month. That means it is time again for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<h2>The Why?</h2>
<p>This month, Todd Kleinhans<span class="TweetAuthor-decoratedName"><span class="TweetAuthor-name TweetAuthor-name--flex Identity-name customisable-highlight" title="Malathi Mahadevan" data-scribe="element:name"> (<a href="https://toddkleinhans.wordpress.com/" target="_blank" rel="noopener noreferrer">b</a> | <a href="https://twitter.com/toddkleinhans" target="_blank" rel="noopener noreferrer">t</a>)</span></span> <a href="https://toddkleinhans.wordpress.com/2019/04/04/t-sql-tuesday-113-what-do-you-use-databases-for/">invites us</a> to share something personal about ourselves. Well sort of. The invitation to each of us is to share a little about databases that we use in our personal lives or that we have created in our personal lives to help us in some fashion or another.</p>
<p><img loading="lazy" class="wp-image-5295 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/04/dizzy_emoji.png" alt="" width="196" height="168" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/04/dizzy_emoji.png 775w, https://jasonbrimhall.info/wp-content/uploads/2019/04/dizzy_emoji-300x257.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/04/dizzy_emoji-768x657.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/04/dizzy_emoji-50x43.png 50w" sizes="(max-width: 196px) 85vw, 196px" />I think this is a really cool idea. Data and databases are very integrated into my life. The integration is enough that it would be difficult to un-blur the line where personal life and professional life begins when talking about data and databases.</p>
<p>Take a moment and reflect on the importance of data and databases within your life. At a minimum, you have taken the approach that data is your profession of choice and hopefully it is a career for you and not just a job.</p>
<p>If you have taken it down the career path, then you probably study your craft in your personal time to try and make yourself better at your trade-craft. Often times, if you are like me, these studies lead to trial and error, experiments, and possibly rabbit holes. If data is just a J-O-B, it is quite likely none of this will apply to you. Those are the types that fall into a category Steve Jones <a href="https://www.sqlservercentral.com/editorials/youre-not-really-that-good-at-sql-server-submitted">wrote about recently</a>, and I would urge you to change that sooner rather than later. (Side note, I read that article as if it applied to me directly because I really do need to learn and practice more about my craft too!)</p>
<h3>Personal Databases</h3>
<p>Over the years, I have had sooo many personal databases that I have created for one reason or another. Some still need to be finished. Here are some examples of what I use a database for in my personal life.</p>
<p><strong>Finances</strong>: A simple little database to track (sort of like a checkbook yes) credits and debits. More importantly, it tracked bills and due dates with dollar amounts for each bill. This is useful both for reminders for bills but also to see if there are any noteworthy trends with spending or increased costs. Now, many banking (and credit card) sites offer the same types of services &#8211; so long as the spending is done with their card.</p>
<p><strong>Exercise</strong>: Back in the day, I tracked all of my activities in a database. I would track the duration, activity type, effort level and various biometric measures after each activity. Once again, this is something that is now tracked by so many different apps and databases that it seems counter productive to maintain my own system in favor of something that works more easily on a wearable device.</p>
<p>I have also previously done databases to inventory books, movies, track personal studies and link thoughts about studies from day to day, or even track routine chores (calendar reminders don&#8217;t offer much for tracking details). The short of it is, a database can be created to manage so many things as a part of everyday personal life.</p>
<p>&nbsp;</p>
<h3>Wrapping it Up</h3>
<p>If you can use a database to create automation routines to help sustain your work life, you can certainly do the same to sustain your personal life. Databases are an essential piece of both my personal and professional life. Not only do I use them to create automation (such as <a href="https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/">this</a> or <a href="http://jasonbrimhall.info/2014/01/14/t-sql-tuesday-050-automating-database-restores/">this</a>) for things, but I stand databases up to test numerous things from corruption to recovery to performance tuning to help improve my personal abilities and craft in the realm of data.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5292" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/04/09/making-databases-personal/">Making Databases Personal</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/04/09/making-databases-personal/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Indexed Views &#8211; Performance Panacea or Plight</title>
		<link>https://jasonbrimhall.info/2019/04/01/indexed-views-performance-panacea-or-plight/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=indexed-views-performance-panacea-or-plight</link>
					<comments>https://jasonbrimhall.info/2019/04/01/indexed-views-performance-panacea-or-plight/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 01 Apr 2019 12:42:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5221</guid>

					<description><![CDATA[<p>An indexed view is a view where the result set from the query (the view definition) becomes materialized in lieu of the virtual table result set of a standard (non-indexed) view. Many times we see that an indexed view would be created to help improve performance. Far too often, an indexed view is created without consideration for the costs of the indexed view.</p>
The post <a href="https://jasonbrimhall.info/2019/04/01/indexed-views-performance-panacea-or-plight/">Indexed Views – Performance Panacea or Plight</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://bit.ly/SQLBack2Basics"><img loading="lazy" class="alignright wp-image-5232" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night-1024x500.png" alt="" width="266" height="130" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night-1024x500.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night-300x147.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night-768x375.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night-50x24.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/binocular_night.png 1588w" sizes="(max-width: 266px) 85vw, 266px" /></a>Indexed View(s)</h2>
<p>An indexed view is a view where the result set from the query (the view definition) becomes materialized in lieu of the virtual table result set of a standard (non-indexed) view. Many times we see that an indexed view would be created to help improve performance. Far too often, an indexed view is created without consideration for the costs of the indexed view. In this article, I hope to cover some of the more important costs that are frequently overlooked when considering an indexed view as a performance panacea.</p>
<h3>The Setup</h3>
<p>To demonstrate the overlooked costs of indexed views, I have decided to use the AdventureWorks2014 database (if you don&#8217;t have this sample database, you can get your copy <a href="http://bit.ly/Aworksdb">here</a>). I will create a view in that database and then I will add a few indexes to that view. Prior to sharing the entire setup, and like all good DBAs, I need to first grab a baseline. For this baseline, I am doing nothing terribly complex. I will just grab table sizes and storage information for the entire database.</p>
<p>Here are my results for the size of the objects within the AdventureWorks2014 database:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5231" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start-1024x162.png" alt="" width="560" height="89" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start-1024x162.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start-300x47.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start-768x121.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_start.png 1927w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>These results show that the largest object in the database happens to be the Person.Person table at just about 30MB. Not terribly large, but the database is not terribly large as a whole. Let&#8217;s see what happens when I add a materialized view, based on the Person.Person table, to the mix. Here is the definition of that view along with the indexes that I will add to help the performance of some essential production related queries.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [AdventureWorks2014];
GO

CREATE VIEW [Person].[vPerson]
WITH SCHEMABINDING
AS
	SELECT pp.BusinessEntityID
			, pp.FirstName
			, pp.LastName
			, sp.[StateProvinceID]
			, sp.[StateProvinceCode]
			, sp.[IsOnlyStateProvinceFlag]
			, sp.[Name] AS [StateProvinceName]
			, sp.[TerritoryID]
			, cr.[CountryRegionCode]
			, cr.[Name] AS [CountryRegionName]
			, pbe.AddressTypeID
			, pp.AdditionalContactInfo
			, pp.Demographics
		FROM [Person].[StateProvince] sp
			INNER JOIN [Person].[CountryRegion] cr
				ON sp.[CountryRegionCode] = cr.[CountryRegionCode]
			INNER JOIN Person.Address pa
				ON sp.StateProvinceID = pa.StateProvinceID
			INNER JOIN Person.BusinessEntityAddress pbe
				ON pbe.AddressID = pa.AddressID
			INNER JOIN Person.Person pp
				ON pp.BusinessEntityID = pbe.BusinessEntityID
		WHERE pbe.AddressTypeID = 2;

GO


CREATE UNIQUE CLUSTERED INDEX CI_vPersonID ON Person.vPerson(BusinessEntityID);

CREATE INDEX IX_vPersonName ON Person.vPerson(FirstName,LastName);
CREATE INDEX IX_vPersonState ON Person.vPerson(FirstName,LastName,StateProvinceID,StateProvinceCode,StateProvinceName);</pre><p>After executing all of that code to create this new view with its indexes, I have the following size results:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5230" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post-1024x162.jpg" alt="" width="560" height="89" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post-1024x162.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post-300x48.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post-768x122.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post-50x8.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/Tablesize_post.jpg 1923w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>The creation of this view has chewed up a bunch of storage. It has jumped right up to the number two spot on the biggest objects list within this database. You can see that differences by comparing the highlighted rows to the previous image. The vPerson view is highlighted in red in this second image to help point it out quickly.</p>
<p>Surely this must be a contrived example and people don&#8217;t really do this in the real world, right? The answer to that is simply: NO! It DOES happen. I see situations like this all too often. Far too often, large text fields are added to an indexed view to make retrieval faster. I have mimicked that by adding in two XML columns from the Person.Person table. This is definitely overkill because a simple join back to the table based on the BusinessEntityID <a href="http://bit.ly/XE60Days"><img loading="lazy" class="alignright wp-image-5132" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion.png" alt="" width="241" height="241" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion.png 479w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-144x144.png 144w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-65x65.png 65w" sizes="(max-width: 241px) 85vw, 241px" /></a>would get me those two columns. All I have effectively done is duplicated data being stored and I have achieved that at the low low cost of increased storage of 25% for this small database. If you are curious, the column count between the Person.Person table and this new view is 13 columns each.</p>
<p>I call the 25% increase storage cost a significant increase. An increase of 25% in storage for a single materialized view is not an uncommon occurrence. I have seen multi-terabyte databases with 25% of the total data storage being caused by a single view. If you are tight on storage, any unexpected data volume increase can cause a non-linear growth in data requirements to occur just because of the presence of indexed views. Take that into consideration when presented with an option to either performance tune the code or to take a short-cut and create an indexed view.</p>
<h3>Band-aid Performance</h3>
<p>I alluded to the use of indexed views as a cog to help improve performance. This is done by taking the query that sucks and turning it into a view. The thought is that it will run faster because an index is created specifically for that data set. Generally the performance gains from using an indexed view, to camouflage the bad query, are seen when the query is complex. Unfortunately, the query I provided for this article is not terribly complex. Due to the simplicity of the first example, let&#8217;s look first at the execution plan for another query that runs terribly slow but is also not terribly complex:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5225" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew-1024x801.png" alt="" width="560" height="438" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew-1024x801.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew-300x235.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew-768x601.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew-50x39.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/idxvieworigplannew.png 1382w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>There are a few table spools and index scans. The most costly operator of the bunch appears to be a merge join with a many-to-many join operation. The indexed view in this case does give me a very significant improvement on this query (look at that estimated cost and then the estimated number of rows). What if I could tune the query a little and avoid the all of storage cost? Let&#8217;s see!</p>
<p>Consider the base query for this new view:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT pp.BusinessEntityID
			, pp.FirstName
			, pp.LastName
			, sp.[StateProvinceID]
			, sp.[StateProvinceCode]
			, sp.[IsOnlyStateProvinceFlag]
			, sp.[Name] AS [StateProvinceName]
			, sp.[TerritoryID]
			, cr.[CountryRegionCode]
			, cr.[Name] AS [CountryRegionName]
			, pbe.AddressTypeID
			, pp.AdditionalContactInfo
			, pp.Demographics
		FROM [Person].[StateProvince] sp 
			INNER JOIN [Person].[CountryRegion] cr
				ON RTRIM(LTRIM(sp.[CountryRegionCode])) = RTRIM(LTRIM(cr.[CountryRegionCode]))
			INNER JOIN Person.Address pa
				ON RTRIM(LTRIM(sp.StateProvinceID)) = RTRIM(LTRIM(pa.StateProvinceID))
			INNER JOIN Person.BusinessEntityAddress pbe
				ON RTRIM(LTRIM(pbe.AddressID)) = RTRIM(LTRIM(pa.AddressID))
			INNER JOIN Person.Person pp
				ON RTRIM(LTRIM(pp.BusinessEntityID)) = RTRIM(LTRIM(pbe.BusinessEntityID))
		WHERE RTRIM(LTRIM(pbe.AddressTypeID)) = 2;</pre><p>Looking at the query, you may be asking yourself why use so many trim functions on each of the joins? This is an extreme that can be easily fixed. None of the fields in the joins should need to be trimmed since they are all numeric in this case. Starting there and removing all of the function use in the joins should provide significant improvements in query speed and without the use of a view. Testing it out would yield similar performance results to the first view in this article. This small change would cause the query to complete in 1 second compared to about 90 seconds. That is a huge gain, and without the added cost of increased storage use.</p>
<p>Do I really see stuff like this in the field? Yes! Spending a little time to fix the root of the problem rather than looking for a quick fix and performance can be spectacular. There are times, though, that an indexed view may be an absolute requirement. That would be perfectly fine. There are times when it is warranted and there is no way around it. If an indexed view is an absolute must, then there are a couple more considerations to be taken into account.</p>
<h3>Disappearing Act</h3>
<p>I showed previously that the indexed view requires storage space and showed that the new view created quickly claimed its place as the second largest object within the database. Now, to stage the next segment, I will show once again that the indexes are present and consuming disk space. This can be shown via the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT o.name AS ObjName
		, i.name AS IdxName
		, SUM(ps.page_count) AS page_count
		, SUM(ps.record_count) AS record_count
		, SUM(ps.page_count) / 128.0 AS SizeMB
	FROM sys.indexes i
		INNER JOIN sys.objects o
			ON i.object_id = o.object_id
		INNER JOIN sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL,
													'detailed') ps
			ON ps.object_id = o.object_id
	WHERE o.name LIKE 'vperson%'
	GROUP BY o.name
		, i.name;</pre><p>And the results of that query should look something like the following (quick reminder that I created a new indexed view for the second demo and these results will be based on that second view):</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5224" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2-1024x231.jpg" alt="" width="560" height="126" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2-1024x231.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2-300x68.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2-768x173.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2-50x11.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/vperson2.jpg 1052w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Now that we know the index is present and consuming space, time to make a change to the view and see what happens. I am proceeding under the premise that I have determined that including the two XML columns in the view are completely unnecessary and are the cause of too much space consumption. I can reap the benefits of the view at a fraction of the cost if I ALTER the view and remove those columns. So I will proceed by issuing the following ALTER statement:</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER VIEW [Person].[vPerson2]
WITH SCHEMABINDING
AS
	SELECT pp.BusinessEntityID
			, pp.FirstName
			, pp.LastName
			, sp.[StateProvinceID]
			, sp.[StateProvinceCode]
			, sp.[IsOnlyStateProvinceFlag]
			, sp.[Name] AS [StateProvinceName]
			, sp.[TerritoryID]
			, cr.[CountryRegionCode]
			, cr.[Name] AS [CountryRegionName]
			, pbe.AddressTypeID
		FROM [Person].[StateProvince] sp 
			INNER JOIN [Person].[CountryRegion] cr
				ON RTRIM(LTRIM(sp.[CountryRegionCode])) = RTRIM(LTRIM(cr.[CountryRegionCode]))
			INNER JOIN Person.Address pa
				ON RTRIM(LTRIM(sp.StateProvinceID)) = RTRIM(LTRIM(pa.StateProvinceID))
			INNER JOIN Person.BusinessEntityAddress pbe
				ON RTRIM(LTRIM(pbe.AddressID)) = RTRIM(LTRIM(pa.AddressID))
			INNER JOIN Person.Person pp
				ON RTRIM(LTRIM(pp.BusinessEntityID)) = RTRIM(LTRIM(pbe.BusinessEntityID))
		WHERE RTRIM(LTRIM(pbe.AddressTypeID)) = 2
;

GO</pre><p>Take note of how long this ALTER command takes to complete &#8211; nearly instantaneous.  That rocks! Right? Let&#8217;s look at the indexes to make sure they are still in working order and don&#8217;t require a defrag. Based on that, I will re-run that query to check the indexes and sizes &#8211; for giggles.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT o.name AS ObjName
		, i.name AS IdxName
		, SUM(ps.page_count) AS page_count
		, SUM(ps.record_count) AS record_count
		, SUM(ps.page_count) / 128.0 AS SizeMB
	FROM sys.indexes i
		INNER JOIN sys.objects o
			ON i.object_id = o.object_id
		INNER JOIN sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL,
													'detailed') ps
			ON ps.object_id = o.object_id
	WHERE o.name LIKE 'vperson%'
	GROUP BY o.name
		, i.name;</pre><p>This time when the query completes, I get a nice little surprise: I no longer have any indexes on that view. Changing the view definition instantly drops any indexes that were built on that view. If this is done in a production system, imagine the implications and problems that could arise.</p>
<h3>Conclusion</h3>
<p>In this article, I have covered indexed views and three different considerations that are often overlooked when looking to implement a materialized view. The three considerations for indexed views, as discussed, are: storage, changes to the view, and the band-aid effect. Overlooking the cost of storage can have serious repercussions on the production environment. Implementing an indexed view without attempting to tune the code first could lead to overlooking the storage cost and could end up just being a waste of resources. The last tidbit is that any change to an indexed view will drop the indexes. That is an easily overlooked feature of indexed views. If you forget to recreate the indexes on the view after making changes, you could be looking at a production outage.</p>
<p>There are a couple more critical considerations for indexed views that are often overlooked as well. These additional considerations are blocking, deadlocking, and maintenance. These considerations will be discussed further in a future article.</p>
<p>For more reading enjoyment try the <a href="http://jasonbrimhall.info/tag/back-to-basics/">Back to Basics</a> or <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Xevents series</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5221" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/04/01/indexed-views-performance-panacea-or-plight/">Indexed Views – Performance Panacea or Plight</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/04/01/indexed-views-performance-panacea-or-plight/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Connect To SQL Server &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2019/03/27/connect-to-sql-server-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=connect-to-sql-server-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2019/03/27/connect-to-sql-server-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 27 Mar 2019 13:13:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5249</guid>

					<description><![CDATA[<p>The first critical task any data professional should ever learn how to do is how to connect to SQL Server. Without a connection to SQL Server, there is barely anything one could do to be productive in the data professional world (for SQL Server).</p>
The post <a href="https://jasonbrimhall.info/2019/03/27/connect-to-sql-server-back-to-basics/">Connect To SQL Server – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/tag/back-to-basics/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>The first critical task any data professional should ever learn how to do is how to connect to SQL Server. Without a connection to SQL Server, there is barely anything one could do to be productive in the data professional world (for SQL Server).</p>
<p>Yet, despite the commonality of this requirement and ease of the task, I find that there is frequent need to retrain professionals on how to connect to SQL Server. This connection could be attempted from any of the current options but for some reason it still perplexes many.</p>
<p>Let&#8217;s look at just how easy it is (should be) to connect to SQL Server (using both SQL Auth and Windows Auth).</p>
<h2>Simplicity</h2>
<p>First let&#8217;s take a look at the dialog box we would see when we try to connect to a server in SQL Server Management Studio (SSMS).</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5252" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog-1024x678.png" alt="" width="560" height="371" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog-1024x678.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog-300x199.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog-768x508.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/connectsql_dialog.png 1192w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Circled in red we can see the two types of authentication I would like to focus on: &#8220;Windows Authentication&#8221; and &#8220;SQL Server Authentication&#8221;. These are both available from the dropdown box called Authentication. The default value here is &#8220;Windows Authentication&#8221;.</p>
<p>If I choose the default value for authentication or &#8220;Windows Authentication&#8221;, I only need to click on the connect button at the bottom of that same window. Upon closer inspection, it becomes apparent that the fields &#8220;User name:&#8221; and &#8220;Password:&#8221; are disabled and cannot be edited when this default value is selected. This is illustrated in the next image.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5254" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2-1024x670.png" alt="" width="560" height="366" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2-1024x670.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2-300x196.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2-768x503.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/disabled_authpair2.png 1205w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Notice that the fields circled in red are greyed out along with their corresponding text boxes. This is normal and is a GOOD thing. Simply click the connect button circled in green and then you will be connected if you have permissions to the specific server in the connection dialog.</p>
<p>Complicating things a touch is the &#8220;SQL Server Authentication&#8221;. This is where many people get confused. I see many people trying to enter windows credentials in this authentication type. Sure, we are authenticating to SQL Server, but the login used in this method is not a windows account. The account to be used for this type of authentication is strictly the type that is created explicitly inside of SQL Server. <a href="https://docs.microsoft.com/en-us/sql/t-sql/statements/create-login-transact-sql?view=sql-server-2017">This is a type of login where the principal name and the password are both managed by SQL Server</a>.</p>
<p>Let&#8217;s take a look at an example here.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5257" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login-1024x676.png" alt="" width="560" height="370" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login-1024x676.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login-300x198.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login-768x507.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/sql_login.png 1205w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Notice here that the text boxes are no longer greyed out and I can type a login and password into the respective boxes. Once done, I then click the &#8220;Connect&#8221; button and I will be connected (again, presuming I have been granted access and I typed the user name and password correctly).</p>
<p>What if I attempt to type a windows username and password into these boxes?</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5258" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth-1024x678.png" alt="" width="560" height="371" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth-1024x678.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth-300x199.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth-768x508.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/domainuid_insqlauth.png 1198w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>If I click connect on the preceding image, I will see the following error.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5259" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed-1024x523.png" alt="" width="560" height="286" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed-1024x523.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed-300x153.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed-768x392.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed-50x26.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/login_failed.png 1540w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>This is by design and to be expected. The authentication methods are different. We should never be able to authenticate to SQL Server when selecting the &#8220;SQL Server Authentication&#8221; and then providing windows credentials. Windows credentials must be used with the &#8220;Windows Authentication&#8221; option. If you must run SSMS as a different windows user, then I recommend reading this <a href="http://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/">article</a>.</p>
<h2>The Wrap</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon.png"><img loading="lazy" class="wp-image-5194 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png" alt="" width="226" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png 226w, https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji-50x45.png 50w" sizes="(max-width: 226px) 85vw, 226px" /></a>Sometimes what may be ridiculously easy for some of us may be mind-blowing to others. Sometimes we may use what we think are common terms only to see eyes start to glaze over and roll to the backs of peoples heads. This just so happens to be one of those cases where launching an app as a different principal may be entirely new to the intended audience. In that vein, it is worthwhile to take a step back and &#8220;document&#8221; how the task can be accomplished.</p>
<p>Connecting to SQL Server is ridiculously easy. Despite the ease, I find myself helping &#8220;Senior&#8221; level development and/or database staff.</p>
<p>If you feel the need to read more connection related articles, here is an <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-with-minimal-configuration?view=sql-server-2017">article</a> and <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-in-single-user-mode?view=sql-server-2017">another</a> on the topic.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5249" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/03/27/connect-to-sql-server-back-to-basics/">Connect To SQL Server – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/03/27/connect-to-sql-server-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>An Experiment with Deadlocks</title>
		<link>https://jasonbrimhall.info/2019/03/25/an-experiment-with-deadlocks/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=an-experiment-with-deadlocks</link>
					<comments>https://jasonbrimhall.info/2019/03/25/an-experiment-with-deadlocks/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 25 Mar 2019 12:26:03 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XEvents]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5206</guid>

					<description><![CDATA[<p>There seems to be a myth out there that when deadlocks come a-knocking, then just throw this little directive (ROWLOCK) at it and all will be well. This is total fiction and we will explore that in this article.</p>
The post <a href="https://jasonbrimhall.info/2019/03/25/an-experiment-with-deadlocks/">An Experiment with Deadlocks</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Everything can be fixed with a query hint (*cough* directive), right? If a certain process is consistently causing deadlocks, a simple ROWLOCK hint can be added to prevent it, right?</p>
<p><a href="http://bit.ly/XE60Days"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="167" height="167" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 167px) 85vw, 167px" /></a>Well, for whatever reason, there seems to be a myth out there that when deadlocks come a-knocking, then just throw this little directive at it and all will be well. Today, we get to test that and show what will continue to happen.</p>
<p>First, lets look at what the ROWLOCK actually means:</p>
<blockquote><p>Specifies that row locks are taken when page or table locks are ordinarily taken.</p></blockquote>
<p>This seems like a fabulous idea if the deadlocks are occurring against a table involving a massive update. Let&#8217;s take a look at a small update scenario involving just a handful of records. For the setup, we will use the same setup used in a <a href="https://blog.waynesheffield.com/wayne/archive/2017/05/weaning-yourself-off-of-sql-profiler-part-2/">previous article by Wayne</a>.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE tempdb;
GO
IF OBJECT_ID('dbo.Test1') IS NOT NULL
	DROP TABLE dbo.Test1;
IF OBJECT_ID('dbo.Test2') IS NOT NULL
	DROP TABLE dbo.Test2;
CREATE TABLE dbo.Test1 ( col1 INT );
CREATE TABLE dbo.Test2 ( col2 INT );
INSERT INTO dbo.Test1
	VALUES	( 1 ),
			( 2 ),
			( 3 ),
			( 4 ),
			( 5 );
INSERT INTO dbo.Test2
	VALUES	( 1 ),
			( 2 ),
			( 3 ),
			( 4 ),
			( 5 );
GO
BEGIN TRANSACTION;
UPDATE dbo.Test1
	SET	col1 = col1 * 10
	WHERE col1 = 3;

/* query window 2*/

USE tempdb;
BEGIN TRANSACTION;
UPDATE dbo.Test2
	SET	col2 = col2 * 20
	WHERE col2 = 4;
UPDATE dbo.Test1
	SET	col1 = col1 * 20
	WHERE col1 = 3;
COMMIT TRANSACTION;

/* back to the first query window*/
UPDATE dbo.Test2
	SET	col2 = col2 * 10
	WHERE col2 = 4;
COMMIT TRANSACTION;</pre><p>Looking at the code, we can see there are only five rows in each of the tables. In addition, an update will be performed to both col1 and col2 in each table for one specific row. So we are keeping this to a singleton type of update, and we are able to force a deadlock by using this setup. Not only do we see that a deadlock will occur consistently, we would see the following in the sys.dm_tran_locks DMV as well as in the deadlock graphs.</p>
<p><a href="http://bit.ly/1Qytj9F"><img loading="lazy" class="aligncenter wp-image-5209 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1-1024x521.png" alt="" width="560" height="285" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1-300x153.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1-768x391.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/locks_held1-50x25.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In my environment, I used session 51 and 54 consistently for the deadlock repro. In each of the tests, each spid did obtain page locks as well as RID locks (row locks) that were waiting on each other in order to perform an Update. This is what we saw when I ran the setup without the ROWLOCK directive. What if I used the ROWLOCK directive (are you guessing already that there would be no change because the deadlock occurs on the lock held for the update that is waiting on the other update to complete?)? Let&#8217;s take a look at that too!</p><pre class="urvanov-syntax-highlighter-plain-tag">/* what about using rowlock hint? let's try it */
USE tempdb;
GO
IF OBJECT_ID('dbo.Test1') IS NOT NULL
	DROP TABLE dbo.Test1;
IF OBJECT_ID('dbo.Test2') IS NOT NULL
	DROP TABLE dbo.Test2;
CREATE TABLE dbo.Test1 ( col1 INT );
CREATE TABLE dbo.Test2 ( col2 INT );
INSERT INTO dbo.Test1
	VALUES	( 1 ),
			( 2 ),
			( 3 ),
			( 4 ),
			( 5 );
INSERT INTO dbo.Test2
	VALUES	( 1 ),
			( 2 ),
			( 3 ),
			( 4 ),
			( 5 );
GO
BEGIN TRANSACTION;
UPDATE dbo.Test1 WITH (ROWLOCK)
	SET	col1 = col1 * 10
	WHERE col1 = 3;

/* query window 2*/

USE tempdb;
BEGIN TRANSACTION;
UPDATE dbo.Test2 WITH (ROWLOCK)
	SET	col2 = col2 * 20
	WHERE col2 = 4;
UPDATE dbo.Test1 WITH (ROWLOCK)
	SET	col1 = col1 * 20
	WHERE col1 = 3;
COMMIT TRANSACTION;

/* back to the first query window*/
UPDATE dbo.Test2 WITH (ROWLOCK)
	SET	col2 = col2 * 10
	WHERE col2 = 4;
COMMIT TRANSACTION;</pre><p>The only change to this setup is that the ROWLOCK directive has been added to the update statements. Examining the sys.dm_tran_locks DMV reveals the same locks being held as was seen without the directive. This shouldn&#8217;t be too big of a surprise since the updates are against a single row.</p>
<p>In addition to the same locks being held, we continue to experience the same deadlock problem. Using an Extended Events session to trap deadlock information (similar to the article previously discussed), we can pull out some pretty good info. Let&#8217;s examine some of the deadlock data trapped by an XE session.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH	cte	AS ( SELECT t2.event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
							, t2.event_data.value('(event/@timestamp)[1]',
													'datetime2') AS StartTime
							, t2.event_data.value('(event/data[@name=&quot;duration&quot;]/value)[1]',
													'bigint') AS duration
							, t2.event_data.value('(event/data[@name=&quot;database_name&quot;]/value)[1]',
													'sysname') AS DBName
							, t2.event_data.value('(event/action[@name=&quot;sql_text&quot;]/value)[1]',
													'varchar(max)') AS sql_text
							, t2.event_data.value('(event/action[@name=&quot;nt_username&quot;]/value)[1]',
													'varchar(500)') AS nt_username
							, t2.event_data.value('(event/data[@name=&quot;mode&quot;]/value)[1]',
													'varchar(15)') + ' ('
							+ t2.event_data.value('(event/data[@name=&quot;mode&quot;]/text)[1]',
													'varchar(50)') + ')' AS mode
							, t2.event_data.value('(event/data[@name=&quot;object_id&quot;]/value)[1]',
													'integer') AS object_id
							, t2.event_data.value('(event/data[@name=&quot;resource_description&quot;]/value)[1]',
													'varchar(max)') AS resource_description
							, t2.event_data.value('(event/data[@name=&quot;resource_owner_type&quot;]/text)[1]',
													'varchar(max)') AS resource_owner_type
							, t2.event_data.value('(event/data[@name=&quot;resource_type&quot;]/text)[1]',
													'varchar(max)') + ' ('
							+ t2.event_data.value('(event/data[@name=&quot;resource_type&quot;]/value)[1]',
													'varchar(max)') + ')' AS resource_type
							, t2.event_data.value('(event/action[@name=&quot;server_principal_name&quot;]/value)[1]',
													'varchar(max)') AS server_principal_name
							, t2.event_data.value('(event/action[@name=&quot;session_id&quot;]/value)[1]',
													'varchar(max)') AS session_id
							, t2.event_data.value('(event/action[@name=&quot;client_pid&quot;]/value)[1]',
													'integer') AS client_pid
							, t2.event_data.value('(event/action[@name=&quot;client_app_name&quot;]/value)[1]',
													'varchar(max)') AS client_app_name
							, t2.event_data
							,ROW_NUMBER() OVER (ORDER BY t2.event_data.value('(event/@timestamp)[1]',
													'datetime2')
													,t2.event_data.value('(event/@name)[1]', 'varchar(50)')) AS Event_Seq
						FROM sys.fn_xe_file_target_read_file('C:\Database\XE\Deadlock*.xel',
																NULL, NULL, NULL) t1
							CROSS APPLY ( SELECT CONVERT(XML, t1.event_data)
										) t2 ( event_data )
				)
	SELECT c1.event_name AS LockEvent, c2.event_name AS GraphEvent
			, c1.StartTime
			, DATEADD(MICROSECOND, c1.duration, CONVERT(DATETIME2, [c1].StartTime)) AS EndDate
			, c1.duration
			, c1.DBName
			, c1.sql_text
			, c1.nt_username
			, c1.server_principal_name
			, c1.mode
			, c1.object_id
			, c1.resource_description
			, c1.resource_owner_type
			, c1.resource_type
			, c1.session_id
			, c1.client_pid
			, c1.client_app_name
			, c1.event_data
			, graph.query('.') AS EventDeadlockGraph
		FROM cte c1
			INNER JOIN cte c2
				ON c1.Event_Seq = c2.Event_Seq - 1
			CROSS APPLY c2.event_data.nodes('(event/data[@name=&quot;xml_report&quot;]/value)[last()]/*')
				AS deadlock ( graph )
		WHERE c1.event_name = 'lock_deadlock'
			AND c2.event_name = 'xml_deadlock_report'
		ORDER BY c1.StartTime;</pre><p>The results from this query will show us the deadlock graph, the event data, as well as several other pieces of data already parsed from the session data for you. And looking at the session data, one can see that the sql_text from each of the queries will demonstrate both the ROWLOCK directive and the directive-free versions of the query. In this query you can also see that I did a little black magic to match up the two event types from the event session (lock_deadlock and xml_deadlock_report). Then I was able to join the two together to produce one row per deadlock event and to see the sql_text with the deadlock graph on one row. Otherwise, the sql_text does not produce with the deadlock_report event. I leave the rest of the query to the reader to discover and question.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5211" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results-1024x141.png" alt="" width="560" height="77" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results-300x41.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results-768x106.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/xe_results-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>From the EventDeadlockGraph column, we could click the cell and take a close look at the XML generated for the deadlock event. Further, if I choose to save the xml as an XDL file and then reopen it in SSMS, I can see the deadlock graphical report as shown in the following.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5212" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report-1024x348.png" alt="" width="560" height="190" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report-300x102.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report-768x261.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/graphical_report-50x17.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>We see that row locks are still in effect for the update coming from both sides. This further supports that the directive really is just a waste of time in trying to combat this type of deadlock. This is one of those cases where the best option would be to optimize the code and work things out without trying to take a shortcut.</p>
<h3>Wrapping Up</h3>
<p>Look to optimize the code instead of trying to take a shortcut. In addition, take a look at the deadlocks, the locks held, and the code to get a better understanding of what is truly happening.</p>
<p>This article demonstrates briefly the power of Extended Events while diving into deadlocks. For more on using Extended Events, <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">start reading here</a>! This <a href="http://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">article</a> may also be of interest.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5206" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/03/25/an-experiment-with-deadlocks/">An Experiment with Deadlocks</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/03/25/an-experiment-with-deadlocks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Curiously Large CASE Statement</title>
		<link>https://jasonbrimhall.info/2019/03/20/the-curiously-large-case-statement/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-curiously-large-case-statement</link>
					<comments>https://jasonbrimhall.info/2019/03/20/the-curiously-large-case-statement/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 20 Mar 2019 12:47:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5234</guid>

					<description><![CDATA[<p>A powerful little expression in SQL Server is the CASE statement. The CASE statement has the ability to "transform" data per business rules to help better understand the data in a given query. In the simplest form, the CASE statement is a statement that evaluates a list of conditions (in order) and returns the first matching result expressions.</p>
The post <a href="https://jasonbrimhall.info/2019/03/20/the-curiously-large-case-statement/">The Curiously Large CASE Statement</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p>A powerful little expression in SQL Server is the CASE statement. The CASE statement has the ability to &#8220;transform&#8221; data per business rules to help better understand the data in a given query. In the simplest form, the <a href="https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql?view=sql-server-2017">CASE statement</a> is a statement that evaluates a list of conditions (in order) and returns the first matching result expressions.</p>
<p>Most uses of the CASE statement are benign enough that one wouldn&#8217;t even bat an eye at them. Every now and again, along comes a nifty little query <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/"><img loading="lazy" class="alignright wp-image-5170" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm.png" alt="" width="128" height="124" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm.png 219w, https://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm-50x48.png 50w" sizes="(max-width: 128px) 85vw, 128px" /></a>that contains over 300 conditions in the CASE statement. Something that extreme certainly deserves a second (third or even fourth) look. In this article, I am going to explore one such CASE statement in an effort to squeeze more efficiency out of it.</p>
<h2>300!</h2>
<p>300+ conditions may be a bit hard to imagine. I know I had to double take the list more than once. Immediately upon seeing such an <strong>awful piece of code </strong>(not pulling punches there), I really wanted to dump the conditions/evaluations into a table and join to it. Eventually, I did put it into a table but not before catching some metrics. Let&#8217;s take a look at what this thing looked like from the execution plan properties perspective.</p>
<p><img loading="lazy" class="wp-image-5238 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/case_properties_2014.png" alt="" width="271" height="337" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/case_properties_2014.png 576w, https://jasonbrimhall.info/wp-content/uploads/2019/03/case_properties_2014-241x300.png 241w, https://jasonbrimhall.info/wp-content/uploads/2019/03/case_properties_2014-40x50.png 40w" sizes="(max-width: 271px) 85vw, 271px" /></p>
<p>In the preceding image, note the query map in the scrollbar. I have the case statement circled in green. Yes &#8211; it is really that large. Next, I have &#8220;cached plan size&#8221;, &#8220;estimated number of rows&#8221;, and &#8220;estimated subtree cost&#8221; circled in red. Each of these shows something that is a little alarming to me. First, the plan size is <strong>48MB</strong>! Next, the cost of the query is a little elevated at 51 and change. Last is what seems to be a high value for the estimated number of rows to be returned (only ~6k actually get returned).</p>
<p>On the plus side, the query only takes 381ms, or does it? The query actually takes 3 seconds to complete despite the timing in the properties window. Sometimes, we have to take some of these values in the properties window with a grain of salt.</p>
<p>What if I try to run this query on SQL Server 2017 instead of SQL Server 2014? Let&#8217;s take a look at what that might look like.</p>
<p><img loading="lazy" class="alignright wp-image-5239" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/2017_case_properties.png" alt="" width="271" height="302" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_case_properties.png 672w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_case_properties-270x300.png 270w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_case_properties-45x50.png 45w" sizes="(max-width: 271px) 85vw, 271px" /></p>
<p>Firstly, we have a few properties that seem to indicate that we have moved in a slightly better direction with this particular query. The cached plan size has dropped all the way down to just <strong>37MB</strong>. The estimated cost dropped to 36 and change and the elapsed time dropped to 353ms. Nothing terribly earth shattering there &#8211; but just changing to SQL Server 2017, in this case, we see a bit of an improvement.</p>
<p>That said, take a look at the compile memory and compile time. Memory is 30,544kb and the time is 1,324ms. Aha &#8211; we see why this query takes 3 seconds on SQL 2014 and roughly 2 seconds on SQL 2017. High compile times. That memory for the compile is too high for my liking as well so let&#8217;s go ahead and take a look at why that might be a little high. It&#8217;s time to look at the plan XML and the converted tree for the query (because it is fun).</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5240" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/case_exec_xml-1024x593.png" alt="" width="560" height="324" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/case_exec_xml-1024x593.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/case_exec_xml-300x174.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/case_exec_xml-768x445.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/case_exec_xml-50x29.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>This is where we get a little geeky with the CASE statement. In the execution plan XML (and the converted tree we will see in a bit), every evaluation criteria for the case statement must have some sort of instruction on how and what should be done. In the case of the XML, we have multiple scalar operators to denote the CASE statement and then each of the evaluations for the CASE statement.</p>
<p>Once we enter the CASE statement, the first thing we see is that there is an &#8220;OR&#8221; operation (circled in red). Then for each of the values to be compared, we will see an &#8220;Equality&#8221; operation (circled in green) followed by the value to be evaluated. For just the three values I have in the image, notice how that immediately bloats the execution plan XML for this query.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5241" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case-1024x374.png" alt="" width="560" height="205" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case-1024x374.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case-300x109.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case-768x280.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case-50x18.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/03/converted_tree_case.png 1719w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>In the preceding image, we see the converted tree for this query. We see the same pattern evolve here. There is a scalar operator for each value to be evaluated. In this image, I just have the equality comparisons. However, there is also an OR operator that is defined further up in this converted tree. Could this possibly be the reason for the bloated compile time and compile memory?</p>
<p>Let&#8217;s evolve that query just a bit and use a table and a join for that particular case statement to see what happens.</p>
<p><img loading="lazy" class="aligncenter wp-image-5242" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties.png" alt="" width="271" height="504" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties.png 489w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties-161x300.png 161w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties-27x50.png 27w" sizes="(max-width: 271px) 85vw, 271px" /></p>
<p>Immediately, we can see that the cached plan size improves dramatically! The cached plan size is down to 1.1MB. The compile memory is down to ~4MB and the compile time is down to 174ms. These are all significant improvements but now we see an interesting problem with the memory grant. This query is requesting over 400MB for the memory grant. That should be sounding sirens everywhere. Also of note is the estimated number of rows has dropped to ~28k (a significant improvement in estimate). This query is completing in under 1 second at this point compared to the 3 seconds otherwise but that memory grant is worrying me (and hopefully you too).</p>
<p>For giggles, I went ahead and added a columnstore index to this table (for good reasons beyond the scope of this article). Let&#8217;s see what that did.</p>
<p><img loading="lazy" class="aligncenter wp-image-5243" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties_ccx.png" alt="" width="271" height="442" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties_ccx.png 483w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties_ccx-184x300.png 184w, https://jasonbrimhall.info/wp-content/uploads/2019/03/2017_table_properties_ccx-31x50.png 31w" sizes="(max-width: 271px) 85vw, 271px" /></p>
<p>Notice how the memory grant has dropped to just over 28MB? This is an acceptable improvement for this query. Also note the query execution time improved by a decent amount. This query timing for this query is similar with both a warm cache or cold cache at this point.</p>
<p>Remember that note about the XML and converted tree bloat? With the case statement, the query plan was in excess of 37MB and the revised version is sitting at about 1.1MB. Looking at the quantity of text in each, I see 5819 lines of XML in the version with the case statement and only 3755 lines of XML in the table version of the query (and more room for optimization). The converted tree is more dramatic in that the case statement version of the converted tree requires 3157 lines of instruction and the version that uses a table instead only has 1353 lines of instruction.</p>
<p>What does any of that matter? It helps to illustrate that this 300+ condition filled CASE statement is causing bloat and wasting space along with execution resources.</p>
<h2>Wrap</h2>
<p>If you ever find yourself writing a query that requires an excessive amount of conditions to be evaluated in a CASE statement, you should reconsider the query design. Too many conditions can lead to plan bloat and excessive memory grants. Keep an eye out for stuff like that!</p>
<p>Thanks for reading! This has been a pseudo deep dive into a really ugly CASE statement. If you would like to read other articles that are less of a deep dive, You can read check out the Back to Basics articles <a href="http://jasonbrimhall.info/tag/back-to-basics/">here,</a> or the Extended Events articles <a href="http://bit.ly/XE60Days">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5234" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/03/20/the-curiously-large-case-statement/">The Curiously Large CASE Statement</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/03/20/the-curiously-large-case-statement/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Disk Space and SQL Server</title>
		<link>https://jasonbrimhall.info/2019/03/18/disk-space-and-sql-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=disk-space-and-sql-server</link>
					<comments>https://jasonbrimhall.info/2019/03/18/disk-space-and-sql-server/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 18 Mar 2019 12:49:47 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5197</guid>

					<description><![CDATA[<p>One of the frequently required job functions of the database administrator is to track disk space consumption. Whether this requirement comes from management or from a learning opportunity after a production outage, the need exists.</p>
The post <a href="https://jasonbrimhall.info/2019/03/18/disk-space-and-sql-server/">Disk Space and SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Disk Space in SQL Server</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png"><img loading="lazy" class=" wp-image-4327 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png" alt="" width="236" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics.png 770w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-300x219.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-768x562.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/back2dbbasics-50x37.png 50w" sizes="(max-width: 236px) 85vw, 236px" /></a>One of the frequently required job functions of the database administrator is to track disk space consumption. Whether this requirement comes from management or from a learning opportunity after a production outage, the need exists.</p>
<p>As a hard working DBA, you want to make sure you hit all of the notes to make management sing your praises. Knowing just when the database may fill the drives and prevent a production outage just happens to be one of those sharp notes that could result in a raise and management singing hallelujah. The problem is, how do you do it from within SQL Server? You are just a DBA after all and the disk system is not your domain, right?</p>
<p>Trying to figure it out, you come across a pretty cool function within SQL Server. The name of the function is <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-os-volume-stats-transact-sql?view=sql-server-2017">sys.dm_os_volume_stats</a>. Bonus! This is an excellent discovery, right? Let&#8217;s see just how it might work. First a sample query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT  ovs.logical_volume_name AS VolumeName
		, ovs.volume_mount_point AS DiskDrive
		, ovs.available_bytes AS FreeSpace
		, ovs.total_bytes AS CurrentSize
	FROM sys.master_files mf
		CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.file_id) ovs;</pre><p>If I run that on my local system, I <em>might</em> end up with something that looks like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1.png"><img loading="lazy" class="aligncenter size-full wp-image-5199" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1.png" alt="" width="914" height="212" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1.png 914w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1-300x70.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1-768x178.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run1-50x12.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a>Looking at the image you may be wondering to yourself right now why I have highlighted a couple of things. You may also be wondering why I used the word &#8220;might&#8221; in the previous paragraph as well. The reasoning will become more evident as we progress. For now, you have resolved to continue testing the script so execute it again and end up with something that <em>may</em> look like the following (for the same server):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2.png"><img loading="lazy" class="aligncenter size-full wp-image-5200" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2.png" alt="" width="909" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2.png 909w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2-300x74.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2-768x190.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run2-50x12.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>Whoa! What just happened there? Why are there two listings for the C: drive? Why does each register a different value for the FreeSpace column? In addition without any additional usage on the C drive (as verified through other tools) the FreeSpace is changing between executions as well as within the same execution. This is problematic, so you continue testing:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3.png"><img loading="lazy" class="aligncenter size-full wp-image-5201" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3.png" alt="" width="897" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3.png 897w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3-300x68.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3-768x175.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run3-50x11.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>And yet again!</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4.png"><img loading="lazy" class="aligncenter size-full wp-image-5202" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4.png" alt="" width="921" height="172" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4.png 921w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4-300x56.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4-768x143.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_run4-50x9.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a>This can&#8217;t be correct, can it? Just for giggles let&#8217;s modify it just a bit to see if there are any additional clues. Using the following changed script, hopefully a clue will help shed some light on this:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ovs.logical_volume_name AS VolumeName
		, ovs.volume_mount_point AS DiskDrive
		, ovs.available_bytes AS FreeSpace
		, ovs.total_bytes AS CurrentSize
	FROM sys.master_files mf
		CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.file_id) ovs;</pre><p>This script yields the following potential results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts.jpg"><img loading="lazy" class="aligncenter size-large wp-image-5198" src="http://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-754x1024.jpg" alt="" width="560" height="761" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-754x1024.jpg 754w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-221x300.jpg 221w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-768x1043.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts-37x50.jpg 37w, https://jasonbrimhall.info/wp-content/uploads/2019/03/dmv_space_nodistincts.jpg 884w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Look at the different highlighted areas! There are three different values for FreeSpace for the C: drive in this particular execution. The case of the C: drive plays no role in whether the value is recorded differently or not. This seems to be more of a bug within the dynamic management function. From execution to execution, using this particular method, one could end up with duplicate entries but distinct values. The sort of the execution could be returned differently (though we could fix that).</p>
<p>All of these tests were run on my local machine and I really do only have one C: drive. I should never receive multiple entries back for any drive. If using this particular DMF to track space usage, it could be somewhat problematic if the duplicate drive data pops up. How do we get around it, you ask? Here is another example that I have that has not yet produced this duplication:</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH presel AS (SELECT database_id, file_id,LEFT(mf1.physical_name,3) AS Volume, ROW_NUMBER() OVER (PARTITION BY LEFT(mf1.physical_name,3) ORDER BY mf1.database_id) AS RowNum
					FROM sys.master_files mf1)
,roundtwo AS (SELECT DISTINCT pr.database_id, pr.file_id
				FROM presel pr
				WHERE pr.RowNum = 1)

SELECT ovs.logical_volume_name AS VolumeName
		, ovs.volume_mount_point AS DiskDrive
		, ovs.available_bytes AS FreeSpace
		, ovs.total_bytes AS CurrentSize
	FROM roundtwo mf
		CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.file_id) ovs;</pre><p>Using this version of the script is not terribly more complex, but it will prove to be more reliable. You can see I used some CTEs to provide a little trickery and ensure that I limit my results. What if it is a mount point or a non-standard drive letter? I have not tested that. Let me know how that goes. As you can see, I am restricting the drive selection by using the row_number function against the drive letter.</p>
<p>For alternative reliable methods to find your disk space consumption, I would recommend something different because it is tried and tested. I would recommend using a wmi call to fetch the data. Samples are provided as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* for mount points, something like this */
EXECUTE sys.xp_cmdshell 'wmic volume get name, freespace, capacity, label'
/* the base wmi query that does not support mount points */
EXECUTE xp_cmdshell 'wmic logicaldisk get name,freespace,size,volumename,blocksize'</pre><p>Easy peasy, right? Have at it and try tracking your disk space.</p>
<p>Thanks for reading! This has been another article in the Back to Basics series. You can read many more <a href="http://jasonbrimhall.info/tag/back-to-basics/">here</a>. For other interesting articles about database space &#8211; check <a href="http://bit.ly/tablespace">here</a> or <a href="http://jasonbrimhall.info/2015/07/29/internal-tables-and-space-used/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5197" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/03/18/disk-space-and-sql-server/">Disk Space and SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/03/18/disk-space-and-sql-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Passion, Challenges, and SQL</title>
		<link>https://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=passion-challenges-and-sql</link>
					<comments>https://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 Feb 2019 17:56:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5191</guid>

					<description><![CDATA[<p>One of my biggest reasons why I do what I do, boils down to the challenges that I frequently get to encounter. There is a wild satisfaction to working on a very difficult and challenging task, product, tool, profession, skill, etc. This satisfaction often involves reward and a sense of accomplishment.</p>
The post <a href="https://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/">Passion, Challenges, and SQL</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png"><img loading="lazy" class="wp-image-4643 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png" alt="" width="190" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png 190w, https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection-50x46.png 50w" sizes="(max-width: 190px) 85vw, 190px" /></a>TSQL Tuesday</h2>
<p>The second Tuesday of the month comes to us a little early this month. That means it is time again for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<h2>The Why?</h2>
<p>Long time friend Andy Leonard (<a href="https://andyleonard.blog">b</a> | <a href="https://twitter.com/AndyLeonard">t</a>) <a href="https://andyleonard.blog/2019/02/t-sql-tuesday-111-what-is-your-why/">invites us this month</a> to do a little checkup on ourselves and talk about the &#8220;why&#8221; around what we do. This could be a very easy topic for some. Equally, this could be a very difficult topic for those same people at different times in their lives. Thus the problem, the topic is simple in nature but sure requires a firm <a href="http://jasonbrimhall.info/2018/12/04/influence-somebody-invite/">reflection</a> on self and what you have been doing.</p>
<p>The problem for me is less about the &#8220;why&#8221; behind what I do, and more about how to stretch it out into something more than a few sentences. Think! Think! Think!</p>
<h3>Challenges</h3>
<p>One of my biggest reasons why I do what I do, boils down to the challenges that I frequently get to encounter. There is a wild satisfaction to working on a very difficult and challenging task, product, tool, profession, skill, etc. This satisfaction <a href="http://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png"><img loading="lazy" class=" wp-image-5194 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png" alt="" width="157" height="142" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji.png 226w, https://jasonbrimhall.info/wp-content/uploads/2019/02/thinking_emoji-50x45.png 50w" sizes="(max-width: 157px) 85vw, 157px" /></a>often involves reward and a sense of accomplishment.</p>
<p>The challenge can be anything from how to effectively communicate with a difficult person, a tough to find internals problem in SQL Server that could be causing a performance issue, or taking over a project and turning it back from the edge of failure and onto a track of success. Sometimes, the challenge may be as simple as converting a pathetic cursor into a set based approach and gaining an improvement of 100x in performance.</p>
<p>I really do enjoy some of the puzzles (challenges) that I get to work on routinely. This gives me an opportunity to improve my skillset as well as continue to learn. Being able to continually improve is a great motivation for me. The frequent challenges and continual opportunity to learn presents a great opportunity to evolve ones self and career. In a constantly changing world, being able to naturally and easily evolve your personal career is a bonus!</p>
<h3>Passion</h3>
<p>&#8220;Do what you love and you will never work a day in your life.&#8221; This is a common saying in the United States. Agree or disagree &#8211; there is some truth to it. Being able to do something one loves makes the really hard days a lot easier. Knowing, I may be able to solve a complex problem makes it easier to face the day.</p>
<p>I really enjoy the opportunity to face difficult challenges and resolve those challenges. The passion to solve these puzzles with data doesn&#8217;t end there. I also really do enjoy the opportunity to learn which brings up two other challenges that help me learn: <a href="http://jasonbrimhall.info/2018/05/08/giving-back/">speaking and writing</a>.</p>
<p>By putting myself out there regularly to speak and write, I am becoming a better technical person. I am becoming better equipped to solve many of the puzzles I face. Those are great benefits. That said, I don&#8217;t feel I could get out there and talk about something about which I wasn&#8217;t passionate. I have learned to become passionate about writing and speaking &#8211; though I still have plenty of room for improvement (just as I do in my quest to become a good DBA).</p>
<h3><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>Wrapping it Up</h3>
<p>I really do enjoy the challenges I get to face on a frequent basis in the world of data. This is the big &#8220;WHY&#8221; for me to continue my progress in this career.</p>
<p>Find something you are passionate about and strive to envelop your career with as many opportunities to do that thing. If that means accepting some less wanted tasks in order to do more of the thing you love, it could very well be worth it!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5191" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/">Passion, Challenges, and SQL</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/02/12/passion-challenges-and-sql/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Interview Trick Questions</title>
		<link>https://jasonbrimhall.info/2019/02/04/interview-trick-questions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interview-trick-questions</link>
					<comments>https://jasonbrimhall.info/2019/02/04/interview-trick-questions/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 04 Feb 2019 13:56:20 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5131</guid>

					<description><![CDATA[<p>Anybody that has interviewed for a job has most likely run into the trick question. Some interviewers like to throw out multiple trick questions all in an effort to trip up the candidate and get the candidate to doubt him/her self.</p>
The post <a href="https://jasonbrimhall.info/2019/02/04/interview-trick-questions/">Interview Trick Questions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>Today, I am diverging from the more technical posts that I routinely share. Instead, as the title suggests, I want to dive into a something a little more fun.</p>
<p>Anybody that has interviewed for a job has most likely run into the <em><strong>trick question</strong></em>. Some interviewers like to throw out multiple trick questions all in an effort to trip up the candidate and get the candidate to doubt him/her self. Sure, there can be some benefit to throwing out a trick question or four. One such benefit would be to see how the candidate performs under pressure (see them squirm).</p>
<p>The downside to throwing out trick questions, in my opinion, would be that you can turn a serious candidate into an uninterested candidate. So, when throwing out the tricks, <strong>tread carefully</strong>.</p>
<p>Let&#8217;s take a look at an interview trick question candidate. This is a more technical question and is designed to make you think a little bit. Before reading on to see the answer, I implore that you try to answer the question for yourself legitimately.</p>
<p><em><strong>How can you insert data into two tables using a single statement without the use of triggers, service broker or some other behind-the-scenes feature?</strong></em></p>
<p>Are you thinking about it?</p>
<p>Do you have your answer yet?</p>
<p>Now that you have your answer, go ahead and continue reading.</p>
<p>Is your answer to this question something along the lines of &#8220;You can&#8217;t do that and this is just a trick question&#8221;?</p>
<p>Well, honestly, it is a bit of a trick question. But I assure you, you can certainly perform an <a href="http://www.sqlservercentral.com/articles/T-SQL/156204/">insert into multiple tables from a single statement</a>. Here is one such setup that demonstrates how you can do this:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE tin1
	(
		t1id INT IDENTITY(1, 1)
					PRIMARY KEY CLUSTERED
		, someval VARCHAR(100)
	);
CREATE TABLE tin2
	(
		t2id INT IDENTITY(1, 1)
					PRIMARY KEY CLUSTERED
		, someval VARCHAR(100)
	);
GO


INSERT INTO tin1
		( someval )
	OUTPUT INSERTED.someval
		INTO dbo.tin2 ( someval )
	VALUES ( 'double my insert pleasure' );


SELECT *
	FROM dbo.tin1;
SELECT *
	FROM dbo.tin2;</pre><p>Do you see how I was able to perform that insert into multiple tables? The trick is in using the <a href="https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017">OUTPUT clause</a>. This little feature in SQL Server can be of great use for things such as building multiple staging tables during an ETL process.</p>
<p>Here is that little trick again just to highlight it.</p><pre class="urvanov-syntax-highlighter-plain-tag">OUTPUT INSERTED.someval
INTO</pre><p></p>
<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion.png"><img loading="lazy" class="wp-image-5132 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion.png" alt="" width="240" height="240" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion.png 479w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-144x144.png 144w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/trickquestion-65x65.png 65w" sizes="(max-width: 240px) 85vw, 240px" /></a>Conclusion</h3>
<p>There are cases when an interview trick question is suitable. It is when the purported question is truly more technical than trick and is really trying to evaluate your depth and knowledge of SQL Server. The puzzle during the interview boils down to figuring out when it is a trick and when it might not be. Then from there, work your way through possible solutions. But don&#8217;t be afraid to admit when you haven&#8217;t got a clue. That will be far more impressive than to try and flim-flam the interviewer.</p>
<p>I invite you to share your trick questions in the comments.  Also, how did you solve this particular trick question?</p>
<p>&nbsp;</p>
<p>Thanks for reading! This has been another article in the Back to Basics series. You can read many more <a href="http://jasonbrimhall.info/tag/back-to-basics/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5131" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/02/04/interview-trick-questions/">Interview Trick Questions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/02/04/interview-trick-questions/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Defaults In msdb Database</title>
		<link>https://jasonbrimhall.info/2019/01/28/defaults-in-msdb-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defaults-in-msdb-database</link>
					<comments>https://jasonbrimhall.info/2019/01/28/defaults-in-msdb-database/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 28 Jan 2019 14:22:42 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5126</guid>

					<description><![CDATA[<p>The defaults in the msdb database are about what is missing. It's missing quite a few things that could be critical to your environment.</p>
The post <a href="https://jasonbrimhall.info/2019/01/28/defaults-in-msdb-database/">Defaults In msdb Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>Today is a day to discuss defaults. It started with the day being TSQL Tuesday and having a topic of &#8220;Say No to Defaults.&#8221; You can read more about that from the invite &#8211; <a href="https://sqlbek.wordpress.com/2015/07/06/invitation-to-t-sql-tuesday-68-just-say-no-to-defaults/">here</a>. I already participated in the party but did also want to discuss defaults a little bit more. That said, this article is not participating in the blog party. That would seem a bit silly.</p>
<p>While, this post is not a part of the party, the defaults to be discussed are fairly important. I have seen severe consequences due to these defaults being ignored and not changed. So today, in addition to my earlier article (<a href="http://bit.ly/1MqEon4">you can read it here</a>), I implore you to make some fundamental changes to your production servers with regards to various defaults.</p>
<h2>A Trio of msdb Defaults</h2>
<p>There aren&#8217;t really that many defaults within the msdb database that must be changed, are there? I mean, seriously, beyond the defaults that are available to every database, what could possibly be unique to this database that could have a severe consequence?</p>
<p>I am so glad you asked!</p>
<p>The defaults in the msdb database are more about what is missing than what is actually there. By default, this database is missing quite a few things that could be deemed critical to your environment.</p>
<h3>Let&#8217;s start with an easy one &#8211; Indexes</h3>
<p>There are a few out there that may disagree, but the proof really is in the effect on performance for backup jobs and such. I have three indexes I like to put on every instance. I have seen the implementation of these indexes aid in improved job times as well as aid in reduced time to &#8220;clean&#8221; up the database.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Number 1 */
/* msdb maintenance activity related indexes */

CREATE INDEX IX_maintplan_taskdetailid ON [msdb].[dbo].[sysmaintplan_logdetail]
([task_detail_id])
WITH (FILLFACTOR = 90);

CREATE INDEX IX_backupset_type ON msdb.dbo.backupset
([type],[backup_finish_date])
INCLUDE ([media_set_id], [database_name])
WITH (FILLFACTOR = 90);

CREATE INDEX IX_jobactivity_jobid ON [msdb].[dbo].[sysjobactivity]
([job_id])
INCLUDE ([session_id])
WITH (FILLFACTOR = 90);</pre><p>Easy enough. These indexes are very straight forward and pretty small in the grand scheme of things. But if the index can help improve performance by a factor of 10, then I am in favor of them (and I have seen that performance gain).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/deadlydefaults.png"><img loading="lazy" class=" wp-image-5129 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/deadlydefaults.png" alt="" width="308" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/deadlydefaults.png 276w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deadlydefaults-50x33.png 50w" sizes="(max-width: 308px) 85vw, 308px" /></a></p>
<p>Now that we have some supporting indexes to help a bit with performance, we should take a look at the next item. This one can help with job performance as well as help with keeping the msdb database nice and trim.</p>
<h3>Data Pruning</h3>
<p>I have walked into client instances that had backup history dating all the way back to 2005 and included two-three full backups a day per database with quarter-hourly log backups. Oh and this was for an instance containing well north of 200 databases. Can you say sluggish backups and sluggish msdb overall?</p>
<p>The fix is very easy! Not only do I recommend pruning the backup history, but also the job history, mail history and maintenance plan history (eew &#8211; if you use those things). Think about it &#8211; do you really need to know that Job XYZ ran successfully in 2006 and only took 15 seconds? This is 2015 and that kind of data is probably not pertinent at this point.</p>
<p>The pruning of this data is not enabled by default! You have to configure this for each of the servers under your purview. Luckily, this is easy to do!</p><pre class="urvanov-syntax-highlighter-plain-tag">/* NUMBER 2 */
/****** Object:  Job [DBA - Clean msdb Historical data]    Script Date: 03/06/2013 17:40:02 ******/
BEGIN TRANSACTION;
DECLARE @ReturnCode INT;
SELECT @ReturnCode = 0;
/****** Object:  JobCategory [DBA Maintenance]]    Script Date: 03/06/2013 17:40:03 ******/
IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.syscategories
					WHERE name = N'DBA Maintenance'
						AND category_class = 1 )
	BEGIN
		EXEC @ReturnCode = msdb.dbo.sp_add_category @class = N'JOB',
			@type = N'LOCAL', @name = N'DBA Maintenance';
		IF ( @@ERROR &lt;&gt; 0
				OR @ReturnCode &lt;&gt; 0
			)
			GOTO QuitWithRollback;

	END;

DECLARE @jobId BINARY(16);
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name = N'DBA - Clean msdb Historical data',
	@enabled = 1, @notify_level_eventlog = 0, @notify_level_email = 0,
	@notify_level_netsend = 0, @notify_level_page = 0, @delete_level = 0,
	@description = N'No description available.',
	@category_name = N'DBA Maintenance', @owner_login_name = N'sa',
	@job_id = @jobId OUTPUT;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
/****** Object:  Step [Purge Backup History]    Script Date: 03/06/2013 17:40:03 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId,
	@step_name = N'Purge Backup History', @step_id = 1,
	@cmdexec_success_code = 0, @on_success_action = 3, @on_success_step_id = 0,
	@on_fail_action = 2, @on_fail_step_id = 0, @retry_attempts = 0,
	@retry_interval = 0, @os_run_priority = 0, @subsystem = N'TSQL',
	@command = N'/* Cleanup old backup history */
DECLARE @BackupHistoryOlderThan DATETIME
Set @BackupHistoryOlderThan = DATEADD(d, -90, GETDATE())
EXECUTE msdb.dbo.sp_delete_backuphistory @BackupHistoryOlderThan

', @database_name = N'msdb', @flags = 4;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
/****** Object:  Step [Purge MaintPlan Log Data]    Script Date: 03/06/2013 17:40:04 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId,
	@step_name = N'Purge MaintPlan Log Data', @step_id = 2,
	@cmdexec_success_code = 0, @on_success_action = 3, @on_success_step_id = 0,
	@on_fail_action = 2, @on_fail_step_id = 0, @retry_attempts = 0,
	@retry_interval = 0, @os_run_priority = 0, @subsystem = N'TSQL',
	@command = N'Declare @OldDate DateTime
Set @OldDate = GETDATE() - 14;

Execute msdb.dbo.sp_maintplan_delete_log @oldest_time = @OldDate',
	@database_name = N'msdb', @flags = 4;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
/****** Object:  Step [Purge Mail History]    Script Date: 03/06/2013 17:40:04 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId,
	@step_name = N'Purge Mail History', @step_id = 3, @cmdexec_success_code = 0,
	@on_success_action = 3, @on_success_step_id = 0, @on_fail_action = 2,
	@on_fail_step_id = 0, @retry_attempts = 0, @retry_interval = 0,
	@os_run_priority = 0, @subsystem = N'TSQL',
	@command = N'/* Cleanup old mail items */
DECLARE @MailItemHistoryOlderThan DATETIME
Set @MailItemHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sysmail_delete_mailitems_sp @sent_before = @MailItemHistoryOlderThan

', @database_name = N'master', @flags = 0;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
/****** Object:  Step [Purge Job History]    Script Date: 03/06/2013 17:40:04 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @jobId,
	@step_name = N'Purge Job History', @step_id = 4, @cmdexec_success_code = 0,
	@on_success_action = 1, @on_success_step_id = 0, @on_fail_action = 2,
	@on_fail_step_id = 0, @retry_attempts = 0, @retry_interval = 0,
	@os_run_priority = 0, @subsystem = N'TSQL',
	@command = N'/*Cleanup of Old Job History*/
Declare @JobHistoryOlderThan DATETIME
Set @JobHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sp_purge_jobhistory @oldest_date = @JobHistoryOlderThan',
	@database_name = N'master', @flags = 0;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @jobId,
	@name = N'Daily', @enabled = 1, @freq_type = 4, @freq_interval = 1,
	@freq_subday_type = 1, @freq_subday_interval = 0,
	@freq_relative_interval = 0, @freq_recurrence_factor = 0,
	@active_start_date = 20120831, @active_end_date = 99991231,
	@active_start_time = 0, @active_end_time = 235959;
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId,
	@server_name = N'(local)';
IF ( @@ERROR &lt;&gt; 0
		OR @ReturnCode &lt;&gt; 0
	)
	GOTO QuitWithRollback;
COMMIT TRANSACTION;
GOTO EndSave;
QuitWithRollback:
IF ( @@TRANCOUNT &gt; 0 )
	ROLLBACK TRANSACTION;
EndSave:

GO</pre><p>If you use this code sample, be sure to adjust the number of days shown in the retention to match your specific needs.</p>
<p>Now we have addressed a couple of defaults in msdb that can impact your performance. We are tidying up the database and in a much happier state these days. There is one more default, though, that is really critical to your data&#8217;s well being. This one is set within the msdb database but it really is for all of your databases!</p>
<h3>Configuring Alerts!</h3>
<p>I&#8217;m not talking about just any alerts. There are some very specific alerts that really should be configured. These are the alerts that can help you intervene to minimize corruption.</p>
<p>If you haven&#8217;t faced a problem with corruption &#8211; you will. It is only a matter of time. Corruption happens. When it happens, the earlier one can intervene, usually the better the outcome. Every minute counts, so why not try to reduce that time as much as possible?</p>
<p>This one is not terribly difficult to implement. I happen to have a query ready to go for that as well. All that needs to be done is a minor adjustment to the alert email address:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Number 3 */
USE [msdb];
GO

IF EXISTS ( SELECT name
				FROM msdb.dbo.sysalerts
				WHERE name = N'DBA Alert: Message Id: 823' )
	EXEC msdb.dbo.sp_delete_alert @name = N'DBA Alert: Message Id: 823';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysalerts
					WHERE name = N'DBA Alert: Message Id: 823' )
	EXEC msdb.dbo.sp_add_alert @name = N'DBA Alert: Message Id: 823',
		@message_id = 823, @severity = 0, @enabled = 1,
		@delay_between_responses = 600, @include_event_description_in = 1,
		@notification_message = N'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.',
		@category_name = N'[Uncategorized]',
		@job_id = N'00000000-0000-0000-0000-000000000000';
GO

IF EXISTS ( SELECT name
				FROM msdb.dbo.sysalerts
				WHERE name = N'DBA Alert: Message Id: 824' )
	EXEC msdb.dbo.sp_delete_alert @name = N'DBA Alert: Message Id: 824';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysalerts
					WHERE name = N'DBA Alert: Message Id: 824' )
	EXEC msdb.dbo.sp_add_alert @name = N'DBA Alert: Message Id: 824',
		@message_id = 824, @severity = 0, @enabled = 1,
		@delay_between_responses = 600, @include_event_description_in = 1,
		@notification_message = N'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.',
		@category_name = N'[Uncategorized]',
		@job_id = N'00000000-0000-0000-0000-000000000000';
GO

IF EXISTS ( SELECT name
				FROM msdb.dbo.sysalerts
				WHERE name = N'DBA Alert: Message Id: 825' )
	EXEC msdb.dbo.sp_delete_alert @name = N'DBA Alert: Message Id: 825';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysalerts
					WHERE name = N'DBA Alert: Message Id: 825' )
	EXEC msdb.dbo.sp_add_alert @name = N'DBA Alert: Message Id: 825',
		@message_id = 825, @severity = 0, @enabled = 1,
		@delay_between_responses = 600, @include_event_description_in = 1,
		@notification_message = N'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.',
		@category_name = N'[Uncategorized]',
		@job_id = N'00000000-0000-0000-0000-000000000000';
GO

IF EXISTS ( SELECT name
				FROM msdb.dbo.sysalerts
				WHERE name = N'DBA Alert: Message Id: 829' )
	EXEC msdb.dbo.sp_delete_alert @name = N'DBA Alert: Message Id: 829';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysalerts
					WHERE name = N'DBA Alert: Message Id: 829' )
	EXEC msdb.dbo.sp_add_alert @name = N'DBA Alert: Message Id: 829',
		@message_id = 829, @severity = 0, @enabled = 1,
		@delay_between_responses = 600, @include_event_description_in = 1,
		@notification_message = N'I/O error detected. This could be a sign of impending I/O failure. Forward this ticket to the primary DBA for this account for followup.',
		@category_name = N'[Uncategorized]',
		@job_id = N'00000000-0000-0000-0000-000000000000';
GO

IF EXISTS ( SELECT name
				FROM msdb.dbo.sysalerts
				WHERE name = N'DBA Alert: Message Id: 832' )
	EXEC msdb.dbo.sp_delete_alert @name = N'DBA Alert: Message Id: 832';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysalerts
					WHERE name = N'DBA Alert: Message Id: 832' )
	EXEC msdb.dbo.sp_add_alert @name = N'DBA Alert: Message Id: 832',
		@message_id = 832, @severity = 0, @enabled = 1,
		@delay_between_responses = 600, @include_event_description_in = 1,
		@notification_message = N'Page memory error detected. This could be a sign of impending memory failure. Forward this ticket to the primary DBA for this account for followup.',
		@category_name = N'[Uncategorized]',
		@job_id = N'00000000-0000-0000-0000-000000000000';
GO

IF NOT EXISTS ( SELECT name
					FROM msdb.dbo.sysoperators
					WHERE name = N'DBA Support' )
	EXEC msdb.dbo.sp_add_operator @name = N'DBA Support', @enabled = 1,
		@weekday_pager_start_time = 90000, @weekday_pager_end_time = 180000,
		@saturday_pager_start_time = 90000, @saturday_pager_end_time = 180000,
		@sunday_pager_start_time = 90000, @sunday_pager_end_time = 180000,
		@pager_days = 0, @email_address = N'support@DBA.com',
		@category_name = N'[Uncategorized]';
GO
EXEC msdb.dbo.sp_add_notification @alert_name = N'DBA Alert: Message Id: 823',
	@operator_name = N'DBA Support', @notification_method = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'DBA Alert: Message Id: 824',
	@operator_name = N'DBA Support', @notification_method = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'DBA Alert: Message Id: 825',
	@operator_name = N'DBA Support', @notification_method = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'DBA Alert: Message Id: 829',
	@operator_name = N'DBA Support', @notification_method = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'DBA Alert: Message Id: 832',
	@operator_name = N'DBA Support', @notification_method = 1;
GO</pre><p></p>
<h2>Wrap</h2>
<p>Wow! Now there are three quick defaults that must be changed on every server. These defaults will help improve performance as well as help you stay on top of things when they start to go south (corruption). With timely notifications, and better performance, your servers will be happier, healthier, and longer lasting.</p>
<p>Thanks for reading! This has been another article in the Back to Basics series. You can read many more <a href="http://jasonbrimhall.info/tag/back-to-basics/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5126" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/28/defaults-in-msdb-database/">Defaults In msdb Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/28/defaults-in-msdb-database/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Audit SQL Agent Jobs</title>
		<link>https://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=audit-sql-agent-jobs</link>
					<comments>https://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 17 Jan 2019 14:21:54 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Agent]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5177</guid>

					<description><![CDATA[<p>One probably seldom thinks of the SQL Agent jobs scheduled on the SQL Server instance - unless they fail. What if the job failed because something was changed in the job? Maybe you knew about the change, maybe you didn't.</p>
The post <a href="https://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/">Audit SQL Agent Jobs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png"><img loading="lazy" class="wp-image-5179 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png" alt="" width="165" height="191" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent.png 223w, https://jasonbrimhall.info/wp-content/uploads/2019/01/red_db_agent-43x50.png 43w" sizes="(max-width: 165px) 85vw, 165px" /></a></p>
<p>One probably seldom thinks of the <a href="https://docs.microsoft.com/en-us/sql/ssms/agent/sql-server-agent?view=sql-server-2017">SQL Agent</a> jobs scheduled on the SQL Server instance &#8211; unless they fail. What if the job failed because something was changed in the job? Maybe you knew about the change, maybe you didn&#8217;t.</p>
<p>Once upon a time, I was in the position of trying to figure out why a job failed. After a bunch of digging and troubleshooting, it was discovered that the job had changed but nobody knew when or why. Because of that, I was asked to provide a low cost audit solution to try and at least provide answers to the when and who of the change.</p>
<p>Tracking who made a change to an agent job should be a task added to each database professionals checklist / toolbox. Being caught off guard from a change to a system under your purview isn&#8217;t necessarily a fun conversation &#8211; nor is it pleasant to be the one to find that somebody changed your jobs without notice &#8211; two weeks after the fact! Usually, that means that there is little to no information about the change and you find yourself getting frustrated.</p>
<h2>To the Rescue</h2>
<p>When trying to come up with a low to no-cost solution to provide an audit, Extended Events (XE) is quite often very handy. XE is not the answer to everything, but it does come in handy very often. This is one of those cases where an out of the box solution from XE is pretty handy. Let&#8217;s take a look at how a session might be constructed to help track agent job changes.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AuditAgentJobs' )
	DROP EVENT SESSION AuditAgentJobs 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION [AuditAgentJobs] ON SERVER

ADD EVENT sqlserver.sp_statement_completed ( SET collect_object_name = ( 1 )
	ACTION ( package0.callstack, sqlserver.client_app_name,
	sqlserver.database_name, sqlserver.nt_username, sqlserver.query_hash,
	sqlserver.query_plan_hash, sqlserver.session_id, sqlserver.sql_text,
	sqlserver.tsql_stack,package0.event_sequence )
	WHERE (  [sqlserver].[client_app_name] LIKE 'SQLAgent%'
			AND database_name = 'msdb'
	/* if desire just agent jobsteps try something like 'SQLAgent%JobStep%' */
			) ),
ADD EVENT sqlserver.degree_of_parallelism ( 
	ACTION ( package0.callstack, sqlserver.client_app_name,
	sqlserver.database_name, sqlserver.nt_username, sqlserver.query_hash,
	sqlserver.query_plan_hash, sqlserver.session_id, sqlserver.sql_text,
	sqlserver.tsql_stack,package0.event_sequence )
	WHERE (  database_name = 'msdb'
			and statement_type &lt;&gt; 'Select'
	/* if desire just agent jobsteps try something like 'SQLAgent%JobStep%' */
			) ),
ADD EVENT sqlserver.sql_statement_completed (
	ACTION ( package0.callstack, sqlserver.client_app_name,
	sqlserver.database_name, sqlserver.nt_username, sqlserver.query_hash,
	sqlserver.query_plan_hash, sqlserver.session_id, sqlserver.sql_text,
	sqlserver.tsql_stack,package0.event_sequence )
	WHERE (   [sqlserver].[client_app_name] LIKE 'SQLAgent%'
			AND database_name = 'msdb'
	/* if desire just agent jobsteps try something like 'SQLAgent%JobStep%' */
			) )
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\AuditAgentJobs.xel' )
WITH ( MAX_MEMORY = 512000 KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 5 SECONDS
		, MAX_EVENT_SIZE = 0 KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO
ALTER EVENT SESSION AuditAgentJobs ON SERVER
STATE = START;
GO</pre><p>With this session, I am using degree_of_parallelism as a sort of catch-all in the event that queries that cause a change are not trapped by the other two events (sql_statement_completed and sp_statement_completed). With the degree_of_parallelism event, notice I have a filter to exclude all &#8220;Select&#8221; statement types. This will trim some of the noise and help track the changes faster.</p>
<p>Looking at data captured by this session, I can expect to see results like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit.png"><img loading="lazy" class="aligncenter size-large wp-image-5182" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit-1024x326.png" alt="" width="560" height="178" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit-1024x326.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit-300x95.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit-768x244.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit-50x16.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And the degree_of_parallelism event will catch data such as this.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-5181" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit_dop-1024x124.png" alt="" width="560" height="68" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit_dop-1024x124.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit_dop-300x36.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit_dop-768x93.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/agentjob_audit_dop-50x6.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>In this example, the deletion of a job was captured by the degree_of_parallelism event. In addition to catching all of the various events that fire as Jobs are being changed and accessed, one will also be able to get a closer look at how SQL Agent runs about its routine.<a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><br />
<img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="255" height="255" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 255px) 85vw, 255px" /></a></p>
<h2>The Wrap</h2>
<p>Extended Events can prove helpful for many additional tasks that may not be thought of on an every day basis. With a little more thought, we can often find a cool solution via Extended Events to help us be better data professionals. In this article, we see one example of that put to use by using XE to audit Agent Job changes.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>For another interesting article about SQL Agent, <a href="http://bit.ly/2Fd9SCW">check this one out</a>!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5177" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/">Audit SQL Agent Jobs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/17/audit-sql-agent-jobs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Automating like an Enterprise DBA</title>
		<link>https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automating-like-an-enterprise-dba</link>
					<comments>https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Jan 2019 20:50:12 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5161</guid>

					<description><![CDATA[<p>One of the things that should seem very commonplace to a data professional is the effort to become a lazy DBA. A lazy DBA is not a bad thing. It just means the DBA works hard to automate the repetitive mundane tasks that may be tedious and/or time consuming.</p>
The post <a href="https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/">Automating like an Enterprise DBA</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation.png"><img loading="lazy" class="wp-image-5162 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation.png" alt="" width="174" height="170" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation.png 351w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation-300x293.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_automation-65x65.png 65w" sizes="(max-width: 174px) 85vw, 174px" /></a>TSQL Tuesday</h2>
<p>The second Tuesday of the month comes to us a little early this month. That means it is time again for another group blog party called TSQLTuesday. This party that was started by Adam Machanic has now been going for long enough that changes have happened (such as Steve Jones (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) managing it now). For a nice long read, you can find a nice roundup of all TSQLTuesdays over <a href="http://tsqltuesday.com/">here</a>.</p>
<h2>Automation</h2>
<p>The theme as chosen by Garry Bargsley (<a href="https://garrybargsley.com">b</a> | <a href="https://twitter.com/gbargsley">t</a>) is about <a href="https://garrybargsley.com/t-sql-tuesday-110-automate-all-the-things/">automation</a>. Specifically, Garry has provided two requirements about automation for this month. As is always, there is leeway in a post that participates in TSQL Tuesday.</p>
<p>One of the things that should seem very commonplace to a data professional is the effort to become a lazy DBA. A lazy DBA is not a bad thing. It just means the DBA works hard to automate the repetitive mundane tasks that may be tedious and/or time consuming. Time can always be better spent somewhere else, right?</p>
<p>If you are lacking in any ideas for what can be automated, here are a few TSQL Tuesday roundups from when we have talked about automation previously (yes it is a hot topic &#8211; ALWAYS!).</p>
<ol>
<li>August 2010 &#8211; <a href="http://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/" class="broken_link">Beach Time</a> &#8211; what do you automate to earn beach time?</li>
<li>February 2011 &#8211; <a href="https://sqlasylum.wordpress.com/2011/02/11/t-sql-tuesday-15-summary/">Automation in SQL Server</a> &#8211; Give your best tricks for making your life easier through automation.</li>
<li>January 2014 &#8211; <a href="https://sqlchow.wordpress.com/2014/01/07/t-sql-tuesday-050-automation-how-much-of-it-is-the-same/">Automation</a> &#8211; How much of it is the same?</li>
<li>September 2015 &#8211; <a href="http://www.midnightdba.com/Jen/2015/09/the-tsql2sday-70-roundup/">The Enterprise</a> &#8211; How does one manage an enterprise of databases?</li>
<li>September 2017 &#8211; <a href="https://sqldbawithabeard.com/2017/09/20/tsql2sday-get-postroundup/">PowerShell Automation</a> &#8211; Find something and automate it.</li>
</ol>
<p>In the past, I have written about automation a few times. Some of my favorites are <a href="http://jasonbrimhall.info/2014/01/14/t-sql-tuesday-050-automating-database-restores/">automated restores</a>, <a href="http://jasonbrimhall.info/2017/04/11/t-sql-tuesday-089-the-cloud-and-job-security/">automation in the cloud</a>, and my <a href="http://jasonbrimhall.info/2018/07/10/just-cant-cut-that-cord/">poor mans automated audit</a>.</p>
<p>I automate many processes and have automated loads of tasks over the years. You see, automation means I can spend more time doing other tasks that require more time, more thought/concentration, more effort, and frankly more interest. So what have I automated recently that may be different from what I have previously written? This time, I have something that may seem utterly trivial but in the end it is rather tedious and time consuming to manually check over and over and over.</p>
<h3>PowerShell</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm.png"><img loading="lazy" class="size-full wp-image-5170 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm.png" alt="" width="219" height="212" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm.png 219w, https://jasonbrimhall.info/wp-content/uploads/2019/01/facepalm-50x48.png 50w" sizes="(max-width: 219px) 85vw, 219px" /></a>When I automate a task, I generally will try to use the tool that seems the most appropriate for the task: windows scheduler, SQL Agent, TSQL, SSIS, VB, C#  and now I am trying to add PoSh to that list. I don&#8217;t believe there is a one size fits all automation tool. Sometimes, one has to be flexible enough to adapt other technologies into the tool-belt.</p>
<p>I have been working with a client to check their servers for SQL Server version, SSMS version, PoSH version and so on. All of this to try and get the appropriate updates installed on the server. Believe it or not, many of their servers were still running PoSH v2 and didn&#8217;t have any Service Packs installed for their database servers. OUCH!</p>
<p>Touching every single server (even if it is only 10 servers) is far too tedious and error prone. So, I spent a little time klooging together with my neanderthal level PoSH skills and found a way to retrieve various pieces of information from the servers and then store those data points in a database so I could report on the entire environment easily with TSQL. In addition, I could show change history and find approximately (at worst) when an update was installed.</p>
<p>Of all of the things I scripted to start tracking, the one I want to share this time can also be used to audit security on each of the database servers. I use the following script to audit the localadmins on each of the database servers in the enterprise. In order to trap each local admin on the server, I also recurse through domain groups to find all users of a group to find everybody that may have access. Here is a version of the script that is similar to what I use now.</p><pre class="urvanov-syntax-highlighter-plain-tag">Param (
[string]$TypeName = $null #"myserver_type"
,[string]$svrname = "" #"myserver"
)

import-module sqlserver
import-module activedirectory

$c = Get-Credential -Credential mydomain\mylogin

$dtime = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff"
$ScriptProcess = "Get-AdminsV2"

$Result = [PSCustomObject] @()

IF($svrname){
$SQLServerList = [ordered]@{
    ServerName = $svrname}
}
else {
if($TypeName){
$SQLServerList = Invoke-Sqlcmd -serverinstance myserver -database "DBA" -query "select distinct ServerName From Mgmt.ServerList sl inner join [Mgmt].[ServerType] st on sl.ServerTypeID = st.TypeID where st.TypeName = '$TypeName'"
}
else{
$SQLServerList = Invoke-Sqlcmd -serverinstance myserver -database "DBA" -query "select distinct ServerName From Mgmt.ServerList sl inner join [Mgmt].[ServerType] st on sl.ServerTypeID = st.TypeID where st.TypeID &lt;&gt; 7;"
}
}

foreach ($server in $SQLServerList)
{
$svrname = $server.ServerName

If  (Test-Connection -ComputerName  $svrname -Count  1 -Quiet ) {
try {
$dtime = get-date
$skipchecks = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck

 Try  { 
$admins = Invoke-Command -Computername $svrname -ErrorAction Stop -SessionOption $skipchecks -Credential $c -ScriptBlock {  Get-LocalGroupMember -Group "Administrators" }
&lt;#$admins = $admins |? {$_.groupcomponent –like '*"Administrators"'}  
  
$admins |% {  
$_.partcomponent –match “.+Domain\=(.+)\,Name\=(.+)$” &gt; $nul  
$admin = $matches[1].trim('"') + “\” + $matches[2].trim('"') 
#&gt;
}
Catch {
  $EObject = [ordered]@{
  ScriptErrorId = ''
  Computername = $svrname
  ScriptError = $_.ToString()
  ScriptProcess = $ScriptProcess
  PollDate = $dtime
  }
  $EResult = (New-Object -TypeName PSCustomObject -Property $EObject)

  # $EResult
  Write-SqlTableData -ServerInstance "myserver" -DatabaseName "DBA" -SchemaName "Monitor" -TableName "ScriptErrors" -Force -InputData $EResult

   # Continue 
  }
  #$admins
 Foreach ($admin in $admins) {
  
    $Adm = $admin.Name.ToString()
    $ObjClass = $admin.objectclass.ToString()
&lt;#
    $admin
    $Adm
    $Admin.Name
    $Admin.ObjectClass
    $ObjClass
    #&gt;

  If ($ObjClass -match 'Group') {
  #"Group Matched"
  $domain,$group = $adm.split('\')
  #$domain
  #$group
    $members = Get-ADGroupMember -Identity "$group" -Recursive
    $grouphierarchy = $Adm

    function Get-GroupHierarchy ($group)
        {
        import-module activedirectory
        $groupMember = get-adgroupmember $group | sort-object objectClass -descending
           foreach ($member in $groupMember)
            {
            if ($member.ObjectClass -match "group")
                {
                $grouphierarchy += "\^\$($domain)\$($member.name)"
                $grouphierarchy
                Get-GroupHierarchy $member.name}}
        }
 
    $grouphierarchy += Get-GroupHierarchy $group
    #$grouphiho.ToString()
    #$grouphierarchy.tostring()

  $Object = [ordered]@{
  AdminId = ''
  Computername = $svrname
  Admin = $Adm
  ScriptProcess = $ScriptProcess
  PollDate = $dtime
}

  $Result = (New-Object -TypeName PSCustomObject -Property $Object)
  #"Result before write to sql attempt"

  Write-SqlTableData -ServerInstance "myserver" -DatabaseName "DBA" -SchemaName "Monitor" -TableName "LocalAdmins" -Force -InputData $Result
  $Result.Clear


    foreach ($member in $members) {
 
 #$member.name

    $Object = [ordered]@{
    AdminId = ''
    Computername = $svrname
    # Admin = "$($domain)\$($group)\^\$($domain)\$($member.name)"
    Admin = "$($grouphierarchy)\^\$($domain)\$($member.name)"
    ScriptProcess = $ScriptProcess
    PollDate = $dtime
    }
  
  $Result = (New-Object -TypeName PSCustomObject -Property $Object)

  Write-SqlTableData -ServerInstance "myserver" -DatabaseName "DBA" -SchemaName "Monitor" -TableName "LocalAdmins" -Force -InputData $Result
  $Result.Clear
  }

 }
  ELSE {
  #"else reached"
    $Object = [ordered]@{
    AdminId = ''
    Computername = $svrname
    Admin = $Adm
    ScriptProcess = $ScriptProcess
    PollDate = $dtime
    }
  
  $Result = (New-Object -TypeName PSCustomObject -Property $Object)

  Write-SqlTableData -ServerInstance "myserver" -DatabaseName "DBA" -SchemaName "Monitor" -TableName "LocalAdmins" -Force -InputData $Result
  $Result.Clear
 
 }
}
 #$Result |FT -AutoSize
}
catch{}
}
}</pre><p>Could I improve on the efficiency of this script? Most definitely I believe there is room for improvement. Remember, I am very novice at my PoSH skills. Scripting issues aside, it works and basically fetches a list of servers from a database, then iterates through each of those servers to fetch the complete list of local admins on each of the servers. Then the script writes out the complete list of admins for each server back to my database so I can generate a history of changes to the admins or report on who has admin access on the server.</p>
<p>For anybody that has admin access to a database server, the permission path (nested group path) is recorded in hierarchical form separated by the carrot character (^). Using this script, I have been able to provide a report to domain admins to clean out various unwanted individuals from access that was not intended or necessary.</p>
<h3>Wrapping it Up</h3>
<p><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>Automation is an essential tool for every data professional. Wait, no, that&#8217;s not accurate. Automation is an essential tool in all facets of IT. Automation is a definitive method to work more efficiently and offload some of the mundane repetitive tasks that consume too much time.</p>
<p>Even if the task is not trivial but needs to be repeated and done so without error, the best tool is automation. Performing tasks over and over naturally leads to higher risk of error. The way to minimize that risk is to perform the task via some automation script or routine.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5161" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/">Automating like an Enterprise DBA</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/08/automating-like-an-enterprise-dba/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Short Circuiting Your Session</title>
		<link>https://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=short-circuiting-your-session</link>
					<comments>https://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 05 Jan 2019 16:14:16 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5149</guid>

					<description><![CDATA[<p>It isn't very often that one would consider a short circuit to be a desired outcome. In SQL Server we have a cool exception to that rule - Extended Events (XE).</p>
The post <a href="https://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/">Short Circuiting Your Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/day12_v2.png"><img loading="lazy" class="wp-image-4931 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day12_v2.png" alt="" width="143" height="206" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day12_v2.png 143w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day12_v2-35x50.png 35w" sizes="(max-width: 143px) 85vw, 143px" /></a></p>
<p>It isn&#8217;t very often that one would consider a short circuit to be a desired outcome. In SQL Server we have a cool exception to that rule &#8211; Extended Events (XE).</p>
<p>What exactly is a short circuit and why would it be undesirable in most cases? I like to think of a short circuit as a &#8220;short cut&#8221; in a sense.</p>
<p>I remember an experience that happened while running a marathon many years ago. A person I had pulled up next to and started chatting with needed to use the restroom. I continued along on the course and a mile later I saw the same person suddenly reappear on the course ahead of me. This person had found a short cut on the course and decided to use it. If caught, he would have been disqualified. He may have saved himself a mile of running and gotten a better time, but the act was to take a course that was not the intended official course for that race.</p>
<p>In electricity, a short circuit does a similar thing. The electricity will follow the path of least resistance. Sometimes, this means the unofficial desired path for the current to flow. The end result can be very bad in electrical terms as an overload may occur which can cause overheating and sparking.</p>
<h2>Why would we want an overload?</h2>
<p>In electricity and mechanical parts, we really don&#8217;t want anything to cause short cuts in the system. On the other hand, when we are dealing with tracing and anything that can put a load on the system, we want that load to be as small as possible.</p>
<p>Trying to trace for problems in the SQL Server engine comes with a cost. That cost comes in the form of additional resource requirements which could mean fewer resources available for the engine to process user requests. None of us wants for the end-user to be stuck waiting in a queue for resources to free due to our tracing activities (i.e. <a href="http://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/">Profiler</a>). So a lightweight method (to trace) is needed.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/xe_shortcircuit.png"><img loading="lazy" class=" wp-image-5156 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/xe_shortcircuit.png" alt="" width="246" height="299" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/xe_shortcircuit.png 485w, https://jasonbrimhall.info/wp-content/uploads/2019/01/xe_shortcircuit-247x300.png 247w, https://jasonbrimhall.info/wp-content/uploads/2019/01/xe_shortcircuit-41x50.png 41w" sizes="(max-width: 246px) 85vw, 246px" /></a>XE is that lightweight method. A big part of the reason for that is the ability of XE to short-circuit (short-cut) to the end result. How can an XE session short-circuit? Think logic constraints and predicates. I <a href="http://bit.ly/1PPvtzm">previously demonstrated how to short-cut</a> the system by using a counter in the predicate, but the short circuit isn&#8217;t constrained to just a counter in the predicate. The short-circuit is super critical to performance and success, but it is often misunderstood and poorly explained. So, I am trying to explain it again &#8211; better.</p>
<p>If we follow the principle that a short-circuit is the <strong>path of least resistance</strong>, we have a construct for how to build the predicate for each event in a session. Think of it as path of least work. Just like with children, XE and electricity will evaluate each junction with a bit of logic. Do I have to do more work if I go down this path or less work? Less work? Great, I am going in this direction.</p>
<p>As an event is fired off and is picked up by the XE session, the session compares that event payload to the conditions in the predicate. Everything in the predicate is processed in precise order &#8211; until a predicate condition fails the comparison (or result is false). Immediately when a condition results to negative (false) then the XE session jumps right to the end and closes. Nothing more is processed.</p>
<p>This is why <a href="http://bit.ly/1PPvtzm">predicate order matters</a>. If a predicate evaluates to false, the short-circuit is invoked and the evaluation ends. With that in mind, what is the most desirable condition in the predicate to be first?</p>
<p>I have heard multiple people state that the &#8220;most likely to succeed&#8221; predicate should be first. Well, if the &#8220;most likely success&#8221; is first what does that mean for your session? It will have to do more work! That is exactly the model that Profiler used (uses) and we all know what happens with Profiler and performance!</p>
<p>No! We don&#8217;t want the most likely to succeed to be the first predicate to be evaluated. We want the least likely to succeed to be first. This means less work &#8211; just as illustrated in the previous image where the short-circuit is represented by the red line. If you would like, we can also call each of the three light-bulbs &#8220;predicates&#8221; and the switch would be the event (nothing is traced in the session if the event doesn&#8217;t even match).</p>
<h2>Which Comes First?</h2>
<p>This brings us to the hard part. How should one order the predicates for each event? The answer to that is not as cut and dry as you probably want. There are many variables in the equation. For instance, the first variable would be the environment. Each SQL environment is different and that makes a difference in evaluating events and predicates. However, lets use a common-ish set of criteria and say we need to decided between database name and query duration.</p><pre class="urvanov-syntax-highlighter-plain-tag">ADD EVENT sqlserver.sp_statement_completed ( 
	SET collect_object_name = ( 1 )
	WHERE ( [sqlserver].[database_name] = 'AdventureWorks2014'
			AND [duration] &gt; ( 5000000 ) -- 5 seconds
)</pre><p>The questions in this case now comes down to 1) how many databases are on the server? and 2) what are the chances of a query lasting more than 5 seconds? If you have 100 databases on the server and 99 of them frequently see queries over 5 seconds, then this predicate order would make sense. What if you have only 4 databases and a query over 5 seconds occurs roughly 1 in 10,000 times? Then the predicate order should be switched to the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">ADD EVENT sqlserver.sp_statement_completed ( 
	SET collect_object_name = ( 1 )
	WHERE ( [duration] &gt; ( 5000000 ) -- 5 seconds
			AND [sqlserver].[database_name] = 'AdventureWorks2014'
)</pre><p>If you don&#8217;t have a database by the name of &#8220;AdventureWorks2014&#8221; then the database name predicate would remain first but really it should be changed to an appropriate database name that exists.<a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="255" height="255" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 255px) 85vw, 255px" /></a></p>
<h2>The Wrap</h2>
<p>Predicate order in an XE session is very important. A well designed predicate can lead to a highly tuned and well performing trace that will ease your life as a data professional. Just remember, contrary to various people out there, the most desirable predicate order is to have the &#8220;<strong>least likely to succeed</strong>&#8221; first and the &#8220;<strong>most likely to succeed</strong>&#8221; should be last.</p>
<p>And yes, we truly do want our XE sessions to short-circuit! As we aspire to do less busy work, an XE session should be configured to do as little work as is necessary.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the eleventh article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5149" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/">Short Circuiting Your Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Automatic Tuning Monitoring and Diagnostics</title>
		<link>https://jasonbrimhall.info/2019/01/04/automatic-tuning-monitoring-and-diagnostics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automatic-tuning-monitoring-and-diagnostics</link>
					<comments>https://jasonbrimhall.info/2019/01/04/automatic-tuning-monitoring-and-diagnostics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 04 Jan 2019 13:32:46 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5141</guid>

					<description><![CDATA[<p>Thanks to Extended Events (XE), we have access to a guide of sorts that will help us better understand if our shiny new tool (automatic tuning) is operating as desired.</p>
The post <a href="https://jasonbrimhall.info/2019/01/04/automatic-tuning-monitoring-and-diagnostics/">Automatic Tuning Monitoring and Diagnostics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/day11_v2.png"><img loading="lazy" class="wp-image-4930 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day11_v2.png" alt="" width="118" height="201" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day11_v2.png 118w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day11_v2-29x50.png 29w" sizes="(max-width: 118px) 85vw, 118px" /></a></p>
<p>Cool new toys/tools have been made available to the data professional. Among these tools are query data store and <a href="https://docs.microsoft.com/en-us/sql/relational-databases/automatic-tuning/automatic-tuning?view=sql-server-2017">automatic tuning</a>. These two tools actually go hand in hand and work pretty nicely together.</p>
<p>With most new tools, there is usually some sort of instruction manual along with a section on how to troubleshoot the tool. In addition to the manual, you usually have some sort of guide as to whether or not the tool is working within desired specifications or not.</p>
<p>Thanks to Extended Events (XE), we have access to a guide of sorts that will help us better understand if our shiny new tool is operating as desired.</p>
<h2>Operationally Sound</h2>
<p>XE provides a handful of events to help us in evaluating the usage of Automatic Tuning in SQL Server. To find these events, we can simply issue a query such as the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">select xo.name, xo.object_type, xo.description
	From sys.dm_xe_objects xo
	where xo.name like '%autom%tun%'
	or xo.description like '%autom%tun%'
	order by xo.object_type;</pre><p>When executed, this query will provide a result set similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events.png"><img loading="lazy" class="aligncenter size-large wp-image-5143" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events-1024x236.png" alt="" width="560" height="129" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events-1024x236.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events-300x69.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events-768x177.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_events-50x12.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I have grouped the results from this query into three sets. In the red set, I have four events that are useful in the diagnostics and monitoring of automatic tuning. These events show errors, diagnostic (and performance) data, configuration changes and state changes.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning.png"><img loading="lazy" class="wp-image-5146 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning.png" alt="" width="166" height="165" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning.png 225w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning-144x144.png 144w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/db_red_highlights_tuning-65x65.png 65w" sizes="(max-width: 166px) 85vw, 166px" /></a>For instance, the state change event will fire when automatic tuning is enabled and will also fire when the database is started (assuming the session is running). The automatic_tuning_diagnostics event fires roughly every 30 minutes on my server to gather performance and diagnostic data that can help me understand how well the feature is performing for my workload in each database.</p>
<p>Highlighted in the green section is a couple of maps that show the various values for the current phase or state of the automatic tuning for each database. One can view these different values with the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">select mv.name,mv.map_key,mv.map_value
	From sys.dm_xe_map_values mv
	where mv.name in ('aprc_state','aprc_task')
	order by mv.name, mv.map_key;</pre><p>This query yields these results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_maps.png"><img loading="lazy" class="aligncenter wp-image-5144" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_maps.png" alt="" width="512" height="252" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_maps.png 612w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_maps-300x148.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_maps-50x25.png 50w" sizes="(max-width: 512px) 85vw, 512px" /></a>We will see those values in use in the events in a session shortly.</p>
<p>We have seen some of the events and some of the maps at a very quick glance. That said, it is a good time to pull it all together and create a session.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AutoTuneMonitor' )
	DROP EVENT SESSION AutoTuneMonitor
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION [AutoTuneMonitor] ON SERVER

ADD EVENT qds.automatic_tuning_config_change(
ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
	  )
,ADD EVENT qds.automatic_tuning_diagnostics(
ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
  )
  ,ADD EVENT qds.automatic_tuning_state_change(
  ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
	)
  ,ADD EVENT qds.automatic_tuning_error(
  ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
	)
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\AutoTuneMonitor.xel')
,ADD TARGET package0.ring_buffer
 WITH (MAX_DISPATCH_LATENCY=5 SECONDS,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF);
GO

ALTER EVENT SESSION [AutoTuneMonitor] ON SERVER STATE = START;
GO</pre><p>Seeing as this session won&#8217;t produce any results without Query data store being enabled and automatic tuning being configured for a database, I have set all of that up in a demo database and have some fresh results to display.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2.png"><img loading="lazy" class="aligncenter size-large wp-image-5145" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2-1024x550.png" alt="" width="560" height="301" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2-1024x550.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2-300x161.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2-768x412.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor2-50x27.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Here I show an example of the output filtered for just the diagnostics event. Note the phase_code shows some of those map values previously discussed. I can also see that roughly every 30 minutes each database undergoes a diagnostics check.</p>
<p>Now, looking at another event in that same session, I can see the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor.png"><img loading="lazy" class="aligncenter size-large wp-image-5147" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor-1024x153.png" alt="" width="560" height="84" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor-1024x153.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor-300x45.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor-768x115.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/autotune_xemonitor-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>The state_code in this event payload demonstrates more values from the maps previously discussed (CorrectionEnabled and DetectionEnabled). In this case, the automatic_tuning_state_change fired a few times for database 6 because that database was intentionally taken offline and set back online to test the event.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="255" height="255" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 255px) 85vw, 255px" /></a>The use of these particular events in this session is very lightweight. I don&#8217;t have a predicate configured for any of the events because I wanted to trap everything. Of course, the number of events can increase with an increased load and usage scenarios on different servers.</p>
<h2>The Wrap</h2>
<p>Automatic tuning can be a pretty sharp tool in your tool-belt on your way to becoming that rock-star DBA. As you start to sharpen your skills with this tool, you will need to have some usage and diagnostic information at your fingertips to ensure everything is running steady. This event session is able to provide that diagnostic information and keep you on top of the automatic tuning engine.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the eleventh article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5141" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/04/automatic-tuning-monitoring-and-diagnostics/">Automatic Tuning Monitoring and Diagnostics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/04/automatic-tuning-monitoring-and-diagnostics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Event Tracing for Windows Target</title>
		<link>https://jasonbrimhall.info/2019/01/03/event-tracing-for-windows-target/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=event-tracing-for-windows-target</link>
					<comments>https://jasonbrimhall.info/2019/01/03/event-tracing-for-windows-target/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 03 Jan 2019 13:41:07 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5102</guid>

					<description><![CDATA[<p>There are many useful targets within SQL Server's Extended Events. Of all of the targets, the most daunting is probably the Event Tracing for Windows (ETW) target. The ETW target represents doing something that is new for most DBAs which means spending a lot of time trying to learn the technology and figure out the little nuances and the difficulties that it can present.</p>
The post <a href="https://jasonbrimhall.info/2019/01/03/event-tracing-for-windows-target/">Event Tracing for Windows Target</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/day10_v2.png"><img loading="lazy" class="wp-image-4929 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day10_v2.png" alt="" width="147" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day10_v2.png 147w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day10_v2-38x50.png 38w" sizes="(max-width: 147px) 85vw, 147px" /></a>There are many useful targets within SQL Server&#8217;s Extended Events. Of all of the targets, the most daunting is probably the Event Tracing for Windows (ETW) target. The ETW target represents doing something that is new for most DBAs which means spending a lot of time trying to learn the technology and figure out the little nuances and the difficulties that it can present.</p>
<p>With all of that in mind, I feel this is a really cool feature and it is something that can be useful in bringing the groups together that most commonly butt heads in IT (Ops, DBA, Devs) by creating a commonality in trace data and facts. There may be more on that later!</p>
<h2>Target Rich</h2>
<p>The ETW target is a trace file that can be merged with other ETW logs from Windows or applications (if they have enabled this kind of logging). You can easily see many default ETW traces that are running or can be run in Windows via Perfmon or from the command line with the following command.</p><pre class="urvanov-syntax-highlighter-plain-tag">logman -ets</pre><p>And from the gui&#8230;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw.png"><img loading="lazy" class="aligncenter size-large wp-image-5105" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw-1024x728.png" alt="" width="560" height="398" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw-1024x728.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw-300x213.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw-768x546.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/perfmonetw.png 1991w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Finding the traces is not really the difficult part with this type of trace. The difficult parts (I believe) come down to learning something new and different, and that <a href="https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/event-tracing-for-windows-target?view=sql-server-2017">Microsoft warns</a> that you should have a working knowledge of it first (almost like a big flashing warning that says &#8220;Do NOT Enter!&#8221;). Let&#8217;s try to establish a small knowledgebase about this target to ease some of the discomfort you may now have.</p>
<p>One can query the DMVs to get a first look at what some of the configurations may be for this target (optional and most come with defaults already set).</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT	xo.name AS TargetName
	, xoc.name AS Attribute
	, xoc.type_name
	, xoc.column_type
	, xoc.column_value AS DefaultValue
	, xoc.description
FROM	sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.name = xoc.object_name
			AND xo.package_guid = xoc.object_package_guid
WHERE xo.name = 'etw_classic_sync_target';</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs.png"><img loading="lazy" class="aligncenter size-large wp-image-5107" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs-1024x138.png" alt="" width="560" height="75" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs-1024x138.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs-300x41.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs-768x104.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etw_target_configs-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Six configurations in total are available for the ETW target. In the query results (just above) you will see that the default value for each configuration option is displayed. For instance, the default_xe_session_name has a default value of XE_DEFAULT_ETW_SESSION. I like to change default names and file paths, so when I see a name such as that, rest assured I will change it. (Contrary to popular belief, the path and session name default values can certainly be changed.)</p>
<p>As I go forward into creating an XE session using the ETW target, it is important to understand that only 1 ETW session can exist. This isn&#8217;t a limitation of SQL Server per se, rather a combination of the use of the ETW Classic target (for backwards compatibility) and Windows OS constraints. If the ETW target is used in more than one XE session on the server (even in a different SQL Server instance), then all of them will use the same trace target in windows (consumer). This can cause a bit of confusion if several sessions are running concurrently.</p>
<p><img loading="lazy" class=" wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="260" height="260" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 260px) 85vw, 260px" /></p>
<p>My recommendation here is to use a very precise and targeted approach when dealing with the ETW target. Only run it for a single XE session at a time. This will make your job of correlating and translating the trace much easier.</p>
<p>The ETW target is a synchronous target and does NOT support asynchronous publication. With the synchronous consumption of events by the target, and if you have multiple sessions with the same event defined, the event will be consumed just a single time by the ETW target. This is a good thing!</p>
<p>Two more tidbits about the ETW target before creating an event session and looking at more metadata. The default path for the target is %TEMP%\&lt;filename&gt;.etl. This is not defined in the configuration properties but is hardwired. Any ideas why one might want to specify a different path? I don&#8217;t like to use the temp directory for anything other than transient files that are disposable at any time!</p>
<p>Whether you change the directory from the default or leave it be, understand that it cannot be changed after the session starts &#8211; even if other sessions use the same target and are started later. However, if you flush the session and stop it, then you can change it. I do recommend that it be changed!</p>
<p>Second tidbit is that other than the classic target, ETW does have a manifest based provider. Should Extended Events (XE) be updated to use the manifest based provider then some of the nuances will disappear with translating some of the trace data (future article to include ntrace and xperf &#8211; stay tuned). For now, understand that viewing the ETW trace data is not done via SQL Server methods. Rather, you need to view it with another tool. This is due to the fact that the ETW is an OS level trace and not a SQL Server trace.</p>
<h2>Session Building</h2>
<p>If it is not clear at this point, when creating an XE session that utilizes the ETW target, two traces are, in essence, created. One trace is a SQL server (XE) trace that can be evaluated within SQL Server. The second trace is an ETW trace that is outside the realm of SQL Server and thus requires new skills in order to review it. Again, this second trace can be of extreme help because it is more easily merged with other ETW traces (<a href="https://www.mssqltips.com/sqlservertip/1212/correlating-performance-monitor-and-sql-server-profiler-data/">think merging perfmon with sql trace</a>).</p>
<p>When I create a session with an ETW target, it would not be surprising to see that I have two targets defined. One target will be the ETW target and a second may be a file target or any of the others if it makes sense. The creation of two targets is not requisite for the XE session to be created. The XE data will still be present in the livestream target even without a SQL related target.</p>
<p>Before creating a session, I need to cover a couple of possible errors that won&#8217;t be easy to find on google.</p>
<blockquote><p><span style="color: #ff0000;">Msg 25641, Level 16, State 0, Line 101 </span><span style="color: #ff0000;">For target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.etw_classic_sync_target&#8221;, </span><span style="color: #ff0000;">the parameter &#8220;default_etw_session_logfile_path&#8221; passed is invalid. </span><br />
<span style="color: #ff0000;">The operating system returned <strong>error 5 (ACCESS_DENIED)</strong> while creating an ETW tracing session. </span><br />
<span style="color: #ff0000;">ErrorFormat: Ensure that the SQL Server startup account is a member of the &#8216;Performance Log Users&#8217; group and then retry your command.</span></p></blockquote>
<p>I received this error message even with my service account being a member of the &#8220;Performance Log Users&#8221; windows group. I found that I needed to grant explicit permissions to the service account to the logging directory that I had specified.</p>
<blockquote><p><span style="color: #ff0000;">Msg 25641, Level 16, State 0, Line 105 For target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.etw_classic_sync_target&#8221;, the parameter &#8220;default_xe_session_name&#8221; passed is invalid. </span><br />
<span style="color: #ff0000;">The default ETW session has already been started with the name &#8216;<strong>unknown</strong>&#8216;. </span><br />
<span style="color: #ff0000;">Either stop the existing ETW session or specify the same name for the default ETW session </span><span style="color: #ff0000;">and try your command again.</span></p></blockquote>
<p>This error was more difficult than the first and probably should have been easier. I could not find the session called &#8216;unknown&#8217; hard as I might have tried. Then it occurred to me (sheepishly) that the path probably wanted a file name too. If you provide a path and not a filename for the trace file, then this error will nag you.</p>
<p>I found both error cases to be slightly misleading but resolvable quickly enough.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'SVRLoginAudit_etw' )
	DROP EVENT SESSION SVRLoginAudit_etw
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION [SVRLoginAudit_etw]
	ON SERVER
	ADD EVENT sqlserver.login
	( SET collect_database_name = ( 1 )
		, collect_options_text = ( 1 )
	ACTION ( package0.collect_system_time
		, package0.event_sequence
		, sqlserver.client_app_name
		, sqlserver.client_connection_id
		, sqlserver.client_hostname
		, sqlserver.context_info
		, sqlserver.database_id
		, sqlserver.database_name
		, sqlserver.nt_username
		, sqlserver.server_principal_name
		, sqlserver.session_id
		, sqlserver.session_nt_username
		, sqlserver.sql_text
		, sqlserver.username ))
	ADD TARGET package0.event_file
	( SET filename = N'C:\Database\XE\SVRLoginAudit_etw.xel'
		, max_file_size = ( 5120 ), max_rollover_files = ( 6 )),
 ADD TARGET package0.etw_classic_sync_target ( --keeping mostly default values
	SET default_etw_session_logfile_path = 'C:\Database\XE\SVRLoginAudit_etw.etl' 
	, default_xe_session_name = 'NotYourETWXESession' -- changed from XE_DEFAULT_ETW_SESSION
	, default_etw_session_buffer_size_kb = 128
	, default_etw_session_logfile_size_mb = 20
	, retries = 0
	, deferred_etw_creation = 0
	)
	WITH ( MAX_MEMORY = 4096KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 30 SECONDS
		, MAX_EVENT_SIZE = 0KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO</pre><p>The session is pretty straight forward here. I am just auditing logins that occur on the server and sending them to both the ETW and event_file targets. To validate the session is created and that indeed the ETW session is not present in SQL Server, I have the following script.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ISNULL(ses.name,xse.name) AS SessionName
		, CASE
			WHEN ISNULL(ses.name,'') = ''
			THEN 'Private'
			ELSE 'Public'
			END AS SessionVisibility
		, CASE
			WHEN ISNULL(xse.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS SessionRunning
		, CASE
			WHEN ISNULL(xse.name,'') = ''
				AND ISNULL(ses.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS IsDeployed
	FROM sys.server_event_sessions ses
	FULL OUTER JOIN sys.dm_xe_sessions xse
		ON xse.name =ses.name
	WHERE ses.name IN ('NotYourETWXESession','XE_DEFAULT_ETW_SESSION','SVRLoginAudit_etw')
		OR xse.name IN ('NotYourETWXESession','XE_DEFAULT_ETW_SESSION','SVRLoginAudit_etw')
	ORDER BY ses.event_session_id;
GO
ALTER EVENT SESSION SVRLoginAudit_etw ON SERVER
STATE = START;

SELECT ISNULL(ses.name,xse.name) AS SessionName
		, CASE
			WHEN ISNULL(ses.name,'') = ''
			THEN 'Private'
			ELSE 'Public'
			END AS SessionVisibility
		, CASE
			WHEN ISNULL(xse.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS SessionRunning
		, CASE
			WHEN ISNULL(xse.name,'') = ''
				AND ISNULL(ses.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS IsDeployed
	FROM sys.server_event_sessions ses
	FULL OUTER JOIN sys.dm_xe_sessions xse
		ON xse.name =ses.name
	WHERE ses.name IN ('NotYourETWXESession','XE_DEFAULT_ETW_SESSION','SVRLoginAudit_etw')
		OR xse.name IN ('NotYourETWXESession','XE_DEFAULT_ETW_SESSION','SVRLoginAudit_etw')
	ORDER BY ses.event_session_id;
GO</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession.png"><img loading="lazy" class="aligncenter size-full wp-image-5109" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession.png" alt="" width="845" height="350" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession.png 845w, https://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession-300x124.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession-768x318.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/deployedetwsession-50x21.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>Despite the absence of the ETW session from SQL Server, I can still easily find it (again either shell or from the perfmon gui). Here is what I see when checking for it from a shell.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession.png"><img loading="lazy" class="aligncenter size-large wp-image-5110" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession-1024x563.png" alt="" width="560" height="308" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession-1024x563.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession-300x165.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession-768x423.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession-50x28.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/notyouretwXEsession.png 1314w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Even though the session (or session data) is not visible from SQL Server, I can still find out a tad more about the target from the XE related DMVs and catalog views.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xse.name AS SessionName, xse.buffer_policy_desc, xse.flag_desc,est.name AS Targetname
		,CASE WHEN est.name = 'event_file'
			THEN sesfo.filename
			ELSE NULL END AS filename
		,CASE WHEN est.name = 'event_file'
			THEN sesfo.max_file_size
			ELSE NULL END AS max_file_size
		,CASE WHEN est.name = 'event_file'
			THEN sesfo.max_rollover_files
			ELSE NULL END AS max_rollover_files
		,CASE WHEN est.name = 'event_file'
			THEN NULL
			ELSE sesfo.default_etw_session_logfile_path END AS default_etw_session_logfile_path
		,CASE WHEN est.name = 'event_file'
			THEN NULL 
			ELSE sesfo.default_xe_session_name END AS default_xe_session_name
		,CASE WHEN est.name = 'event_file'
			THEN NULL 
			ELSE sesfo.default_etw_session_buffer_size_kb END AS default_etw_session_buffer_size_kb
		,CASE WHEN est.name = 'event_file'
			THEN NULL 
			ELSE sesfo.default_etw_session_logfile_size_mb END AS default_etw_session_logfile_size_mb
	FROM sys.server_event_sessions ses
	INNER JOIN sys.dm_xe_sessions xse
		ON xse.name =ses.name
	INNER JOIN sys.server_event_session_targets est
		ON ses.event_session_id = est.event_session_id
	INNER JOIN (
			SELECT *
				FROM    (
					SELECT sesf.event_session_id, sesf.name AS FieldName, sesf.value AS FieldValue
						FROM sys.server_event_session_fields sesf
					) fields
					PIVOT   (
						max(FieldValue)
						FOR FieldName IN (begin_event
								,begin_matching_actions
								,begin_matching_columns
								,collect_cached_text
								,collect_call_stack
								,collect_column_list
								,collect_data
								,collect_database_name
								,collect_feature_data
								,collect_object_name
								,collect_options_text
								,collect_plan_handle
								,collect_resource_description
								,collect_statement
								,end_event
								,end_matching_actions
								,end_matching_columns
								,filename
								,filtering_event_name
								,max_events_limit
								,max_file_size
								,max_memory
								,max_rollover_files
								,metadatafile
								,occurrence_number
								,source
								,source_type
								,default_etw_session_logfile_path
								,default_etw_session_buffer_size_kb
								,default_etw_session_logfile_size_mb
								,retries
								,default_xe_session_name
								,deferred_etw_creation)
					) PVT
				) sesfo
		ON est.event_session_id = sesfo.event_session_id
	WHERE ses.name IN ('NotYourETWXESession','XE_DEFAULT_ETW_SESSION','SVRLoginAudit_etw');</pre><p>Running that query will result in something similar to this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout.png"><img loading="lazy" class="aligncenter size-large wp-image-5111" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout-1024x85.png" alt="" width="560" height="46" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout-1024x85.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout-300x25.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout-768x64.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/etwtargetconfigout-50x4.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<h2>The Wrap</h2>
<p>I have just begun to scratch the surface of the ETW target. This target can provide plenty of power for troubleshooting when used in the right way. The difficulty may seem to be getting to that point of knowing what the right way is. This target may not be suitable for most troubleshooting issues &#8211; unless you really need to correlate real windows metrics to SQL metrics and demonstrate to Joe Sysadmin that what you are seeing in SQL truly does correlate to certain conditions inside of windows. Try it out and try to learn from it and figure out the right niche for you. In the interim, stay tuned for a follow-up article dealing with other tools and ETW.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the tenth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5102" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/03/event-tracing-for-windows-target/">Event Tracing for Windows Target</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/03/event-tracing-for-windows-target/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Checking your Memory with XE</title>
		<link>https://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=checking-your-memory-with-xe</link>
					<comments>https://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 02 Jan 2019 13:46:46 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5063</guid>

					<description><![CDATA[<p>It is well known and understood that SQL Server requires a substantial amount of memory. SQL Server will also try to consume as much memory as possible from the available system memory - if you let it. Sometimes, there will be some contention / pressure with the memory.</p>
The post <a href="https://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/">Checking your Memory with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/day9_v2.png"><img loading="lazy" class="wp-image-4928 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day9_v2.png" alt="" width="144" height="216" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day9_v2.png 144w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day9_v2-33x50.png 33w" sizes="(max-width: 144px) 85vw, 144px" /></a>It is well known and understood that SQL Server requires a substantial amount of memory. SQL Server will also try to consume as much memory as possible from the available system memory &#8211; if you let it. Sometimes, there will be some contention / pressure with the memory.</p>
<p>When contention occurs, the users will probably start screaming because performance has tanked and deadlines are about to be missed. There are many different ways (e.g. <a href="https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/04/using-sys-dm_os_ring_buffers-to-diagnose-memory-issues-in-sql-server/">here</a> or <a href="https://www.mssqltips.com/sqlservertip/2304/how-to-identify-microsoft-sql-server-memory-bottlenecks/">here</a>) to try and observe the memory conditions and even troubleshoot memory contention. Extended Events (XE) gives one more avenue to try and troubleshoot problems with memory.</p>
<p>Using XE to observe memory conditions is a method that is both geeky/fun and an advanced technique at the same time. If nothing else, it will certainly serve as a divergence from the mundane and give you an opportunity to dive down a rabbit hole while exploring some SQL Server internals.</p>
<h2>Diving Straight In</h2>
<p>I have a handful of events that I have picked for an event session to track when I might be running into some memory problems. Or I can run the session when I suspect there are memory problems to try and provide me with a &#8220;second opinion.&#8221; Here are the pre-picked events.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xo.name AS EventName, xo.capabilities_desc, xo.description
	FROM sys.dm_xe_objects xo
	WHERE xo.name IN ('large_cache_memory_pressure','buffer_manager_page_life_expectancy'
		,'buffer_node_page_life_expectancy'
		,'buffer_pool_eviction_thresholds_recalculated','server_memory_change');</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked.png"><img loading="lazy" class="aligncenter size-large wp-image-5066" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked-1024x130.png" alt="" width="560" height="71" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked-1024x130.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked-300x38.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked-768x97.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked-50x6.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Investigating those specific events a little further, I can determine if the payload is close to what I need.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,ca.map_value AS SearchKeyword
		,ch.Channel --added because large_cache_memory_pressure has no category/search keyword
	FROM sys.dm_xe_object_columns oc
		OUTER APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
							AND oc.object_package_guid = mv.object_package_guid
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = oc.object_name) ca
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = oc.object_name
			AND ch.PkgGuid = oc.object_package_guid
	WHERE oc.object_name IN ('large_cache_memory_pressure','buffer_manager_page_life_expectancy'
			,'buffer_node_page_life_expectancy','buffer_pool_eviction_thresholds_recalculated'
			,'server_memory_change')
		AND oc.column_type &lt;&gt; 'readonly' 
	ORDER BY EventName,oc.column_id;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload.png"><img loading="lazy" class="aligncenter size-large wp-image-5067" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload-1024x193.png" alt="" width="560" height="106" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload-1024x193.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload-300x56.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload-768x144.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/mempressure_prepicked_payload-50x9.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>That is a small snippet of the payload for all of the pre-picked events. Notice that the large_cache_memory_pressure event has no &#8220;SearchKeyword&#8221; / category defined for it. There are a few other events that also do not have a category assigned which makes it a little harder to figure out related events. That said, from the results, I know that I have some &#8220;server&#8221; and some &#8220;memory&#8221; tagged events, so I can at least look at those categories for related events.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Keyword search */
DECLARE @Keyword VARCHAR(64) = 'memory' --memory --server
/* note there are a few more interesting events
buffer_node_database_pages
buffer_manager_database_pages
buffer_manager_target_pages
memory category
query_memory_grant_usage
memory_manager_stolen_server_memory
allocation_failure
bad_memory_detected
*/
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,olm.file_version
		,xp.name AS PackageName
		,mv.map_value AS SearchKeyword
		,ch.Channel
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND oc.column_value = mv.map_key
			AND oc.object_package_guid = mv.object_package_guid
			AND oc.name = 'KEYWORD'
		INNER JOIN sys.dm_xe_packages xp
			ON oc.object_package_guid = xp.guid
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = oc.object_name
			AND ch.PkgGuid = oc.object_package_guid
	WHERE mv.map_value = @Keyword
	ORDER BY oc.object_name;</pre><p>This query will yield results similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents.png"><img loading="lazy" class="aligncenter size-large wp-image-5068" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents-1024x199.png" alt="" width="560" height="109" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents-1024x199.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents-300x58.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents-768x150.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/memory_relatedevents-50x10.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If you look closely at the script, I included a note about some additional interesting events that are related to both categories &#8220;server&#8221; and &#8220;memory.&#8221;</p>
<p>After all of the digging and researching, now it&#8217;s time to pull it together and create a session that may possibly help to identify various memory issues as they arise or to at least help confirm your sneaking suspicion that a memory issue is already present.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'BuffMemPressure' )
	DROP EVENT SESSION BuffMemPressure
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO


CREATE EVENT SESSION [BuffMemPressure] ON SERVER
ADD EVENT sqlos.large_cache_memory_pressure (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
		),
ADD EVENT sqlserver.buffer_manager_page_life_expectancy (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
		),
ADD EVENT sqlserver.buffer_node_page_life_expectancy (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
		),
ADD EVENT sqlserver.buffer_pool_eviction_thresholds_recalculated (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
		),
ADD EVENT sqlserver.server_memory_change (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
		)
ADD TARGET package0.event_file (  SET filename = N'C:\Database\XE\BuffMemPressure.xel'
									, max_rollover_files = ( 5 ) )
WITH (  MAX_MEMORY = 4096 KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 5 SECONDS
		, MAX_EVENT_SIZE = 0 KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = ON );
GO

ALTER EVENT SESSION BuffMemPressure ON SERVER
STATE = START;</pre><p>When running this session for a while, you will receive a flood of events as they continue to trigger and record data to your trace file. You will want to keep a steady eye on the trace files and possibly only run the session for short periods.</p>
<p>Here is an example of my session with events grouped by event name. Notice anything of interest between the groups?</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts.png"><img loading="lazy" class="aligncenter size-large wp-image-5071" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts-1024x378.png" alt="" width="560" height="207" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts-1024x378.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts-300x111.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts-768x283.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts-50x18.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/buffmem_xecounts.png 1030w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If the data in the session does not seem to be helpful enough, I recommend looking at adding the additional events I noted previously.</p>
<p>Here is another view on a system that has been monitoring these events for a while longer and does experience memory pressure.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results.png"><img loading="lazy" class="aligncenter size-large wp-image-5100" src="http://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results-1024x464.png" alt="" width="560" height="254" srcset="https://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results-1024x464.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results-300x136.png 300w, https://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results-768x348.png 768w, https://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results-50x23.png 50w, https://jasonbrimhall.info/wp-content/uploads/2019/01/more_buffermem_results.png 1467w" sizes="(max-width: 560px) 85vw, 560px" /></a>Here we can see some of the direct results of index operations on memory as well as the effects on memory for some really bad code. Really cool is that we can easily find what query(ies) may be causing the memory pressure issues and then directly tune the offending query(ies).</p>
<h2>The Wrap</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class=" wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="177" height="177" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 177px) 85vw, 177px" /></a>Diving in to the internals of SQL Server can be useful in troubleshooting memory issues. Extended Events provides a means to look at many memory related events that can be integral to solving or understanding some of your memory issues. Using Extended Events to dive into the memory related events is a powerful tool to add to the memory troubleshooting toolbelt.</p>
<p>Try it out on one or more of your servers and let me know how it goes.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the ninth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5063" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/">Checking your Memory with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Finding Application Session Settings</title>
		<link>https://jasonbrimhall.info/2019/01/01/finding-application-session-settings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=finding-application-session-settings</link>
					<comments>https://jasonbrimhall.info/2019/01/01/finding-application-session-settings/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 01 Jan 2019 14:06:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5051</guid>

					<description><![CDATA[<p>One of the underused troubleshooting and performance tuning techniques is to validate the application session settings. Things can work fabulous inside of SSMS, but run miserably inside the application.</p>
The post <a href="https://jasonbrimhall.info/2019/01/01/finding-application-session-settings/">Finding Application Session Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/day8_v2.png"><img loading="lazy" class="wp-image-4927 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day8_v2.png" alt="" width="140" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day8_v2.png 140w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day8_v2-34x50.png 34w" sizes="(max-width: 140px) 85vw, 140px" /></a>One of the underused troubleshooting and performance tuning techniques is to validate the application session settings. Things can work fabulous inside of SSMS, but run miserably inside the application. I have long been using Extended Events to help me identify these settings (and yes XE has saved the day more than once by identifying the application settings easily). This article will help show how to use XE to help save the day or at least identify what an application is doing when connecting to SQL Server.</p>
<p>This is only one method, there are other methods. My second option is usually to drop into the DMVs &#8211; but others exist beyond that. Tara Kizer jumps into some of those other methods <a href="https://www.brentozar.com/archive/2018/03/troubleshooting-parameter-sniffing-issues-right-way-part-2/">here</a>.</p>
<h2>Easy Stuff First</h2>
<p>Before diving into XE, first it makes sense to get some more data on what the possible connection settings include. We can query SQL Server for most of the applicable information. For the extended details we have to <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-user-options-server-configuration-option?view=sql-server-2017">look it up online</a>.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sv.name AS ConfigName, sv.number AS ConfigValue
	FROM master.dbo.spt_values sv
	WHERE sv.type = 'sop';</pre><p>Inside SQL Server, we have been given the information for what the values are and what the setting name happens to be. Querying the spt_values table for the group of values of type &#8220;sop&#8221; (<em>think <strong>s</strong>et <strong>op</strong>tions</em>) we get the results we need. That will yield results similar to this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results.png"><img loading="lazy" class="aligncenter size-large wp-image-5054" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results-1024x274.png" alt="" width="560" height="150" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results-1024x274.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results-300x80.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results-768x206.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/setoptions_results-50x13.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If I take that a little further, I can modify the query to figure out what configurations are enabled for my current session (in SSMS).</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @Options BIGINT = @@OPTIONS;

SELECT @Options AS OptionsValue

SELECT sv.name AS ConfigName, sv.number AS ConfigValue
		,CASE WHEN sv.number &amp; @Options &gt; 0
			THEN 1
			ELSE 0
			END AS EnabledForCurrentSession
	FROM master.dbo.spt_values sv
	WHERE sv.type = 'sop';</pre><p>For me, currently, this yields the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession.png"><img loading="lazy" class="aligncenter wp-image-5055" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession.png" alt="" width="512" height="562" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession.png 775w, https://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession-273x300.png 273w, https://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession-768x843.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/set_currentsession-46x50.png 46w" sizes="(max-width: 512px) 85vw, 512px" /></a>Everything marked with a &#8220;1&#8221; is enabled and the rest are disabled. Ok, easy enough. Now that we can figure out SSMS values and we have an idea of what they mean, it is time to trap the settings from the application. We will be doing that via XE.</p>
<h2>App Settings</h2>
<p>In order to find the application settings, we need to capture a specific data point called &#8220;collect_options_text&#8221;. To find which events have this type of data, we can query the XE infrastructure.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xo.name, xo.object_type, xo.description--, xoc.name AS ColumnName
		, xoc.column_type, xoc.capabilities_desc, xoc.description AS ColumnDescription
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.name = xoc.object_name
			AND xo.package_guid = xoc.object_package_guid
	WHERE xoc.name = 'collect_options_text';</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions.png"><img loading="lazy" class="aligncenter size-large wp-image-5056" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions-1024x83.png" alt="" width="560" height="45" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions-1024x83.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions-300x24.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions-768x62.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_collectsetoptions.png 2043w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Running the preceding query finds two events &#8211; login and existing_connection. Both indicate that the &#8220;collect_options_text&#8221; is a flag that is disabled by default. When enabled it will collect the options_text for each session (new or existing depending on your connections).</p>
<p>If I delve further into the &#8220;login&#8221; event, I can see some nice data points for troubleshooting and learn more about what the event does.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = 'login' --'existing_connection
	,@ReadFlag VARCHAR(64) = 'readonly' --readonly' --ALL if all columntypes are desired
 
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,ca.map_value AS SearchKeyword
	FROM sys.dm_xe_object_columns oc
		OUTER APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = oc.object_name) ca
	WHERE oc.object_name = @EventName
		AND oc.column_type &lt;&gt; @ReadFlag;</pre><p>Which yields this&#8230;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/login_event.png"><img loading="lazy" class="aligncenter size-large wp-image-5057" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/login_event-1024x267.png" alt="" width="560" height="146" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/login_event-1024x267.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/login_event-300x78.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/login_event-768x201.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/login_event-50x13.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/login_event.png 1827w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class="wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="144" height="144" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 144px) 85vw, 144px" /></a>Everything in the orange circles is useful in various troubleshooting scenarios. Just a little side tidbit to keep in your reserves. The blue box is highlighting the options and options_text data points. The options_text becomes enabled when we flip the &#8220;collect_options_text&#8221; flag to on.</p>
<p>Another interesting note is the &#8220;SearchKeyword&#8221;. This is a category of sorts (it is a category when looking at it in the GUI). This can tell me all of the events that also might be related to the login event. Looking deeper at that, I can see the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Keyword search */
DECLARE @Keyword VARCHAR(64) = 'session'
 
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,olm.file_version
		,xp.name AS PackageName
		,mv.map_value AS SearchKeyword
		,ch.Channel
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND oc.column_value = mv.map_key
			AND oc.object_package_guid = mv.object_package_guid
			AND oc.name = 'KEYWORD'
		INNER JOIN sys.dm_xe_packages xp
			ON oc.object_package_guid = xp.guid
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = oc.object_name
			AND ch.PkgGuid = oc.object_package_guid
	WHERE mv.map_value = @Keyword
	ORDER BY oc.object_name;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword.png"><img loading="lazy" class="aligncenter size-large wp-image-5058" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword-1024x337.png" alt="" width="560" height="184" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword-1024x337.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword-300x99.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword-768x252.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/session_keyword-50x16.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>That is another juicy tidbit to keep in your back pocket as an extra tool for future use! Seventeen events are in the &#8220;session&#8221; category and could be related, but we will not use them for this particular event session.</p>
<h2>The Juicy Center</h2>
<p>Having covered some of the path to getting to the events that matter and what data is available in the events, we are now ready to put a session together.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AppSessionOptions' )
	DROP EVENT SESSION AppSessionOptions 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION AppSessionOptions ON SERVER
ADD EVENT sqlserver.login ( SET collect_database_name = ( 1 ), collect_options_text = (1)
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name
	,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,
	sqlserver.database_id, sqlserver.database_name,
	sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id,
	sqlserver.context_info, sqlserver.client_connection_id ) 
	),
ADD EVENT sqlserver.existing_connection ( SET collect_database_name = ( 1 ), collect_options_text = (1)
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name
	,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,
	sqlserver.database_id, sqlserver.database_name,
	sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id,
	sqlserver.context_info, sqlserver.client_connection_id ) 
	)
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\AppSessionOptions.xel' 
									, max_file_size = ( 5120 )
									, max_rollover_files = ( 4 ) )
WITH (STARTUP_STATE = OFF
	,TRACK_CAUSALITY = ON);

/* start the session */
ALTER EVENT SESSION AppSessionOptions 
ON SERVER 
STATE = START;
GO</pre><p>After creating and starting the XE session, all that is needed is to wait for a login event to occur from the application. Once it does, then check the trace file and evaluate the data. As I look at the data from the application and look specifically at the options_text data, I will see something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings.png"><img loading="lazy" class="aligncenter size-large wp-image-5059" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings-1024x780.png" alt="" width="560" height="427" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings-1024x780.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings-300x229.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings-768x585.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_loginsettings.png 1461w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I circled an interesting difference that pops up between the XE session and the @@Options server variable. A login captured by XE will also show the language and date settings for the connection.</p>
<h2>The Wrap</h2>
<p>Creating a session to capture the settings being used by an application is particularly easy. Being able to trap the relevant data and troubleshoot performance issues is a tool necessary (and yes easy to do) to be able to quickly become a rock-star DBA. I showed how to search for the necessary events (quickly) as well as how to figure out relationships between events in a particular category.</p>
<p>Try it out on one or more of your servers and let me know how it goes.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the eighth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5051" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2019/01/01/finding-application-session-settings/">Finding Application Session Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2019/01/01/finding-application-session-settings/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Finding Installed Event Sessions</title>
		<link>https://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=finding-installed-event-sessions</link>
					<comments>https://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 31 Dec 2018 13:45:39 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4916</guid>

					<description><![CDATA[<p>Get off that arctic island and warm up with a little XE fun. This script is quite simple but will show you what you may have out there on your servers. Once you see what is there, hopefully your curiosity will get a little piqued and you will want to learn a little more (there is more of that here on this site too).</p>
The post <a href="https://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/">Finding Installed Event Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="alignright wp-image-4926 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day7_v2.png" alt="" width="154" height="232" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day7_v2.png 154w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day7_v2-33x50.png 33w" sizes="(max-width: 154px) 85vw, 154px" /></a>As a DBA, it is not uncommon to feel like you are marooned off on some tiny little island trying to figure things out for yourself. It may even be very common to feel the icy pain of the development cold shoulder (intentional or not) as you go about doing your duties to protect the data and secure high octane performance out of the database.</p>
<p>Not only may it be very commonplace to experience this due to the nature of the job, but it can also get to feel that way when a new product is released. Suddenly, that icy island is further north into the Arctic Ocean and you are struggling to gasp for a bit of air in the frigid cold.</p>
<p>I am certain this may be some of what you feel as you try to take a look at Extended Events. It is a fancy, new technology and there is not a ton of time to get up to speed while trying to warm yourself against the development chill. As you stew about the situation, you begin to ponder, &#8220;How am I even supposed to know what an XE is, let alone what XEs are running on my server?&#8221; Never mind the confusion on what an XE is and that it is actually running or deployed sessions on the server. Don&#8217;t worry about the terminology just yet. <strong>What can we do to figure out what might be out there</strong>?</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/polarcold.png"><img loading="lazy" class=" wp-image-4918 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/polarcold.png" alt="" width="244" height="218" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/polarcold.png 369w, https://jasonbrimhall.info/wp-content/uploads/2018/12/polarcold-300x268.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/polarcold-50x45.png 50w" sizes="(max-width: 244px) 85vw, 244px" /></a>Well, that is where the trusty Google has come to help you. Thanks to a better than adequate ability to search the Internet, you landed on this page that has a script to help you explore what might be running as far as Extended Events on your server. You may be surprised to learn that you have more Extended Events Sessions running than you fathomed. Yes, SQL Server comes with some default sessions. Yes, some of these default sessions are more public than others. And yes, some of these</p>
<p><span style="color: #f25e00;"><strong>Come on in out of the cold</strong></span>. Get off that arctic island and warm up with a little XE fun. This script is quite simple but will show you what you may have out there on your servers. Once you see what is there, hopefully your curiosity will get a little piqued and you will want to learn a little more (there is more of that here on this site too).</p>
<p>&nbsp;</p>
<p>sessions are &#8220;hidden&#8221; from you. That is, until now.</p>
<p>And now, for that script:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(128) = NULL --'sp_server_diagnostics session' --NULL for all
;

SELECT ISNULL(ses.name,xse.name) AS SessionName
		, CASE
			WHEN ISNULL(ses.name,'') = ''
			THEN 'Private'
			ELSE 'Public'
			END AS SessionVisibility
		, CASE
			WHEN ISNULL(xse.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS SessionRunning
		, CASE
			WHEN ISNULL(xse.name,'') = ''
				AND ISNULL(ses.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS IsDeployed
	FROM sys.server_event_sessions ses
	FULL OUTER JOIN sys.dm_xe_sessions xse
		ON xse.name =ses.name
	WHERE COALESCE(@SessionName, ses.name, xse.name) = ISNULL(ses.name, xse.name)
	ORDER BY ses.event_session_id;

GO</pre><p>Quick and simple, and full of that warming XE sensation. This script just shows you what is a private session versus public. What is a private session, you ask? Well, that happens to be all of those database audits you have deployed to your server. It also includes those little things like the &#8220;sp_server_diagnostics session&#8221; session (yes it sounds redundant but that is because session is also part of the name for that session).</p>
<p><a href="http://bit.ly/XE60Days"><img loading="lazy" class="alignright wp-image-4347" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="214" height="214" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 214px) 85vw, 214px" /></a></p>
<p>This script will also show you what is deployed to the server versus what is running on the server (not all sessions have to be running). And to top it all off, I set it up so you can query for a specific session or for all sessions.</p>
<p>Try it out on one or more of your servers and let me know how it goes.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the seventh article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4916" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/">Finding Installed Event Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQLs Black Box Recorder &#8211; sp_server_diagnostics</title>
		<link>https://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqls-black-box-recorder-sp_server_diagnostics</link>
					<comments>https://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sun, 30 Dec 2018 14:05:59 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4863</guid>

					<description><![CDATA[<p>The diagnostics process will trap various server related health (diagnostics) information related to the SQL Server instance in an effort to try and detect potential failures and errors.</p>
The post <a href="https://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/">SQLs Black Box Recorder – sp_server_diagnostics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="alignright wp-image-4925 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day6_v2.png" alt="" width="150" height="233" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day6_v2.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day6_v2-32x50.png 32w" sizes="(max-width: 150px) 85vw, 150px" /></a></p>
<p>Yesterday i shared the first article in a three part series about the SQL Black Box Recorder, that you can read <a href="http://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">here</a>, with a promise of at least two more posts. The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components of the black box recorder. The three components as laid out in that article are:</p>
<ul>
<li>Default Trace</li>
<li>system_health Extended Event Session</li>
<li>sp_server_diagnostics procedure</li>
</ul>
<p>The first article went into deeper detail about the first leg of this three-legged black box recorder &#8211; the default trace. In this article, the focus will be directed to the next leg of the black box recorder &#8211; or the system_health Extended Event Session. If by some measure you are in the dark about what Extended Events is, then I recommend you read my personal blog series on the subject. There are numerous articles stepping through the subject in easy-to-digest fashion. You can find many of the articles in the following table of contents &#8211; <a href="http://bit.ly/XE60Days">here</a>.</p>
<p>The focus of this article will take on the topic of the third piece of the black box recorder, sp_server_diagnostics. I will show how this procedure is critical in gathering pertinent information that is crucial to gathering an overall picture of the system—from a default black box recorder perspective.</p>
<h2>SQL Black Box Recorder</h2>
<h3>What is the sp_server_diagnostics process?</h3>
<p>Beyond being a component of the black box for SQL Server, what exactly is this diagnostics process? The sp_server_diagnostics is much as the name implies—it is a &#8220;diagnostics&#8221; service that attempts to gather information about various events that may affect the overall health of the SQL Server instance.</p>
<p>The diagnostics process will trap various server related health (diagnostics) information related to the SQL Server instance in an effort to try and detect potential failures and errors. This diagnostics session/process traps information for five different categories by default. There is a sixth category of information for those special servers that happen to be running an Availability Group.</p>
<h4>The Six</h4>
<ul style="list-style-type: circle;">
<li><strong>system</strong>: overall health of the server including information about spinlocks, severe processing conditions, non-yielding tasks, page faults, and CPU usage.</li>
<li><strong>resource</strong>: health of resources, specifically including physical and virtual memory, buffer pools, pages, cache and other memory objects</li>
<li><strong>query_processing</strong>: captures query processing data about worker threads, tasks, wait types, CPU intensive sessions, and blocking tasks.</li>
<li><strong>io_subsystem</strong>: health related data to IO.</li>
<li><strong>events</strong>: errors and events of interest recorded by the server, including details about ring buffer exceptions, ring buffer events about memory broker, out of memory, scheduler monitor, buffer pool, spinlocks, security, and connectivity.</li>
<li><strong>AvailabilityGroup</strong>: basic information about the AvailabilityGroup if there is an AvailabilityGroup enabled on the server.</li>
</ul>
<p>This is fantastic introductory information. As luck would have it, you can also read more about it from my <span style="text-decoration: underline;"><a href="http://bit.ly/1GMfikp">blog &#8211; here</a></span>.</p>
<h3>How to use this process?</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png"><img loading="lazy" class=" wp-image-4846 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png" alt="" width="206" height="157" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png 506w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox-300x228.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox-50x38.png 50w" sizes="(max-width: 206px) 85vw, 206px" /></a>What good is any level of information if we don&#8217;t quite know how to use or consume that data? Do we consume it via trace? Do we execute the stored procedure? Do we capture the information from some other means? The answer is yes! Wait, yes to what? Yes to all of it! Let&#8217;s explore how to consume this data.</p>
<h4>Option 1</h4>
<p>The first step to learning how to consume this data is to start at probably the most basic of levels. As you have already noted, this is a stored procedure. It was probably the sp_ in the name that gave it away, right? Since it comes in the form of a stored procedure, it makes it pretty easy to figure out the first means to get the data from it—just execute it. Actually, let me clarify that just a bit. sp_server_diagnostics is a CLR stored procedure. Nonetheless, all that needs be done is execute it at this level to get to the data.</p><pre class="urvanov-syntax-highlighter-plain-tag">EXECUTE sp_server_diagnostics;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components.png"><img loading="lazy" class="aligncenter size-large wp-image-4872" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-1024x161.png" alt="" width="560" height="88" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-1024x161.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-300x47.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-768x121.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_components-50x8.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Look at that! Pretty slick! I execute the stored procedure and I can see a point in time result of the &#8220;health check&#8221; from this component of the black box recorder. Notice here that I only have five of the six categories that I had mentioned. This is due to the lack of a configured availability group (AlwaysOn) from this particular instance. Another point of interest is that the data column is not in a very friendly format for DBA consumption. This is flat text that just goes on and on. It is painful to consume in this manner.</p>
<h4>Tidy that Code</h4>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #ServerDiagnosticsResult
	(
		create_time DATETIME
		, component_type sysname
		, component_name sysname
		, state INT
		, state_desc sysname
		, data XML
	);  
INSERT INTO #ServerDiagnosticsResult
		EXECUTE sp_server_diagnostics;  

SELECT *
	FROM #ServerDiagnosticsResult;

DROP TABLE #ServerDiagnosticsResult;</pre><p>Looking at the code, you can see quickly the difference. I have changed the data column to be XML-based to better match the data being output from the stored procedure. Let&#8217;s see that in action:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml.png"><img loading="lazy" class="aligncenter size-large wp-image-4874" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-1024x166.png" alt="" width="560" height="91" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-1024x166.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-300x49.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-768x124.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/spdiag_componentxml-50x8.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>That is much better. Now I can simply click one of the data results and see a nicely formatted easy to read XML output of that component. Here is an example from the query_processing component:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml.png"><img loading="lazy" class="aligncenter size-large wp-image-4877" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-1024x351.png" alt="" width="560" height="192" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-1024x351.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-300x103.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-768x263.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml-50x17.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/query_processingxml.png 1685w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<h4>Option 2</h4>
<p>Cool! I have just shown one means of exploring this facet of the black box recorder. Now, let&#8217;s take a look at other means to get at this particular data, beyond just executing the stored procedure. Did you know that this procedure is very closely related to Extended <a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class="wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="193" height="193" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 193px) 85vw, 193px" /></a>Events? (I am sure that you picked up on that nugget due to reading the <span style="text-decoration: underline;"><a href="http://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/" class="broken_link">previous article in the series</a></span> or possibly the other article I mentioned <span style="text-decoration: underline;"><a href="http://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">here</a></span>). With such a close relationship to Extended Events, it makes sense that sp_server_diagnostics also has a couple of events and is consumed by multiple sessions.</p>
<p>SQL Server comes with various default Extended Event sessions, of those sp_server_diagnostics is consumed by the system_health session as well as the hidden session for SQLDiag that is used by Windows Clustering and Availability Groups to determine server health. You already heard about the system_health (from the previous article), but few have heard about the hidden session. I will take a look at the events as well as the sessions that consume the sp_server_diagnostics data.</p>
<h4>Events</h4>
<p>First, I will share the details for each of the events related to the sp_server_diagnostics process.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag.png"><img loading="lazy" class="aligncenter size-large wp-image-4881" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-1024x82.png" alt="" width="560" height="45" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-1024x82.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-300x24.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-768x61.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag.png 1726w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>As I have shown here, you can see that these events are a part of the debug channel. In the next couple of images, I want to show some of the payload attached to these events.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra.png"><img loading="lazy" class="aligncenter size-large wp-image-4884" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-1024x159.png" alt="" width="560" height="87" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-1024x159.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-300x47.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-768x119.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_extra-50x8.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult.png"><img loading="lazy" class="aligncenter size-large wp-image-4887" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-1024x350.png" alt="" width="560" height="191" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-1024x350.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-300x103.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-768x263.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_serverdiag_ult-50x17.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>These events show what I have shown previously with regards to output of the stored procedure. There is a consistency in the output of the diagnostics process. What I have yet to show in this data is one more piece of information that could be helpful down the road and that pertains specifically to the extended events data. That piece of information I need to share is the keyword associated with each of these events. When looking for related events, I need you to understand that the sp_server_diagnostics events are a part of the <strong>scheduling</strong> classification. There, I have said it. I just gave you a big clue to help you in your troubleshooting endeavors and the use of the diagnostics processes/events.</p>
<h4>Which Sessions then?</h4>
<p>Now that I have shown which events are related to diagnostics, I can finally show which sessions are dependent upon the diagnostics data. To show that kind of information, I have this next query to help:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* session that is running */
SELECT xs.name AS SessionName
		, xse.event_name
	FROM sys.dm_xe_session_events xse
		INNER JOIN sys.dm_xe_sessions xs
			ON xse.event_session_address = xs.address
	WHERE xse.event_name IN ( 'sp_server_diagnostics_result_set',
								'sp_server_diagnostics_component_result' );

/* sessions on the server but may be stopped */
SELECT ses.name AS SessionName
		, sese.name AS event_name
	FROM sys.server_event_session_events sese
		INNER JOIN sys.server_event_sessions ses
			ON ses.event_session_id = sese.event_session_id
	WHERE sese.name IN ( 'sp_server_diagnostics_result_set',
							'sp_server_diagnostics_component_result' );</pre><p>When I execute the statements in the preceding query, I will receive a single result—system_health. That said, do not believe everything I just showed you with that query. SQL Server does a decent job at hiding some of the details. When I run the next query, I will see a little bit more information.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
	FROM sys.dm_xe_sessions;</pre><p>When I run the preceding query, I will see the following two sessions (given that I have not change the default settings):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png"><img loading="lazy" class="aligncenter size-full wp-image-4891" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png" alt="" width="916" height="99" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions.png 916w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-300x32.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-768x83.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox_sessions-50x5.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>Take note of the names of those two sessions. I showed that the system_health session is reliant upon the diagnostics events. Now, I am showing that there is another event session called &#8220;<strong>sp_server_diagnostics session</strong>&#8220;. Wait, there is more! SQL Server continues to hide stuff from us.</p>
<h4>Hidden Sessions</h4>
<p>When you have AlwaysOn configured, there is an additional hidden session that is not visible within the sessions lists inside of SQL Server. To view this hidden session, you must follow the directions shown in <a href="https://msdn.microsoft.com/en-us/library/dn135337%28v=sql.110%29.aspx?f=255&amp;MSPPError=-2147217396">this article on msdn</a>. Once you have navigated to the folder containing the hidden XEL files, you can open them in Management Studio and view the data. It is while viewing the data that you will be able to see the relationship between sp_server_diagnostics and this newly discovered trace file.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png"><img loading="lazy" class="aligncenter size-full wp-image-4894" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png" alt="" width="765" height="338" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth.png 765w, https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth-300x133.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/clusterhealth-50x22.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>The payload from this image demonstrates the relationship between sp_server_diagnostics and the hidden trace file. I challenge you to take some time to explore this hidden trace file on one of your servers where AlwaysOn is configured. I know you will be thankful for the investment at some point down the road.</p>
<h3>Conclusion</h3>
<p>I have just shown a ton of info about the third component of the black box recorder—sp_server_diagnostics. This procedure may be lesser known than the first two components, but it is highly integral into the overall monitoring and health of your SQL Server instance. In this article, I have not only shown how to use sp_server_diagnostics (albeit quickly), but I have also shown that the diagnostics are heavily relied upon by other components of the black box recorder. In addition, I have shown how this component is integrated into other hidden traces that are essential in the monitoring and troubleshooting of your instance.</p>
<p>The black box recorder is real. You need to invest time in getting to know the black box recorder components and how they can be of help to you in becoming a superhero DBA.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the sixth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4863" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/">SQLs Black Box Recorder – sp_server_diagnostics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Servers Black Box Recorder &#8211; system_health</title>
		<link>https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-servers-black-box-recorder-system_health</link>
					<comments>https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 29 Dec 2018 13:26:38 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4854</guid>

					<description><![CDATA[<p>In this article, the focus will be directed to the next leg of the black box recorder - or the system_health Extended Event Session.</p>
The post <a href="https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/">SQL Servers Black Box Recorder – system_health</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="alignright wp-image-4924 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day5_v2.png" alt="" width="148" height="229" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day5_v2.png 148w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day5_v2-32x50.png 32w" sizes="(max-width: 148px) 85vw, 148px" /></a></p>
<p>Yesterday i shared the first article in a three part series about the SQL Black Box Recorder, that you can read <a href="http://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">here</a>, with a promise of at least two more posts. The first article in the series laid the groundwork about the black box recorder in SQL Server. Furthermore, there was a brief introduction into the three components of the black box recorder. The three components as laid out in that article are:</p>
<ul>
<li>Default Trace</li>
<li>system_health Extended Event Session</li>
<li>sp_server_diagnostics procedure</li>
</ul>
<p>The first article went into deeper detail about the first leg of this three-legged black box recorder &#8211; the default trace. In this article, the focus will be directed to the next leg of the black box recorder &#8211; or the system_health Extended Event Session. If by some measure you are in the dark about what Extended Events is, then I recommend you read my personal blog series on the subject. There are numerous articles stepping through the subject in easy-to-digest fashion. You can find many of the articles in the following table of contents &#8211; <a href="http://bit.ly/XE60Days">here</a>.</p>
<p>The focus of this article will not be to introduce the topic of Extended Events. Rather, it will be to introduce the system_health session and dive into it a fair bit.</p>
<h2>SQL Black Box Recorder</h2>
<h3>What is the system_health session?</h3>
<p>Beyond being a component of the black box for SQL Server, what exactly is this event session? The system_health is much as the name implies &#8211; it is a &#8220;trace&#8221; that attempts to gather information about various events that may affect the overall health of the SQL Server instance.</p>
<p>The event session will trap various events related to deadlocks, waits, clr, memory, schedulers, and reported errors. To get a better grasp of this, let&#8217;s take a look at the event session makeup based on the available metadata in the dmvs and catalog views.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(256) = 'system_health';

/* note: this only works if the session is running and the source is &quot;server&quot; not internal or something else.
*/

SELECT xs.name AS SessionName
		, xs.session_source
		, xse.event_name
		, xo.description AS EventDesc
		, xsea.action_name
		, xoa.description AS ActionDesc
		, xse.event_predicate
		, sese.predicate, sese.predicate_xml
	FROM sys.dm_xe_sessions xs
		INNER JOIN sys.dm_xe_session_events xse
			ON xs.address = xse.event_session_address
		LEFT OUTER JOIN sys.dm_xe_session_event_actions xsea
			ON xse.event_session_address = xsea.event_session_address
				AND xse.event_name = xsea.event_name
		INNER JOIN sys.dm_xe_objects xo
			ON xse.event_name = xo.name
				AND xse.event_package_guid = xo.package_guid
				AND xo.object_type = 'event'
		LEFT OUTER JOIN sys.dm_xe_objects xoa
			ON xsea.action_name = xoa.name
				AND xsea.action_package_guid = xoa.package_guid
				AND xoa.object_type = 'action'
		INNER JOIN sys.server_event_sessions ses
			ON xs.name = ses.name
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON ses.event_session_id = sese.event_session_id
			AND xse.event_name = sese.name
	WHERE xs.name = @SessionName
	ORDER BY xs.name,xse.event_name, xsea.action_name;</pre><p>In addition to the types of events I mentioned, there are also a few more interesting things to discover from the results of this particular query. For instance, the actions that are being employed help to gather even more information such as the callstack, tsql_callstack, database id, and sql text of the query that was executing at the moment of the event that is trapped.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png"><img loading="lazy" class=" wp-image-4846 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png" alt="" width="212" height="161" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox.png 506w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox-300x228.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/blackbox-50x38.png 50w" sizes="(max-width: 212px) 85vw, 212px" /></a>One very peculiar event that is trapped is the sp_server_diagnostics_component_result event. Remember from earlier in this article that I noted the third leg of the black box record happens to be a very similarly named session &#8211; &#8220;sp_server_diagnostics procedure&#8221;. When I cover this third leg, it will make a little more sense. Understand, for now, that your suspicion of it being a bit more integral to the black box (than merely 1/3 of the overall black box) is confirmed.</p>
<p>This is a good set of information that can be trapped. Furthermore, this is a <strong>good set of information</strong> which can give a fairly good diagnosis of several different potential problems within your SQL Server Instance! (Yes it may seem repetitive, but I wanted to underscore the importance of the data that can be trapped.) That said, compare the types of events to those of the default trace. Take note of how many events actually overlap between the two components of the black box recorder.</p>
<p>For ease of comparison, let&#8217;s simplify that previous query to get a set of events to read without the duplication due to the actions on each event.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(256) = 'system_health';

SELECT xs.name AS SessionName, xse.event_name
	FROM sys.dm_xe_sessions xs
		INNER JOIN sys.dm_xe_session_events xse
			ON xs.address = xse.event_session_address
	WHERE xs.name = @SessionName
	ORDER BY xse.event_name;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events.png"><img loading="lazy" class="aligncenter size-large wp-image-4858" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events-1024x717.png" alt="" width="560" height="392" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events-300x210.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events-768x538.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/system_health_events-50x35.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And since I am feeling particularly generous, I have lumped the events from the two traces together in the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(256) = 'system_health';

SELECT xs.name AS SessionName
		, xse.event_name AS EventName
		, mv.map_value AS CategoryName
	FROM sys.dm_xe_sessions xs
		INNER JOIN sys.dm_xe_session_events xse
			ON xs.address = xse.event_session_address
		INNER JOIN sys.dm_xe_objects xo
			ON xse.event_package_guid = xo.package_guid
			AND xse.event_name = xo.name
			AND xo.object_type = 'event'
		INNER JOIN sys.dm_xe_object_columns oc
			ON oc.object_name = xo.name
			AND oc.object_package_guid = xo.package_guid
			AND oc.name = 'KEYWORD'
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND oc.column_value = mv.map_key
			AND oc.object_package_guid = mv.object_package_guid
	WHERE xs.name = @SessionName
UNION ALL
/* events */
SELECT 'Default Trace' AS SessionName
		, te.name AS EventName
		, tca.name AS CategoryName
	FROM sys.traces t
		CROSS APPLY ( SELECT DISTINCT gei.eventid
							FROM sys.fn_trace_geteventinfo(t.id) gei
					) ca
		INNER JOIN sys.trace_events te
			ON te.trace_event_id = ca.eventid
		INNER JOIN sys.trace_categories tca
			ON te.category_id = tca.category_id
	WHERE t.is_default = 1
	ORDER BY EventName;</pre><p>That should help to compare the 17 events from the system_health session and the 34 from the default trace with a little more ease and speed. The events from the two sessions are rather complimentary to each as they help to construct the SQL Server Black Box recorder.</p>
<h3>How to use this session?</h3>
<p>With the events trapped by this session, there are a few ways to use the trapped data that should stand out pretty easily. To me, the quick application of the data from this session can come from the review of deadlocks, reported errors, or even waits analysis. Using the deadlock as probably the most common problem people will want to troubleshoot, this information is suddenly much more valuable and easy to access (no more need for that trace flag). Since the system_health is now trapping the deadlock by default, one could quickly access the deadlock graph from the event data and proceed to troubleshooting. More information on getting that deadlock graph can be found <a href="http://www.sqlsolutionsgroup.com/wean-off-sql-profiler-part-1/">here </a>and <a href="http://blog.waynesheffield.com/wayne/code-library/deadlocks/shred-deadlock-graph/">here</a>.</p>
<p>Learn to use the data made available through this member of the black box recorder. Becoming familiar with this tool (and additionally with Extended Events) will make you a rock-star in the office. The information needed to troubleshoot most problems is right at your fingertips through the use of the different pieces of the black box recorder. If it is not available there, then more than likely it can be made available through a bit of tinkering with Extended Events. Get to know the tools and be that rock-star DBA.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the fifth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4854" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/">SQL Servers Black Box Recorder – system_health</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Servers Black Box Recorder &#8211; Def Trace</title>
		<link>https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-servers-black-box-recorder-def-trace</link>
					<comments>https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 28 Dec 2018 13:54:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4845</guid>

					<description><![CDATA[<p>Very much like what you may find with the airline industry, the black box recorder in SQL Server is not just a single method (device) implemented to capture all of the desired data points.</p>
The post <a href="https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">SQL Servers Black Box Recorder – Def Trace</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="wp-image-4923 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day4_v2.png" alt="" width="133" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day4_v2.png 133w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day4_v2-26x50.png 26w" sizes="(max-width: 133px) 85vw, 133px" /></a></p>
<p>Across many professions and industries there is often a need to have some sort of device that &#8220;audits&#8221; everything that happens with a device or process. We are probably all quite familiar with the infamous black box recorders used by the passenger airline and train industries. It is also quite possibly fairly common knowledge that many pace makers perform the same sort of functionality &#8211; on a smaller scale. Various metrics and data points are registered and recorded somewhere. Whether to a local storage device or whether the device phones home to some other remote location, it is recorded.</p>
<p>We often pontificate about the what-ifs for a black box recorder within SQL Server, right? We wish and dream and go about creating our own little recorder to suit the requirements we deem necessary for successful monitoring of the server for the just-in-case scenario. Well, the truth of the matter is that we really don&#8217;t need to go to such great lengths to create a &#8220;black box recorder&#8221; because Microsoft has already done all of that for us.</p>
<p>Wait, what? Yes, that&#8217;s right! Truth be told this shouldn&#8217;t be much news for most Senior Level data professionals working with SQL Server for the past few years. But if you are new to the product, this might be good news for you. Then again, it might just be bad news depending on your take.</p>
<p>Very much like what you may find with the airline industry, the black box recorder in SQL Server is not just a single method (device) implemented to capture all of the desired data points. On a passenger jet, you may find that there are three or more such devices that contribute to the capture and recording of the in-flight data. In SQL Server, there are three major processes that help capture our in-flight data. Over the next few articles I will discuss each of these processes. These processes include:</p>
<ul>
<li>Default Trace</li>
<li>system_health Extended Event Session</li>
<li>sp_server_diagnostics procedure</li>
</ul>
<p>This multi-tiered approach does provide a sort of fail-safe system. If one should be disabled, there still remain up to two more processes that may be running. That said, each of these can be disabled but it does take a bit of an overt effort. And since it does require somebody to put out effort to try and disable each of the black box components, you could potentially capture the culprit via audits from the other components or via an explicit audit that you create for these types of purposes.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/footprints.png" class="broken_link"><img loading="lazy" class=" wp-image-4851 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/footprints-296x1024.png" alt="" width="141" height="488" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/footprints-296x1024.png 296w, https://jasonbrimhall.info/wp-content/uploads/2018/12/footprints-87x300.png 87w, https://jasonbrimhall.info/wp-content/uploads/2018/12/footprints.png 465w" sizes="(max-width: 141px) 85vw, 141px" /></a>Since this will be something to discuss over a few articles, I will break out each process into an individual article. For today, I will discuss the default trace.</p>
<h2>Default Trace</h2>
<p>The <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/default-trace-enabled-server-configuration-option?view=sql-server-2017">default trace</a> by itself is something that can be turned off via configuration option. There may be good reason to disable the default trace. Before disabling the default trace, please consider the following that can be captured via the default trace. I will use a query to demonstrate the events and categories that are configured for capture in the default trace.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* events */
SELECT te.name AS EventName
		,tca.name AS CategoryName
		, CASE tca.type WHEN '0' THEN 'Normal'
				WHEN '1' THEN 'Connection'
				WHEN '2' THEN 'ERROR' END AS CategoryType
		, t.path AS TracePath
		, oa.logical_operator,oa.comparison_operator, oa.value AS FilteredValue
	FROM sys.traces t
		CROSS APPLY (SELECT DISTINCT gei.eventid FROM sys.fn_trace_geteventinfo(t.id) gei) ca
		INNER JOIN sys.trace_events te
			ON te.trace_event_id = ca.eventid
		INNER JOIN sys.trace_categories tca
			ON te.category_id = tca.category_id
		OUTER APPLY (SELECT gfi.columnid,gfi.logical_operator,gfi.comparison_operator,gfi.value FROM sys.fn_trace_getfilterinfo(t.id) gfi) oa
	WHERE t.is_default = 1</pre><p>In this query, I have requested a few more data points than necessary to illustrate the point. That is to help illustrate an additional point that the default trace isn&#8217;t filtering out any data for these events. If the event fires (in this trace), it is recorded. Let&#8217;s divert right back to the events and categories for now. The results of that query will produce the following sample list of events for me on SQL Server 2014:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events.png"><img loading="lazy" class="aligncenter wp-image-4849 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events-968x1024.png" alt="" width="560" height="592" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events.png 968w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events-284x300.png 284w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events-768x812.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_events-47x50.png 47w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>That is quite a range of events covered by this particular recording device. From changes to objects down to security related events and even errors and warnings. If somebody drops an object, the default trace can catch it. If one of the various DBCC statements is executed, it will be trapped in this trace.</p>
<p>There is one thing that is captured by this trace that is not overly obvious. In fact, it is rather annoying in how it is recorded in my opinion. Server configuration settings such as &#8220;cost threshold of parallelism&#8221; or the lesser utilized &#8220;user options&#8221; are not registered as an &#8220;Object:Alter&#8221; event but rather as an ErrorLog event. I wouldn&#8217;t call this type of &#8220;change&#8221; an error and don&#8217;t necessarily like seeing these registered with other legitimate errors. That said, it would be nice to see these logged differently (they are currently logged the same way with Extended Events). So, if somebody is dorking around with server configurations, it becomes a bit more convoluted to figure it out, but we can get there. Let&#8217;s see how that works:</p><pre class="urvanov-syntax-highlighter-plain-tag">-- server configs Audited via Def Trace
SELECT 	T.StartTime
		, T.SPID
		, T.LoginName
		, T.HostName
		, T.ApplicationName
		, T.DatabaseName
		--, ObjectName,sv.number AS ObjTypeVal, sv.name [ObjectType]
		--, T.TextData
		, ConfigOption = SUBSTRING(T.TextData,CHARINDEX('''',T.TextData)+1,CHARINDEX(' changed from ',T.TextData)-CHARINDEX('''',T.TextData)-2)
		, PrevValue = SUBSTRING(T.TextData,CHARINDEX('from ',T.TextData)+5,CHARINDEX('to ',T.TextData)-CHARINDEX('from ',T.TextData)-5)
		, NewValue = SUBSTRING(T.TextData,CHARINDEX('to ',T.TextData)+3,CHARINDEX('. Run',T.TextData)-CHARINDEX('to ',T.TextData)-3)
		, EventName = te.name
		, T.EventClass
	FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
			( SELECT REVERSE(SUBSTRING(REVERSE(path),
					CHARINDEX('\',REVERSE(path)),256)) + 'log.trc'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) AS T  
		INNER JOIN sys.trace_events AS te
			ON T.EventClass = te.trace_event_id
	WHERE T.EventClass = 22
		AND T.TextData LIKE '%config%'
	ORDER BY T.StartTime DESC;</pre><p>Looking at my system, I get the following sample results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs.png"><img loading="lazy" class="aligncenter wp-image-4850 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs-1024x200.png" alt="" width="560" height="109" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs-300x59.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs-768x150.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/deftrace_servconfigs-50x10.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>You can see there are plenty of settings that I have been playing with captured by the default trace. If you happen to have a junior DBA or maybe a cowboy DBA that loves to shoot from the hip and make changes, this will help you find all the necessary details to bring to that DBA for discussion.</p>
<p>The default trace comprises one third of the black box recorder. I have shown a quick use for the default trace and have also shown some of the various events that are captured from this trace. I recommend getting to know your default trace just a little bit better. You never know when you may need to resort to the flight recorder data held in the default trace. Being familiar with the default trace before you need to use it will help improve your comfort level when under the stress of trying to figure out what happened just before the server went belly up!</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the fourth article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4845" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/">SQL Servers Black Box Recorder – Def Trace</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/28/sql-servers-black-box-recorder-def-trace/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>How to: File Target use in Extended Events</title>
		<link>https://jasonbrimhall.info/2018/12/27/how-to-file-target-use-in-extended-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-file-target-use-in-extended-events</link>
					<comments>https://jasonbrimhall.info/2018/12/27/how-to-file-target-use-in-extended-events/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 27 Dec 2018 13:38:03 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4841</guid>

					<description><![CDATA[<p>Using a file target is not difficult from a creation point of view (event session creation). But, some basics are critical or you could end up with fewer follicles.</p>
The post <a href="https://jasonbrimhall.info/2018/12/27/how-to-file-target-use-in-extended-events/">How to: File Target use in Extended Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="alignright wp-image-4922 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day3_v2.png" alt="" width="162" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day3_v2.png 162w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day3_v2-31x50.png 31w" sizes="(max-width: 162px) 85vw, 162px" /></a></p>
<p>I have been doing a lot of posts of late about extended events but have failed to share some of the essential building blocks. I am not looking to do a series of definitions, but just share a couple of quick tips and examples here and there that will make the use of extended events a little easier to undertake.</p>
<p>The first one to tackle is the use of the file target. Using a file target is not difficult from a creation point of view (event session creation). <em><strong>But</strong></em>, some basics are critical or you could end up with fewer follicles.</p>
<p>Let&#8217;s take a quick peek at some of these tips.</p>
<h3>File System Prep</h3>
<p>This first little tip comes from a painful experience. It is common sense to only try and create files in a directory that exists, but sometimes that directory has to be different on different systems. Then comes a little copy and paste of the last code used that worked. You think you are golden but forgot that one little tweak for the directory to be used. Oops.</p>
<p>Take this example session. When you run this code, you will not see an error (don&#8217;t change anything).</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Create the Event Session
IF EXISTS(SELECT * 
          FROM sys.server_event_sessions 
          WHERE name='FileTargetDemo')
    DROP EVENT SESSION FileTargetDemo 
    ON SERVER;
GO
CREATE EVENT SESSION FileTargetDemo
ON SERVER
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* Pick an event for this demo */
--ADD EVENT sqlserver.buffer_node_page_life_expectancy()
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ADD EVENT sqlserver.buffer_node_page_life_expectancy()
/* Note two targets exist here */
ADD TARGET package0.ring_buffer,
ADD TARGET  package0.asynchronous_file_target(
     SET filename='C:\Database\XEs\FileTargetDemo.xel',max_file_size = 5,max_rollover_files = 4)
WITH (MAX_DISPATCH_LATENCY = 5SECONDS)
GO</pre><p>However, if you try to start the session, you will receive a pretty little error. Here is the code to try and start the session, along with it&#8217;s associated error.</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Start the Event Session
ALTER EVENT SESSION FileTargetDemo 
ON SERVER 
STATE = START;
GO</pre><p></p>
<blockquote><p><span style="color: #ff0000;">Msg 25602, Level 17, State 22, Line 25</span><br />
<span style="color: #ff0000;">The target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.event_file&#8221;, encountered a configuration error during initialization. Object cannot be added to the event session. The operating system returned error 3: &#8216;The system cannot find the path specified.</span><br />
<span style="color: #ff0000;">&#8216; while creating the file &#8216;C:\Database\XEs\FileTargetDemo_0_130670484928250000.xel&#8217;.</span></p></blockquote>
<p>If you double check in the SSMS GUI, you will see that the session is there. It is just stopped. You can also check that the session exists if you recall my query from a previous <a href="http://bit.ly/2arQWit">post</a> where I show the status of the session.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(64) = 'FileTargetDemo';
 
SELECT sn.SessionName
	, CASE WHEN ISNULL(es.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		END AS XESessionExists
	, CASE WHEN ISNULL(xe.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		END AS XESessionRunning
	FROM (SELECT @SessionName AS SessionName) sn
		LEFT OUTER JOIN sys.server_event_sessions es
			ON sn.SessionName = es.name
		LEFT OUTER JOIN sys.dm_xe_sessions xe
			ON es.name = xe.name
	;</pre><p>If you take it a step further and try to read the log file that should be created, you will be greeted once more with a reminder that there is a problem. Try this (sans change again).</p><pre class="urvanov-syntax-highlighter-plain-tag">/* read the session data */
SELECT CAST(event_data AS xml) AS TargetData
            FROM sys.fn_xe_file_target_read_file('C:\Database\XEs\FileTargetDemo*.xel',NULL,NULL, NULL)</pre><p>And you will receive the following message:</p>
<blockquote><p><span style="color: #ff0000;">Msg 25718, Level 16, State 3, Line 31</span><br />
<span style="color: #ff0000;">The log file name &#8220;C:\Database\XEs\FileTargetDemo*.xel&#8221; is invalid. Verify that the file exists and that the SQL Server service account has access to it.</span></p></blockquote>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class="wp-image-4545 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="256" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 256px) 85vw, 256px" /></a></p>
<p>The beauty here is that all is not lost. These are easy problems to get around and resolve. All it takes is to adjust the file path to be the correct path or a path that exists (to which you have permissions).</p>
<h3>Read the Log File</h3>
<p>If you have been reading this article, then this might seem like a bit of redundancy. That is by design. DBAs love redundancy—well at least when it means there is a means to recovery due to the redundancy.</p>
<p>Unlike reading from the ring_buffer, when you read from the file target, you will use different code. The file target is stored in a binary representation on disk that a function will produce as XML format for human readability. So to read a file target, you would need to do something like the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* read the session data */
SELECT CAST(event_data AS xml) AS TargetData
            FROM sys.fn_xe_file_target_read_file('C:\Database\XEs\FileTargetDemo*.xel',NULL,NULL, NULL)</pre><p>And you definitely do not want to try the following with a file target. That is unless of course you are looking to go bald at an earlier than expected age in this profession.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* do not do this */
 SELECT CAST(target_data AS xml) AS TargetData
            FROM sys.dm_xe_sessions AS s
            INNER JOIN sys.dm_xe_session_targets AS t
                ON s.address = t.event_session_address
            WHERE s.name = 'FileTargetDemo'
              AND t.target_name = 'event_file';</pre><p>If you find yourself doing this version, all you will get for results is a short xml string similar to the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;EventFileTarget truncated="0"&gt;
  &lt;Buffers logged="1" dropped="0" /&gt;
  &lt;File name="C:\Database\XE\FileTargetDemo_0_130670493477970000.xel" /&gt;
&lt;/EventFileTarget&gt;</pre><p>This is not what you would be looking for when trying to read the event session data. That said, it at least provides some information that could be of use. You will see that buffers are tracked and the file name is tracked. For this last demo, I corrected the FileTargetDemo session to use a directory on the file system that existed and to which I had the appropriate level of permissions.</p>
<p>I just covered two quick tips to help make life a little bit easier when dealing with file targets and extended event sessions. I will try to continue little tips like this over the coming months. I hope you have found this useful and that you will indeed be able to put it to use.</p>
<p>&nbsp;</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in an article demonstrating the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the third article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://bit.ly/2DVEgOO">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4841" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/27/how-to-file-target-use-in-extended-events/">How to: File Target use in Extended Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/27/how-to-file-target-use-in-extended-events/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Upgrading From SQL Server Profiler</title>
		<link>https://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=upgrading-from-sql-server-profiler</link>
					<comments>https://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 26 Dec 2018 14:12:42 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4830</guid>

					<description><![CDATA[<p>How to correlate all of your favorite trace/profiler options into the shiny new XE equivalents.</p>
<p>As luck would have it, there is a means to correlate trace/profiler events to Extended Event events (yeah that sounds weird).  With the release of SQL Server 2012, Microsoft introduced a couple of catalog views to help with this correlation effort.</p>
The post <a href="https://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/">Upgrading From SQL Server Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="alignright wp-image-4921 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day2_v2.png" alt="" width="144" height="237" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day2_v2.png 144w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day2_v2-30x50.png 30w" sizes="(max-width: 144px) 85vw, 144px" /></a></p>
<p>I just shared an article describing how to use <a href="http://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/">Extended Events to perform your SQL Server Profiler duties</a>. If not, you can read all about it <a href="http://bit.ly/XEProfilerSSG">here</a>.</p>
<p>In that article, I showed one common use-case for SQL Server Profiler and how to achieve the same result via Extended Events. What I didn&#8217;t show in that article was how to correlate all of your favorite trace/profiler options into the shiny new XE equivalents. Is there even a way to do that?</p>
<p>As luck would have it, there is a means to correlate trace/profiler events to Extended Event events (yeah that sounds weird).  With the release of SQL Server 2012, Microsoft introduced a couple of catalog views to help with this correlation effort. Those views have a pretty straightforward naming convention. For example, one of the views is named sys.trace_xe_event_map while the other is sys.trace_xe_action_map. For this article, I will be focusing on the former.</p>
<h3>Making the Upgrade</h3>
<p>When looking to finally make the upgrade away from trace/profiler, a big key is to figure out if your favorite trace events are even an option at the next level. I have talked about <a href="http://bit.ly/SSGTrifecta">finding events in XE</a> in previous articles by trying to search for a specific topic that might apply to your current condition.</p>
<p>But if you are already familiar with specific trace events, you may just want/need to know what the new name is in XE. This is where those catalog views come into play. And in support of that, here is a query that can help in that upgrade effort:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT te.trace_event_id,tc.name AS CategoryName
	, CASE tc.type
		WHEN 0 THEN 'Normal'
		WHEN 1 THEN 'Connection'
		WHEN 2 THEN 'ERROR'
		END AS TraceEventType
	,te.name AS TraceEventName
	, xem.package_name, xem.xe_event_name
FROM sys.trace_xe_event_map xem
	RIGHT OUTER JOIN sys.trace_events te
		ON te.trace_event_id = xem.trace_event_id
	INNER JOIN sys.trace_categories tc
		ON te.category_id = tc.category_id
ORDER BY tc.category_id,te.trace_event_id ASC;</pre><p>Looking through the results, one would notice that not every trace event maps to an Extended Event event. The events that don&#8217;t map, in general, deal with audits (which is actually driven by Extended Events).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="230" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 230px) 85vw, 230px" /></a>This is a really good start to getting you on your way to that much needed upgrade away from profiler/trace. What if there are several traces that are already in use or scripted for various reasons in the environment?</p>
<h3>Decision Time</h3>
<p>If you happen to have traces that are already deployed in the environment or in script form, it can be a bit of a tedious pain to convert those to Extended Events. Do you manually recreate the traces as XE sessions? Do you abandon the upgrade due to the effort and annoyance it will create? Or do you find some automated means of performing the conversion?</p>
<p>Of those three options, only two are valid options. Those options involve performing the conversion of the traces to XE sessions. There are pros and cons for each. You may opt to take your time and learn more about Extended Events by performing the manual upgrade, or you may choose to save time by using an automated routine.</p>
<p>Should you decide to try the automated routine, there is one already out and available to help you on your way. Jonathan Kehayias wrote the script and you can download it <a href="https://www.sqlskills.com/blogs/jonathan/converting-sql-trace-to-extended-events-in-sql-server-2012/">here</a>.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in another article demonstrating the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This has been the second article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For a full listing of the articles, <a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4830" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/">Upgrading From SQL Server Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/26/upgrading-from-sql-server-profiler/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How To: XEvents as Profiler</title>
		<link>https://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-xevents-as-profiler</link>
					<comments>https://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 25 Dec 2018 14:03:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4825</guid>

					<description><![CDATA[<p>Despite the controls in place there always seems to be some change that is unknown or even some cowboy that makes changes as s/he sees fit and forgets to notify people or follow process.</p>
The post <a href="https://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/">How To: XEvents as Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/"><img loading="lazy" class="wp-image-4920 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/day1_v2.png" alt="" width="114" height="242" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/day1_v2.png 114w, https://jasonbrimhall.info/wp-content/uploads/2018/12/day1_v2-24x50.png 24w" sizes="(max-width: 114px) 85vw, 114px" /></a></p>
<p>A common excuse for not delving into extended events seems to be the jump from Profiler to extended events.  There appears to be an inherent fear with how to use extended events.  In addition to that fear, is the fear that extended events does not do what Profiler can do so easily.</p>
<p>Today, I would like to share a short tutorial on how to use extended events as if it were a profiling session.  I am only going to show one of the many possible means to profile via extended events.  Just understand that this means you have flexibility and a way to do more with this simple example than what I am going to share.</p>
<h3>Requirement</h3>
<p>You need to capture TSQL queries that are occurring against your instance in order to try and determine the code that is being passed to SQL Server from the application.</p>
<h3>How-To</h3>
<p>Rather than jump to Profiler, you are going to need to jump to a fresh, clean query window in SSMS.  Just like in Profiler, you will want to capture certain &#8220;statement&#8221; oriented events.  For this session, I want to start with sp_statement_starting and sql_statement_starting.  I am not going to use the _completed forms of those events because I want to capture as much as I can &#8211; without capturing too much noise.  Sometimes, there may be a _starting without a coordinated _completed and that could throw a wrench in the works.</p>
<p>With the basic information in hand, we are ready to implement some of the things learned in previous XEvents posts (<a href="http://bit.ly/XE60Days">here</a> and <a href="http://bit.ly/2Fti0zB">here</a>).  Let&#8217;s go ahead and start setting up the session that will capture the information we seek.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS(SELECT * 
          FROM sys.server_event_sessions 
          WHERE name='TraceIncomingQueries')
    DROP EVENT SESSION TraceIncomingQueries 
    ON SERVER;
GO
CREATE EVENT SESSION TraceIncomingQueries
ON SERVER
ADD EVENT sqlserver.sp_statement_starting (
	SET collect_object_name=(1)
	ACTION(sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.client_hostname,sqlserver.client_app_name)
WHERE sqlserver.client_app_name &amp;lt;&amp;gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
	),
ADD EVENT sqlserver.sql_statement_starting(
    ACTION(sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.client_hostname,sqlserver.client_app_name)
WHERE sqlserver.database_name='AdventureWorks2014'
	AND sqlserver.client_app_name &amp;lt;&amp;gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
	)
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\TraceIncomingQueries.xel')

/* start the session */
ALTER EVENT SESSION TraceIncomingQueries 
ON SERVER 
STATE = START;
GO</pre><p>One caveat to consider is in the sp_statement_starting event, I have specified a specific set option be used.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET collect_object_name=(1)</pre><p>This particular option is disabled by default.  If you want to know the object_name of code that is being used (triggers, stored procedures, etc), then this option must be enabled.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="261" height="261" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 261px) 85vw, 261px" /></a>I have specified the same actions to be used for each of the events I am trapping, but this is purely up to you.  If you do not wish to capture these actions, then you can remove them or add different actions as necessary.  I have also specified a different predicate for each of the events.  This is something that works so much better in XEvents than Profiler &#8211; the filtering that can be applied is much more flexible.</p>
<p>Once the session is started, then it is merely a matter of figuring out how to look at the data.  I generally use TSQL to parse the data from the file, but you could also fiddle with the GUI as well.  You can access that by right-clicking the event session in management studio and then selecting &#8220;Watch Live Data&#8221;.  If everything is configured properly, then you will start to see data after the first event is triggered.  From within the GUI, you can pick and choose which columns to display in your view.  You can pause the display of the session data, or you can even &#8220;erase&#8221; the data from the current view (just like in Profiler).  You can even filter, aggregate or group the data in the view from the GUI.</p>
<p>The use of the GUI is up to you.  I still prefer to use the script route.  With that route, here is a sample of what you may need to write in order to display the data from the session data file that has been captured.</p><pre class="urvanov-syntax-highlighter-plain-tag">use master;
GO

SELECT
event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP],
	event_data.value('(event/action[@name=&quot;database_name&quot;]/value)[1]', 'varchar(max)') AS DBName
	,event_data.value('(event/data[@name=&quot;statement&quot;]/value)[1]', 'varchar(max)') AS SQLText
	,event_data.value('(event/data[@name=&quot;object_name&quot;]/value)[1]', 'varchar(max)') AS ObjName
	,event_data.value('(event/action[@name=&quot;session_id&quot;]/value)[1]', 'varchar(max)') AS SessionID
	,event_data.value('(event/action[@name=&quot;nt_username&quot;]/value)[1]', 'varchar(max)') AS ExecUser
	,event_data.value('(event/action[@name=&quot;client_hostname&quot;]/value)[1]', 'varchar(max)') AS Client_HostName,
	event_data.value('(event/action[@name=&quot;client_app_name&quot;]/value)[1]', 'varchar(max)') AS Client_AppName
FROM(
SELECT CONVERT(XML, t2.event_data) AS event_data
 FROM (
  SELECT target_data = convert(XML, target_data)
   FROM sys.dm_xe_session_targets t
    INNER JOIN sys.dm_xe_sessions s 
        ON t.event_session_address = s.address
   WHERE t.target_name = 'event_file'
    AND s.name = 'TraceIncomingQueries') cte1
   CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent(FileTarget)
   CROSS APPLY  sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name', 'varchar(1000)'), NULL, NULL, NULL) t2)
    AS evts(event_data);</pre><p>It really is that simple.  Now you have a means to run a Profiler-like trace on your server without the impact of Profiler.  XEvents provides the means to run a more evolved Profiler session on your data to capture things like queries from an application.  XEvents does all of this without the severe penalty of Profiler and with many additional bonuses.  Try it out and enjoy!</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in another article demonstrating the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This is the first article in the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. For the full list of articles, please <a href="http://jasonbrimhall.info/2017/12/26/12-days-of-christmas-and-sql/">visit this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4825" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/">How To: XEvents as Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/25/how-to-xevents-as-profiler/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Quick and Easy XE for Azure DB</title>
		<link>https://jasonbrimhall.info/2018/12/24/quick-and-easy-xe-for-azure-db/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quick-and-easy-xe-for-azure-db</link>
					<comments>https://jasonbrimhall.info/2018/12/24/quick-and-easy-xe-for-azure-db/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 24 Dec 2018 14:33:50 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=5031</guid>

					<description><![CDATA[<p>This is a very simple introduction into the creation of an Extended Event session using a template for Azure SQL DB. I demonstrate the use of the GUI to configure the session quickly and then to subsequently script that configuration before creating the session.</p>
The post <a href="https://jasonbrimhall.info/2018/12/24/quick-and-easy-xe-for-azure-db/">Quick and Easy XE for Azure DB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/red_db_multi_cloud_xe.png"><img loading="lazy" class="wp-image-5032 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/red_db_multi_cloud_xe.png" alt="" width="329" height="174" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/red_db_multi_cloud_xe.png 391w, https://jasonbrimhall.info/wp-content/uploads/2018/12/red_db_multi_cloud_xe-300x159.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/red_db_multi_cloud_xe-50x26.png 50w" sizes="(max-width: 329px) 85vw, 329px" /></a></p>
<h3>The Cloud</h3>
<p>It has been a minute since I gave much love or attention to <a href="http://jasonbrimhall.info/2015/10/28/azure-sql-database/">Extended Events in Azure SQL DB</a>. Things have changed a touch since then. We will see about some of those changes in a future article. As for this time, let&#8217;s focus on how to get a session in Azure SQL DB up and running really quick and easy.</p>
<h3>Create a Session</h3>
<p>I am going to keep this as easy as possible for creating a session and thus I will demonstrate how to do it from the GUI. And for those more in tune with their scripting side, there is a future article on that as well as a glimpse of a script near the end of this article.</p>
<p>Recall from the previous article that things in Azure SQL DB are different for Extended Events. XE is database scoped rather than server scoped (as is the case with your on-premises servers). Due to this change, finding the GUI for XE is a little different.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/azuredb_xe_tree.png"><img loading="lazy" class="aligncenter wp-image-5035" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/azuredb_xe_tree.png" alt="" width="357" height="226" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/azuredb_xe_tree.png 434w, https://jasonbrimhall.info/wp-content/uploads/2018/12/azuredb_xe_tree-300x190.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/azuredb_xe_tree-50x32.png 50w" sizes="(max-width: 357px) 85vw, 357px" /></a>In order to find the GUI for XE, you must drill down into the database and then you will see &#8220;Extended Events.&#8221; (Side note, there is no <a href="http://bit.ly/2BkPBGC">XE Profiler</a> for Azure SQL DB as of this writing.) If you right-click Sessions, you will get a menu with the option to create a New Session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_menu.png"><img loading="lazy" class="aligncenter wp-image-5036" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_menu.png" alt="" width="359" height="275" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_menu.png 446w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_menu-300x230.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_menu-50x38.png 50w" sizes="(max-width: 359px) 85vw, 359px" /></a>After clicking &#8220;New Session&#8230;&#8221; the familiar window for a new session will appear.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general.png"><img loading="lazy" class="aligncenter size-large wp-image-5037" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general-1024x585.png" alt="" width="560" height="320" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general-1024x585.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general-300x171.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general-768x438.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general-50x29.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_newsession_general.png 1396w" sizes="(max-width: 560px) 85vw, 560px" /></a>Here, you see a session that I started creating already. For this session, I opted to go with the template called &#8220;Query Detail Tracking&#8221; (more on templates for Azure SQL DB in a future article). I also like to enable &#8220;Causality tracking&#8221; so that checkbox is ticked in this example. The template has the events I wish to capture already and I am only going to use the ring buffer (file target has some additional requirements for an Azure SQL DB session and should be treated in an entirely separate article) so I will skip those screens straight to the advanced screen before completing this session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript.png"><img loading="lazy" class="aligncenter size-large wp-image-5038" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript-1024x726.png" alt="" width="560" height="397" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript-1024x726.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript-300x213.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript-768x545.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/xe_sessionscript.png 1122w" sizes="(max-width: 560px) 85vw, 560px" /></a>From the advanced screen, all I want to do for now is to decrease the dispatch latency from the default 30 seconds down to 10 seconds. For this session, I just want to capture the events quickly in the target and be able to review them as soon as possible. I won&#8217;t be able to utilize the &#8220;Watch Live data&#8221; option for this session (as shown below), so a quick dispatch is essential.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/no_watchlivedata.png"><img loading="lazy" class="aligncenter wp-image-5039" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/no_watchlivedata.png" alt="" width="349" height="162" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/no_watchlivedata.png 474w, https://jasonbrimhall.info/wp-content/uploads/2018/12/no_watchlivedata-300x139.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/no_watchlivedata-50x23.png 50w" sizes="(max-width: 349px) 85vw, 349px" /></a>After I have selected all of the configurations I desire for this session, then I click the script button at the top of the window. From there, I will select &#8220;New Query Editor Window.&#8221; Once scripted, I will receive the following script for this particular session.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [AzureDB_Demo]
ON DATABASE
	ADD EVENT sqlserver.error_reported
	(ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
  , ADD EVENT sqlserver.module_end
	(SET collect_statement = (1)
	 ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
  , ADD EVENT sqlserver.rpc_completed
	(ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
  , ADD EVENT sqlserver.sp_statement_completed
	(SET collect_object_name = (1)
	 ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.query_plan_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
  , ADD EVENT sqlserver.sql_batch_completed
	(ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
  , ADD EVENT sqlserver.sql_statement_completed
	(ACTION
	 (
		 sqlserver.client_app_name
	   , sqlserver.database_id
	   , sqlserver.query_hash
	   , sqlserver.query_plan_hash
	   , sqlserver.session_id
	 )
	 WHERE (
			   ([package0].[greater_than_uint64]([sqlserver].[database_id], (4)))
			   AND ([package0].[equal_boolean]([sqlserver].[is_system], (0)))
		   )
	)
	ADD TARGET package0.ring_buffer
WITH
(
	MAX_MEMORY = 4096KB
  , EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
  , MAX_DISPATCH_LATENCY = 10 SECONDS
  , MAX_EVENT_SIZE = 0KB
  , MEMORY_PARTITION_MODE = NONE
  , TRACK_CAUSALITY = ON
  , STARTUP_STATE = OFF
)
GO</pre><p>Notice that there is nothing about starting this session in the script to start the session.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION [AzureDB_Demo] ON DATABASE
STATE = START;</pre><p>Note that &#8220;on database&#8221; has been specified instead of the traditional &#8220;on server&#8221; for the session state command. In order to stop the session, it is just as easy as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION [AzureDB_Demo] ON DATABASE
STATE = STOP;</pre><p></p>
<h3>Conclusion</h3>
<p>This has been a very simple introduction into the creation of an Extended Event session using a template for Azure SQL DB. I demonstrated the use of the GUI to configure the session quickly and then to subsequently script that configuration before creating the session.</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Interested in seeing the <strong>power</strong> of XE over Profiler? <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">Check this one out</a>!</p>
<p>This is a quick pre-cursor to the <strong>2018 &#8220;12 Days of Christmas&#8221;</strong> series. The series will begin on December 25th (the first day of Christmas) and you can easily follow it via<a href="http://bit.ly/2DVEgOO"> this page</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=5031" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/24/quick-and-easy-xe-for-azure-db/">Quick and Easy XE for Azure DB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/24/quick-and-easy-xe-for-azure-db/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>File Maintenance &#8211; Cleaning Up Old Files</title>
		<link>https://jasonbrimhall.info/2018/12/21/file-maintenance-cleaning-up-old-files/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=file-maintenance-cleaning-up-old-files</link>
					<comments>https://jasonbrimhall.info/2018/12/21/file-maintenance-cleaning-up-old-files/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 21 Dec 2018 13:28:28 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1483</guid>

					<description><![CDATA[<p>We have all run into a need or a desire to clean up old stale files from the file system, whether it be to remove old backup files or flat files that are created from one process or another.  And based on this need/desire, we have all come up with a method to help with achieve that goal.</p>
The post <a href="https://jasonbrimhall.info/2018/12/21/file-maintenance-cleaning-up-old-files/">File Maintenance – Cleaning Up Old Files</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Using SSIS to Maintain the File System</h3>
<p>We have all run into a need or a desire to clean up old stale files from the file system, whether it be to remove old backup files or flat files that are created from one process or <a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench.png"><img loading="lazy" class=" wp-image-2803 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench.png" alt="" width="274" height="171" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench.png 324w, https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench-300x187.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench-50x31.png 50w" sizes="(max-width: 274px) 85vw, 274px" /></a>another.  And based on this need/desire, we have all come up with a method to help with achieve that goal.</p>
<p>Some of the methods might be to include a flag in a maintenance plan that may be used.  Other methods may be to use a SQL script employing xp_cmdshell and delete statements.  Yet another may utilize the sp_oa stored procs and DMO.  And still others may have ventured into powershell to accomplish the same task.  The point is, there are many methods.</p>
<p>I am adding yet another method to the mix.  Why?  I didn&#8217;t much like the option of using the sp_oa method or the xp_cmdshell route.  I am very novice with powershell and it would take a lot more tinkering to get the script working properly.  Also, I felt pretty comfortable with SSIS and had approval to try and get this done using that method.  And just because I am a novice with powershell, does not mean that I will not circle back around to try and accomplish this task via that means.</p>
<p><strong>Note</strong>: <em>This article was originally written in 2011 and got stuck in an unpublished state. Things have changed since then so i will definitely be circling back around for a powershell version.</em></p>
<h3><strong>Requirements</strong></h3>
<p>The method employed needs to be able to do the following:</p>
<ol>
<li>Remove multiple file types</li>
<li>Be configurable</li>
<li>Clean out files from numerous directories</li>
<li>Remove files older than a specified number of days.</li>
</ol>
<h3>Setup</h3>
<p>The solution I chose utilizes SSIS.  It also requires that there be a table in a database that helps to drive the package.</p>
<p>The table looks like the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [AdminDB_Test]
GO

/****** Object:  Table [dbo].[FilePaths]    Script Date: 12/05/2011 23:36:26 ******/
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FilePaths]') AND type in (N'U'))
DROP TABLE [dbo].[FilePaths]
GO

USE [AdminDB_Test]
GO

/****** Object:  Table [dbo].[FilePaths]    Script Date: 12/05/2011 23:36:26 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[FilePaths](
	[PathID] [int] IDENTITY(1,1) NOT NULL,
	[Process] [varchar](32) NULL,
	[FilePath] [varchar](256) NULL,
 CONSTRAINT [PK_FilePaths] PRIMARY KEY CLUSTERED
(
	[PathID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO</pre><p>The filepath column holds the FileSystem Path for each directory that needs to be cleaned.  Paths that are supported are local (e.g. C:\temp ) and unc paths (\\machine\c$\temp).  I set this attribute to a length of 256, but if you have a longer path, you will want to adjust the length.</p>
<p>The Process column will hold a value describing what that path relates to, such as MaintainDirectory.  In my example, I am using MaintainDirectory to control which directories hold files that potentially need to be deleted.</p>
<p>Here is an example of the contents of that table I am using currently.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/FilePaths_Table.png"><img loading="lazy" class="alignnone size-full wp-image-1484" title="FilePaths_Table" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/FilePaths_Table.png" alt="" width="569" height="82" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/FilePaths_Table.png 569w, https://jasonbrimhall.info/wp-content/uploads/2011/12/FilePaths_Table-300x43.png 300w" sizes="(max-width: 569px) 85vw, 569px" /></a></p>
<p>The last piece of the setup before we start working on the SSIS package is the need for a string splitting function.  Pick the string splitter of your liking.  I have one that I <a href="http://www.sqlservercentral.com/articles/Tally+Table/72993/">like</a> and am sure you have one that you prefer.  The SSIS package relies on the return field from the splitter being named &#8220;Item.&#8221;  If it is named something else, please make the adjustments in the package as necessary.</p>
<h3>The Package</h3>
<p>The package I created has been created in SSIS 2008.  To meet the requirements already set forth, I utilized the following objects: ADO.Net Data Source, 2 Execute SQL Tasks, 2 ForEach Loop Containers, a Script Task, and 8 variables.  Let&#8217;s take a look at these starting with the variables.</p>
<p><strong>Variables</strong></p>
<ul>
<li><strong>SQLServerName</strong> &#8211; The value held here is used in an Expression for the Data Source.  This will overwrite the ServerName value in the Data Source.</li>
<li><strong>DatabaseName</strong> &#8211; Used alongside the SQLServerName variable in an Expression for the Data Source.  This value will overwrite the InitialCatalog value in the Data Source.  This should be the name of the database where the FilePaths table and String Split function exist.</li>
<li><strong>DaysToKeep</strong> &#8211; This value is the cutoff point for which files to keep and which files will be deleted.  This variable is used as a ReadOnly variable in the Script Task.</li>
<li><strong>obj_FileExtension</strong> &#8211; This object variable is used to store the result set from one of the Execute SQL tasks and the results of the string split function from the FileExtensionList variable.</li>
<li><strong>FileExtensionList</strong> &#8211; This is a delimited list of file extensions that need to be evaluated for deletion.  It is important to note that the file extensions that are to be processed are case sensitive.  The extension must appear in this list as it appears in the file system.</li>
<li><strong>FileExtension</strong> &#8211; to be used in one of the ForEach loops.  This variable will receive the FileExtension from the obj_FileExtension variable one at a time.</li>
<li><strong>obj_ListOfDirectories</strong> &#8211; This variable will receive the result set of an Execute SQL Task to be later consumed by one of the ForEach loops.</li>
<li><strong>DirectoryToMaintain</strong> &#8211; receives one at a time the Directory to process for file deletion.  The ForEach loop stores a value from obj_ListOfDirectories in this variable for processing.</li>
</ul>
<p><strong>Execute SQL Tasks</strong></p>
<p>The two Execute SQL Tasks are simple in function.  One is to get the list of directories to maintain from the FilePaths table.  The other is strictly to split the string for the FileExtensionList variable.</p>
<p>The first is named &#8220;Get Directory List&#8221; and should receive the Full Result Set from the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">select fp.PathID,fp.Process,fp.FilePath
	from dbo.FilePaths FP
	where fp.Process = 'MaintainDirectory'
	order by fp.PathID</pre><p>The Result Set tab of this task also needs to be modified.  it should look like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/ListDirectories.png"><img loading="lazy" class="alignnone size-full wp-image-1485" title="ListDirectories" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/ListDirectories.png" alt="" width="574" height="77" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/ListDirectories.png 574w, https://jasonbrimhall.info/wp-content/uploads/2011/12/ListDirectories-300x40.png 300w" sizes="(max-width: 574px) 85vw, 574px" /></a></p>
<p>From this task, we flow to the next Execute SQL Task named &#8220;Split FileList.&#8221;  The setup of this task is very much like the previous task.  We want to receive the full result set.  We have a configuration to make on the result set tab.  We also need to map a parameter.  Let&#8217;s take a look at those real quick.</p>
<p>Parameter Mapping</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/split_param.png"><img loading="lazy" class="alignnone size-full wp-image-1486" title="split_param" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/split_param.png" alt="" width="658" height="73" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/split_param.png 658w, https://jasonbrimhall.info/wp-content/uploads/2011/12/split_param-300x33.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Result Set</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/split_result.png"><img loading="lazy" class="alignnone size-full wp-image-1487" title="split_result" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/split_result.png" alt="" width="554" height="70" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/split_result.png 554w, https://jasonbrimhall.info/wp-content/uploads/2011/12/split_result-300x37.png 300w" sizes="(max-width: 554px) 85vw, 554px" /></a></p>
<p>And this is the query that we will be executing.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select Item
	From stringsplitter(@FileExtensionList,',')</pre><p>Notice that the Parameter we named in the Parameter Mapping tab is being used in the function call.  I chose this method because I could see and understand how it works better.</p>
<p><strong>ForEach Loops</strong></p>
<p>The next stop in the flow is the ForEach Loop &#8211; Directory object.  As the name implies, this ForEach Loop is designed to work with the obj_ListOfDirectories variable/array.</p>
<p>With this first Loop container, we have two tabs that need to be configured in the properties.  Both Loop containers are similar in that they need the same tabs to be configured.  First, let&#8217;s talk about the Collection tab.</p>
<p>On the Collection tab, we need to set the Enumerator option to &#8220;ForEach ADO Enumerator.&#8221;  Then we need to select the obj_ListOfDirectories from the drop down labeled &#8220;ADO Source Object Variable.&#8221;  Your screen should look like the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_collection.png"><img loading="lazy" class="alignnone size-full wp-image-1491" title="Directory_collection" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_collection.png" alt="" width="513" height="257" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_collection.png 513w, https://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_collection-300x150.png 300w" sizes="(max-width: 513px) 85vw, 513px" /></a></p>
<p>With this tab configured, we can focus our attention to the quick changes that need to be made on the Variable Mappings tab.  On this tab, we are telling the enumerator how to handle the data from the object variable.  We are mapping columns from the result set to variables for further consumption.  When configured, it should look like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_variablemap.png"><img loading="lazy" class="alignnone size-full wp-image-1492" title="Directory_variablemap" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_variablemap.png" alt="" width="514" height="79" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_variablemap.png 514w, https://jasonbrimhall.info/wp-content/uploads/2011/12/Directory_variablemap-300x46.png 300w" sizes="(max-width: 514px) 85vw, 514px" /></a></p>
<p>Inside of this ForEach loop container, we have another ForEach loop container.  This second ForEach loop container handles the file extensions that we listed out in delimited fashion in the FileExtensionList variable.  I have called this container &#8220;ForEach Loop &#8211; FileExtension&#8221; (just keeping it simple).</p>
<p>The collection tab follows the same configuration setup.  The difference of course being that this container will use the obj_FileExtension object from the source variable dropdown menu.</p>
<p>The variable mapping tab is also slightly different.  We will be mapping column 0 of the object to the FileExtension variable.  The explanation for the different number between the two loop container variable mappings is simple.  In obj_ListOfDirectories, we have multiple columns being returned.  In obj_FileExtension, we have but one single column being returned.</p>
<p>This inner Loop container will loop through each of the extensions for each of the directories that have been returned to the outer loop container.  the inner loop container has the remainder of the workload in it via the Script Task.</p>
<p><strong>Script Task</strong></p>
<p>It is via the script task that we actually get to start deleting files.  This was the most difficult piece of the entire package &#8211; though the script is not very large.</p>
<p>For the script task, I chose to implement it via the Visual Basic option (instead of C#).  I have three ReadOnlyVariables employed by the script.  Those variables are: User::DaysToKeep,User::DirectoryToMaintain, and User::FileExtension.</p>
<p>Once you have set those on the script tab, the next step is to click the Edit Script&#8230; button where we need to place the following script.</p><pre class="urvanov-syntax-highlighter-plain-tag">' Microsoft SQL Server Integration Services Script Task
' Write scripts using Microsoft Visual Basic 2008.
' The ScriptMain is the entry point class of the script.

Imports System
Imports System.IO
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime

&lt;System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")&gt; _
&lt;System.CLSCompliantAttribute(False)&gt; _
Partial Public Class ScriptMain
	Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

	Enum ScriptResults
		Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
		Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
	End Enum

    Public Sub Main()
        Dim SourcePath As String
        Dim PurgeDays As Integer
        Dim FileExtension As String
        Dim thisFileInUse As Boolean = False

        PurgeDays = CInt(Dts.Variables("User::DaysToKeep").Value)
        SourcePath = CStr(Dts.Variables("User::DirectoryToMaintain").Value)
        FileExtension = CStr(Dts.Variables("User::FileExtension").Value)

        For Each file As FileInfo In New DirectoryInfo(SourcePath).GetFiles()
            If ((Now - file.LastWriteTime).Days &gt; PurgeDays) And (file.Extension = FileExtension) Then
                Try
                    file.Delete()

                Catch ex As Exception

                End Try
            End If

        Next

        Dts.TaskResult = ScriptResults.Success
    End Sub

End Class</pre><p>An important note of interest is the need for the Try&#8230;Catch.  Without this block as it is, you could run into an issue where the file (such as those pesky temp files) may be in use by some process and cause the package to error.  The Try&#8230;catch will move past that nasty error and delete the files that it can.</p>
<p>Inside this script, you will see that I am comparing the LastWriteTime to the PurgeDays and ensuring that the file extension matches one that is in the list.  Then we move into the try&#8230;catch and either delete the file that matches those criteria or throw an exception and move on to the next file.</p>
<p>When all is said and done, your package should look something like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/TheFlow.png"><img loading="lazy" class="alignnone size-full wp-image-1493" title="TheFlow" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/TheFlow.png" alt="" width="593" height="404" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/TheFlow.png 593w, https://jasonbrimhall.info/wp-content/uploads/2011/12/TheFlow-300x204.png 300w" sizes="(max-width: 593px) 85vw, 593px" /></a></p>
<p>You should also have a variable list that looks like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/TheVariables.png"><img loading="lazy" class="alignnone size-full wp-image-1494" title="TheVariables" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/TheVariables.png" alt="" width="498" height="209" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/TheVariables.png 498w, https://jasonbrimhall.info/wp-content/uploads/2011/12/TheVariables-300x125.png 300w" sizes="(max-width: 498px) 85vw, 498px" /></a></p>
<p>Each variable that is not an Object has a value assigned to it at this point.  These values will be overwritten where applicable.</p>
<h3>Next Steps</h3>
<p>Having this package is a good start.  But unless you are prepared to manually run this on a daily basis, it needs to be added to a job and scheduled.  There are two ways to go about scheduling this package.</p>
<p>The first option is to configure the FileExtensionList and DaysToKeep variables and save the package with those values.  Then run this package through SQL Agent with those values every time.  The drawback to this method is that if you need to add or remove a file extension (as an example) then you need to edit the package and re-save it.</p>
<p>The alternative option is pass the values through the job to overwrite those variables as the job runs.  Should you need to remove or add a file extension, it would just be done at the job definition level.</p>
<p>Let&#8217;s take a look at this second option.  I will skip past how to create the job as an SSIS job in SQL Server and we will look directly how to modify those variables from the job properties.</p>
<p>To configure these variables directly from the SQL Agent job, open the Job properties and click on the Set Values tab (assuming you have defined this job as an SSIS Job type).  You should get a screen similar to this (void of the set values shown in the pic).  Just add the parameters (variables) we have discussed to this point with appropriate values to fit your needs/environment.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/Set_Values.png"><img loading="lazy" class="alignnone size-full wp-image-1531" title="Set_Values" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/Set_Values.png" alt="" width="541" height="379" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/Set_Values.png 902w, https://jasonbrimhall.info/wp-content/uploads/2011/12/Set_Values-300x210.png 300w" sizes="(max-width: 541px) 85vw, 541px" /></a></p>
<p>I have chosen to only include the four variables shown above since the remaining variables are either objects or get overwritten in the ForEach loops during processing.  The only thing remaining now is to set the schedule for the job.  Once set, the job (and package) will take care of the rest.</p>
<h3>Conclusion</h3>
<p>I have now shown you how to maintain some of the directories on your system through the use of SSIS and SQL server.  There are many methods to accomplish this goal, it is up to each of us to choose the best method for our environment and comfort level (by means of supporting the chosen solution).</p>
<p>If you would like to read more interesting stuff concerning SSIS, you might want to check any of these articles: <a href="http://bit.ly/2A1zOMK">lost password</a>, <a href="http://jasonbrimhall.info/2014/07/17/ssis-value-does-not-fall-within-the-expected-range/" class="broken_link">expected range errors</a>, and <a href="http://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/">synonyms extending SSIS</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1483" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/21/file-maintenance-cleaning-up-old-files/">File Maintenance – Cleaning Up Old Files</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/21/file-maintenance-cleaning-up-old-files/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday Participation Over the Years</title>
		<link>https://jasonbrimhall.info/2018/12/19/t-sql-tuesday-participation-over-the-years/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-participation-over-the-years</link>
					<comments>https://jasonbrimhall.info/2018/12/19/t-sql-tuesday-participation-over-the-years/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 19 Dec 2018 18:00:11 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4949</guid>

					<description><![CDATA[<p>I have personally participated in quite a large number of these TSQL Tuesday events - despite not being every single one. This is a roundup of my personal participation across the years.</p>
The post <a href="https://jasonbrimhall.info/2018/12/19/t-sql-tuesday-participation-over-the-years/">T-SQL Tuesday Participation Over the Years</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Loads of TSQL Tuesdays</h2>
<p><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></p>
<p>Years ago the TSQL Tuesday party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" rel="noopener" class="broken_link">b</a>|<a href="http://twitter.com/adammachanic" target="_blank" rel="noopener">t</a>). The premise of the monthly event is to get people a topic each month to try and ease some of the difficulty with writing (figuring out what to write) and to get more involved in the community. The party started in December 2009 and is now embarking on the 10th year. The party is running strong and will likely continue for many years to come.</p>
<p>I have personally participated in quite a large number of these events. I am far from a perfect participation record like Rob Farley (<a href="https://t.co/unSOs3PYiI">b</a> | <a href="https://twitter.com/rob_farley">t</a>) but I do participate when I can. Every now and again I think about what I might have participated in or what I have written in the past for a TSQL Tuesday. This post will serve as a table of contents for all of those articles. This is to help make it easier to find for me (as well as give me a chance to review and fix problems from really old posts). This post will provide a quick synopsis of my article (if one exists) along with topic and links to original invite and roundups for the monthly party.</p>
<h3>T-SQL Tuesday #001: Date/Time Tricks (Dec. 2009)</h3>
<p><a href="http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx" class="broken_link">Invite</a> and <a href="http://sqlblog.com/blogs/adam_machanic/archive/2009/12/09/t-sql-tuesday-001-the-roundup.aspx" class="broken_link">roundup</a></p>
<p><strong>My Article</strong>: N/A</p>
<h3>T-SQL Tuesday #002: A Puzzling Situation (January 2010)</h3>
<p><a href="http://sqlblog.com/blogs/adam_machanic/archive/2010/01/04/invitation-for-t-sql-tuesday-002-a-puzzling-situation.aspx" class="broken_link">Invite </a>and <a href="http://sqlblog.com/blogs/adam_machanic/archive/2010/02/08/t-sql-tuesday-002-the-roundup.aspx" class="broken_link">roundup</a></p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/01/13/tsql-tuesday-but-i-was-late/">TSQL Tuesday &#8211; But I was late</a></p>
<p>This was the first time I participated in TSQL Tuesday. I was very new to the blogging concept &#8211; and it shows. The puzzling problem I encountered in the article was a fun little job that kept giving different results than running the same code from SSMS. Check it out!</p>
<h3>T-SQL Tuesday #003: RELATIONSHIPS (February 2010)</h3>
<p><a href="http://blogs.msmvps.com/robfarley/2010/02/01/invitation-for-t-sql-tuesday-003-relationships/" class="broken_link">Invitation</a> and <a href="http://blogs.msmvps.com/robfarley/2010/02/12/t-sql-tuesday-003-relationships-the-round-up/" class="broken_link">summary</a></p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/02/08/relationships/">Relationships</a></p>
<p>I covered all sorts of different relationships that affect SQL Server from work, to marital, to table relationships in a database. It all ties together in requiring an individual to constantly tune the different types of relationships.</p>
<h3>T-SQL Tuesday #004: IO (March 2010)</h3>
<p><a href="https://straightpathsql.com/archives/2010/03/invitation-for-t-sql-tuesday-004-io/">Invitation</a> and <a href="https://straightpathsql.com/archives/2010/03/t-sql-tuesday-004-a-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/03/08/io-io-io/">IO IO IO</a></p>
<p>What if we could create a numbers table without IO?  What if we could perform several different kinds of queries without IO?  Itzik Ben Gan proposed a cascading CTE solution that does this sort of thing. This article shows that method in use to help improve certain IO conditions.</p>
<h3>T-SQL Tuesday #005: Reporting (April 2010)</h3>
<p><a href="http://sqlvariant.com/2010/04/t-sql-tuesday-005-reporting/">Invitation </a>and <a href="http://sqlvariant.com/2010/04/t-sql-tuesday-005-reporting-the-round-up/">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/04/06/ip-and-default-trace-t-sql-tuesday-005/">IP and Default Trace…T-SQL Tuesday #005</a></p>
<p>Having been introduced to a requirement to report on IP addresses of connections, I dive into a solution that will help show hostname, ip address and a few more tidbits.</p>
<p>When it is necessary to provide reports on activity occurring on the server, it pays to do a little prep work.  Be Prepared.  It is not an easy task to be able to go back in time and report on data that isn’t captured.  The little prep work that one may need to do is well worth the effort in the end.</p>
<p><strong>My 2nd Article</strong>: <a title="BLOB Report T-SQL Tuesday #005- Reporting" href="http://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/" rel="bookmark">BLOB Report T-SQL Tuesday #005- Reporting</a></p>
<p>Learning how to decrypt the individual object sizes broken down into type and filegroup. Then report on the data that was retrieved from the DMOs.</p>
<h3>T-SQL Tuesday #006: “What About BLOB?” (May 2010)</h3>
<p><a href="http://sqlblog.com/blogs/michael_coles/archive/2010/05/03/t-sql-tuesday-006-what-about-blob.aspx" class="broken_link">Invitation</a> and <a href="http://sqlblog.com/blogs/michael_coles/archive/2010/05/13/t-sql-tuesday-006-round-up.aspx" class="broken_link">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/">T-SQL Tuesday #006: A Blobbing We Will Go</a></p>
<p>In the DMVs for SQL 2005 and SQL 2008 there is more than one place you can find the information about the size of your LOB data?  And it goes without saying that there is more than one way to find information about LOBs in your database.</p>
<h3>T-SQL Tuesday #007 – Summertime in the SQL (June 2010)</h3>
<p><a href="http://www.sqlchicken.com/2010/06/t-sql-tuesday-007-summertime-in-the-sql/">Invitation</a> and <a href="http://www.sqlchicken.com/2010/06/t-sql-tuesday-007-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/06/08/data-compression/">Data Compression</a></p>
<p>I see database compression, as offered with SQL 2008, to be more like these file compression utilities than DriveSpace.  Data compression in SQL 2008 is not an all or none implementation.  You get to pick and choose what gets compressed.  That is a big time bonus for me.</p>
<h3>T-SQL Tuesday #008: Gettin’ Schooled</h3>
<p><a href="http://sqlsoldier.net/wp/sqlserver/t-sql-tuesday-008-gettin-schooled">Invitation</a> and <a href="https://web.archive.org/web/20181017221048/http://sqlsoldier.net:80/wp/sqlserver/tsqltuesday8roundup">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="Gettin’ Skewled" href="http://jasonbrimhall.info/2010/07/13/gettin-skewled/" rel="bookmark">Gettin’ Skewled</a></p>
<p>I am learning that learning is not just formalized education in a classroom or in specific settings.  There are things to be learned from all aspects of life.  This can be learned if only a little observation is used.</p>
<h3>T-SQL Tuesday #009: Beach Time (August 2010)</h3>
<p><a href="http://jasonbrimhall.info/2010/08/03/t-sql-tuesday-009-beach-time/">Invitation </a>and <a href="http://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/" class="broken_link">roundup</a>.</p>
<p>I hosted this particular event.</p>
<p><strong>My Article</strong>: <a title="R &amp; R" href="http://jasonbrimhall.info/2010/08/10/r-r/" rel="bookmark">R &amp; R</a></p>
<p>I find it completely useless to go on vacation if I am going to be checking email or project statuses every 10 minutes.  There is no rest or relaxation in doing those things while I am supposed to be doing something else.  Vacation should be fun and enjoyable.  Thus, if I am to enjoy vacation, I need to do a few extra things in the office prior to leaving.</p>
<h3>T-SQL Tuesday #010 – Indexes (September 2010)</h3>
<p><a href="http://michaeljswart.com/2010/09/invitation-to-participate-in-t-sql-tuesday-10-indexes/">Invitation</a> and <a href="http://michaeljswart.com/?p=905">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="TSQL Tuesday Indexes and Blobs" href="http://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/" rel="bookmark">TSQL Tuesday Indexes and Blobs</a></p>
<p>How does one find what columns were LOB columns in the database.  I knew I had some past blog posts about various aspects of LOBs, but I had never broken it down to find the columns in the LOB.  Even better was that I wanted to know what columns were in what index that were also a BLOB.</p>
<h3>T-SQL Tuesday #011 – Misconceptions in SQL Server (October 2010)</h3>
<p><a href="http://sankarreddy.com/2010/10/invitation-to-participate-in-t-sql-tuesday-11-misconceptions-in-sql-server/">Invitation</a> and <a href="http://sankarreddy.com:80/2010/11/t-sql-tuesday-11-round-up-misconceptions-in-sql-server/">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/">A Haunting TSQL Tuesday Tale</a></p>
<p>I chose the myth that truncate is unrecoverable. Check it out and see how a truncate is most certainly capable of a rollback or being recoverable.</p>
<h3>T-SQL Tuesday #012 – Why are DBA skills necessary? (November 2010)</h3>
<p><a href="http://www.sqlskills.com/blogs/paul/invitation-to-participate-in-t-sql-tuesday-12-why-are-dba-skills-necessary/">Invitation</a> and <a href="http://www.sqlskills.com/blogs/paul/t-sql-tuesday-012-summary-of-why-dba-skills-are-necessary/">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #012 – Skills" href="http://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/" rel="bookmark">T-SQL Tuesday #012 – Skills</a></p>
<p>As a DBA, we occasionally have the opportunity of attracting a new client or a new job or a new database.  It seems that more often than not, some of the skills requisite (at least they should be) of owning a database are missing. (Nunchuku skills could come in handy from time to time too!)</p>
<h3>T-SQL Tuesday #13 – What the Business Says Is Not What the Business Wants (December 2010)</h3>
<p><a href="https://voiceofthedba.com/2010/12/07/t-sql-tuesday-13-what-the-business-says-is-not-what-the-business-wants/">Invitation</a> and <a href="https://voiceofthedba.wordpress.com/2010/12/17/t-sql-tuesday-13-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #13 – Business Requirements" href="http://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/" rel="bookmark">T-SQL Tuesday #13 – Business Requirements</a></p>
<p>I think a common area that is easily overlooked when it comes to requirements and interpretation of requirements is report creation.  A common problem is that there are no defined or written requirements for the creation of a report.</p>
<h3>T-SQL Tuesday #014 – RESOLUTIONS (January 2011)</h3>
<p><a href="http://www.midnightdba.com/DBARant/t-sql-tuesday-014-resolutions/">Invitation </a>and <a href="http://www.midnightdba.com/Jen/2011/01/t-sql-tuesday-014-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a href="http://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/">TSQL Tuesday 14: Committed</a></p>
<p>This month was all about resolutions and goals. My list of goals were pretty good and entirely profession based.</p>
<h3>T-SQL Tuesday #015 – Automation in SQL Server (February 2011)</h3>
<p><a href="https://sqlasylum.wordpress.com/2011/02/01/invitation-to-t-sql-tuesday-15-automation-in-sql-server/">Invitation</a> and <a href="https://sqlasylum.wordpress.com/2011/02/11/t-sql-tuesday-15-summary/">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #15 DBA Automaton" href="http://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/" rel="bookmark">T-SQL Tuesday #15 DBA Automaton</a></p>
<p>I shared a script that will load a sample of data from every table in every database for every column and give you the length of the pertinent columns (I have excluded obvious columns such as numeric types and certain LOB types).</p>
<h3>T-SQL Tuesday #016 – Aggregate Functions (March 2011)</h3>
<p><a href="http://blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/come-one-come-all-to/" class="broken_link">Invitation</a> and <a href="http://blogs.lessthandot.com/index.php/datamgmt/dbprogramming/sum-t-sql-tuesday-016/" class="broken_link">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #016: Aggregates and Statistics" href="http://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/" rel="bookmark">T-SQL Tuesday #016: Aggregates and Statistics</a></p>
<p>Super geeky article on stats, quartiles and the like. For my data analysis and trending, I wanted to find a simple distribution across quartiles.</p>
<h3>T-SQL Tuesday #017 – APPLY Knowledge (April 2011)</h3>
<p>Invitation and roundup &#8211; unavailable on origin site.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #17 – APPLY Knowledge" href="https://jasonbrimhall.info/2011/04/12/t-sql-tuesday-17-apply-knowledge/" rel="bookmark">T-SQL Tuesday #17 – APPLY Knowledge</a></p>
<p>In this article I take an unexpected twist in my application of the APPLY operator. In that twist, I show a quick and simple script to grab role members.</p>
<h3 class="entry-title">T-SQL Tuesday #018 – CTEs (May 2011)</h3>
<p><a href="https://www.bobpusateri.com/archive/2011/04/invitation-to-t-sql-tuesday-18-ctes/">Invitation</a> and <a href="https://www.bobpusateri.com/archive/2011/05/t-sql-tuesday-18-wrapup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #18 – CTEs" href="http://jasonbrimhall.info/2011/05/10/t-sql-tuesday-18-ctes/" rel="bookmark">T-SQL Tuesday #18 – CTEs</a></p>
<p>I shared a rather complex series of CTEs that are used in the same way a hierarchy and ancestry tree would be generated &#8211; except for Foreign Key relationships. That script was a load of fun.</p>
<h3 class="entry-title">T-SQL Tuesday #019 – Disasters and Recovery (June 2011)</h3>
<p><a href="http://www.allenkinsel.com/archive/2011/06/invitation-for-t-sql-tuesday-19-disasters-recovery/">Invitation</a> and <a href="http://www.allenkinsel.com/archive/2011/06/t-sql-tuesday-19-wrapup/">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #19 – Disasters &amp; Recovery" href="https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/" rel="bookmark">T-SQL Tuesday #19 – Disasters &amp; Recovery</a></p>
<p>Who needs a single disaster when you can enjoy multiple disasters in a single sitting? I share three different types of disasters. I am sure many have had experiences with all three and probably many more types of disasters.</p>
<h3 class="entry-title">T-SQL Tuesday #020 – T-SQL Best Practices (July 2011)</h3>
<p><a href="https://troubleshootingsql.com/2011/07/05/invitation-for-t-sql-tuesday-19-t-sql-best-practices/">Invitation</a> and <a href="https://troubleshootingsql.com/2011/07/15/">roundup</a>.</p>
<p><strong>My Article</strong>: N/A</p>
<p>I missed the announcement or something like that.</p>
<h3 class="entry-title">T-SQL Tuesday #021 – A Day Late and Totally Full Of It. (Aug. 2011)</h3>
<p><a href="http://dataeducation.com/t-sql-tuesday-21-a-day-late-and-totally-full-of-it/">Invitation</a> and roundup.</p>
<p><strong>My Article</strong>: <a title="TSQL Tuesday 21 – FAIL FAIL FAIL" href="http://jasonbrimhall.info/2011/08/10/tsql-tuesday-21-fail-fail-fail/" rel="bookmark">TSQL Tuesday 21 – FAIL FAIL FAIL</a></p>
<p>I don&#8217;t hide much as I share my feelings about crap code and then show my own crap code followed by a little bit of explanation on an improved version of the same code.</p>
<h3 class="entry-title">T-SQL Tuesday #022 – Data Presentation (September 2011)</h3>
<p><a href="http://www.sqlservercentral.com/blogs/pearlknows/2011/09/06/invitation-for-t-sql-tuesday-22-data-presentation/">Invitation</a> and <a href="http://www.sqlservercentral.com/blogs/pearlknows/2011/09/20/t-sql-tuesday-22-round-up-data-presentation/">roundup</a></p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #22 – Data Presentation" href="http://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/" rel="bookmark">T-SQL Tuesday #22 – Data Presentation</a></p>
<p>I chose to touch on several aspects of data presentation &#8211; Performance, Accuracy, Display, and Business Requirements.</p>
<h3 class="entry-title">T-SQL Tuesday #023 – Joins (October 2011)</h3>
<p><a href="http://codegumbo.com/index.php/2011/09/27/tsql2sday-t-sql-tuesday-23early-edition/">Invitation</a> and <a href="http://codegumbo.com/index.php/2011/10/10/tsql2sday-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: N/A</p>
<p>D&#8217;oh &#8211; missed another one in 2011.</p>
<h3 class="entry-title">T-SQL Tuesday #024 – Prox ‘n’ Funx (November 2011)</h3>
<p><a href="http://bradsruminations.blogspot.com/2011/10/invitation-for-t-sql-tuesday-024-prox-n.html">Invitation</a> and <a href="http://bradsruminations.blogspot.com/2011/11/t-sql-tuesday-024-roundup.html">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #024: Prox ‘n’ Funx" href="https://jasonbrimhall.info/2011/11/08/t-sql-tuesday-024-prox-n-funx/" rel="bookmark">T-SQL Tuesday #024: Prox ‘n’ Funx</a></p>
<p>Big takeaway from this month was the value of a very good string splitter.</p>
<h3 class="entry-title">T-SQL Tuesday #025 – Invitation to Share Your Tricks (Dec. 2011)</h3>
<p><a href="http://sqlblog.com/blogs/allen_white/archive/2011/12/05/t-sql-tuesday-025-invitation-to-share-your-tricks.aspx" class="broken_link">Invitation</a> and <a href="http://sqlblog.com/blogs/allen_white/archive/2011/12/17/t-sql-tuesday-25-followup-just-in-time-for-the-holidays.aspx" class="broken_link">roundup</a>.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #025 – Holiday Gifts" href="http://jasonbrimhall.info/2011/12/13/t-sql-tuesday-025-holiday-gifts/" rel="bookmark">T-SQL Tuesday #025 – Holiday Gifts</a></p>
<p>In the spirit of the Holidays, I wanted to share some tricks and tips.  They can be my gifts to you during the holidays.  And maybe they can help you give to somebody else.</p>
<h3 class="entry-title">T-SQL Tuesday #026 – Second Chances (January 2012)</h3>
<p><a href="http://tsqltuesday.com/2012/01/02/t-sql-tuesday-026-second-chances/">Invitation</a> and <a href="http://tsqltuesday.com/2012/01/02/t-sql-tuesday-026-second-chances/">roundup</a>. (Original site toasted).</p>
<p><strong>My Article</strong>: <a title="TSQL Tuesday #26 or #23 – Identity Crisis" href="http://jasonbrimhall.info/2012/01/10/tsql-tuesday-26-or-23-identity-crisis/" rel="bookmark">TSQL Tuesday #26 or #23 – Identity Crisis</a></p>
<p>Having missing TSQLTuesday 23 and the topic being about Second Chances, I chose to write about JOINs and sort of fulfilling the requirements for both TSQL Tuesdays in one shot.</p>
<h3 class="entry-title">T-SQL Tuesday #027 – Invitation to The Big Data Valentine’s Edition (February 2012)</h3>
<p><a href="https://voiceofthedba.com/2012/02/07/t-sql-tuesday-027-the-big-data-valentines-edition/">Invitation</a> and <a href="https://voiceofthedba.com/2012/02/17/the-t-sql-tuesday-027-roundup/">roundup</a>.</p>
<p><strong>My Article</strong>: N/A</p>
<p>After that second chance I blew it the very next month. Luckily I have a good reason &#8211; Valentines Day!</p>
<h3 class="entry-title">T-SQL Tuesday #028 – Jack of All Trades or Master of None (March 2012)</h3>
<p><a href="http://sqlblog.com/blogs/argenis_fernandez/archive/2012/03/05/t-sql-tuesday-028-jack-of-all-trades-master-of-none.aspx" class="broken_link">Invitation</a> and no roundup.</p>
<p><strong>My Article</strong>: <a title="T-SQL Tuesday #028 – Jack of All Trades, Master of None?" href="https://jasonbrimhall.info/2012/03/13/t-sql-tuesday-028-jack-of-all-trades-master-of-none/" rel="bookmark">T-SQL Tuesday #028 – Jack of All Trades, Master of None?</a></p>
<p>This one brings up bad memories of when as the DBA it was also required to be the janitor.</p>
<p>&nbsp;</p>
<h2><em>More updates coming soon!</em></h2>
<h3></h3>
<h3></h3>
<h3>What is T-SQL Tuesday?</h3>
<p>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" rel="noopener" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank" rel="noopener">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. <strong>Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Steve Jones via the</strong> <a href="http://tsqltuesday.com/2018/07/05/request-to-host-t-sql-tuesday/" class="broken_link">tsqltuesday website &#8211; here</a>.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday and 00:00 GMT Wednesday.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank" rel="noopener">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4949" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/19/t-sql-tuesday-participation-over-the-years/">T-SQL Tuesday Participation Over the Years</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/19/t-sql-tuesday-participation-over-the-years/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday 109: Influence Somebody Recap</title>
		<link>https://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-109-influence-somebody-recap</link>
					<comments>https://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 18 Dec 2018 13:42:52 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4769</guid>

					<description><![CDATA[<p>Small tokens of gratitude and small actions help to build this wonderful SQL Community that gives and gives and gives. Humility leads us to seek out ways to give more and become better as individuals. Give and you will receive!</p>
The post <a href="https://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/">T-SQL Tuesday 109: Influence Somebody Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>How have you impacted somebody in the community?</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png"><img loading="lazy" class="wp-image-4643 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png" alt="" width="247" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png 190w, https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection-50x46.png 50w" sizes="(max-width: 247px) 85vw, 247px" /></a>This month I am in charge of the topic for TSQLTuesday. The invite was <a href="http://jasonbrimhall.info/2018/12/04/influence-somebody-invite/">published here</a> a couple of weeks ago. I knew I was picking something rather difficult for people in general and probably more difficult for technologists due to the notion of jumping head first into a discussion with somebody about yourself. I have been asked by previous employers to do my own personal annual job review. This idea is very much like that &#8211; but more personal.</p>
<p>Some say it eats at the core of being prideful to discuss this topic or to broach the &#8220;review&#8221; with others. I like to take a different angle on it. I see it as a means to personal growth and has nothing to do with bragging. I tend to find that people gifted with humility will ask others how they could improve professionally or personally. Being able to find where you are doing well or not so well is key to progress. I would hope those that participated found this difficult exercise helpful in uncovering a new angle on personal and/or professional improvement.</p>
<p>&nbsp;</p>
<h2 style="text-align: left;">Discomfort</h2>
<p><img loading="lazy" class="wp-image-4779 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/rodfarley_tsql2sday109.png" alt="" width="257" height="183" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/rodfarley_tsql2sday109.png 255w, https://jasonbrimhall.info/wp-content/uploads/2018/12/rodfarley_tsql2sday109-50x36.png 50w" sizes="(max-width: 257px) 85vw, 257px" /></p>
<p>There is no hiding from the fact that this task provided a great deal of discomfort and probably angst as demonstrated from this tweet.</p>
<p>&nbsp;</p>
<p>Multiple participants, as you will see as you read their articles, shared their feelings on the level of discomfort and difficulty they had with the topic. I expected the discomfort, I felt it too.</p>
<p>As I read the articles, I could feel the discomfort alongside the author. I get it &#8211; it&#8217;s hard because none of us want to come off as bragging about ourselves. Take into account that discomfort and then the message that each of these people has to share with you!</p>
<h2>WHO?</h2>
<p><strong>Steve Jones</strong> (<a href="https://voiceofthedba.com/">b</a> | <a href="https://twitter.com/way0utwest">t</a>) &#8211; <a href="https://voiceofthedba.com/2018/12/12/t-sql-tuesday-109-influence/">Influence</a>. Steve is not comfortable writing about this topic as he dives in to share with us. As he does he hits a very strong note for me. We, the SQL Community, give a lot of ourselves and that giving grows exponentially. We give of ourselves and many times we end up the recipient of this exponential experience.</p>
<blockquote><p>It can be scary and intimidating to share knowledge with others publicly, but it is also immensely rewarding! -Steve Jones</p></blockquote>
<p>I believe the same can be said of sharing a personal review publicly.</p>
<p><strong>Wayne Sheffield</strong> (<a href="https://blog.waynesheffield.com/wayne/">b</a> | <a href="https://twitter.com/DBAWayne">t</a>) &#8211; <a href="https://blog.waynesheffield.com/wayne/archive/2018/12/tsql-tuesday-109-influence-somebody/">Influence Somebody</a>. I personally know that Wayne had a hard time with this topic and sharing an article. Wayne shares a couple of stories outlining some very small actions on his part. He was largely unaware of his influence and in turn ended up dumbfounded and awestruck at what his influence meant to other people.</p>
<blockquote><p><strong>Small actions</strong>. That’s all it takes to make a positive difference in a person’s life. Be interested, and encouraging. You never know what kind of effect you are truly having on people. And when you do find out, prepare to be astonished. &#8211; Wayne Sheffield</p></blockquote>
<p><strong>Malathi Mahadevan</strong> (<a href="https://curiousaboutdata.com">b</a> | <a href="https://twitter.com/sqlmal">t</a>) &#8211; <a href="https://curiousaboutdata.com/2018/12/11/tsql-tuesday-109-to-influence-and-to-be-influenced/">To Influence and be Influenced</a>. Mala is a very humble person. Mala shares a personal experience about her influence several other people as she worked on her <a href="http://wordpress.redirectingat.com/?id=725X1342&amp;site=curiousaboutdatacom.wordpress.com&amp;xs=1&amp;isjs=1&amp;url=https%3A%2F%2Fwww.amazon.com%2FData-Professionals-Work-Malathi-Mahadevan%2Fdp%2F1484239660%2Fref%3Dsr_1_1%3Fie%3DUTF8%26qid%3D1544573746%26sr%3D8-1%26keywords%3Ddata%2Bprofessionals%2Bat%2Bwork&amp;xguid=01CW6YRZ93BCB7JCMZ266KT8WK&amp;xuuid=69a7fb42a292e6abf0da2fecd3a4d6af&amp;xsessid=&amp;xcreo=0&amp;xed=0&amp;sref=https%3A%2F%2Fcuriousaboutdata.com%2F2018%2F12%2F11%2Ftsql-tuesday-109-to-influence-and-to-be-influenced%2F&amp;pref=https%3A%2F%2Ft.co%2FgkZCrg687r&amp;xtz=420&amp;abp=1&amp;jv=13.12.1-stackpath&amp;bv=2.5.1">very first book project</a> this past year. The really cool part is the joy she got from seeing many people filled with the joy of having the opportunity to be in the book.</p>
<blockquote><p>It is a positive way to end the year on a <strong>tone of gratitude</strong> to people who have influenced you – and it is doubly positive/uplifting to see/hear of what you have done to other people too. &#8211; Mala</p></blockquote>
<p>I am grateful for the friendship I have with Mala, she is a genuine and good person.</p>
<p><strong>Shane O&#8217;Neill</strong> (<a href="https://nocolumnname.blog">b</a> | <a href="https://twitter.com/SOZDBA">t</a>) &#8211; <a href="https://nocolumnname.blog/2018/12/11/t-sql-tuesday-109-influence-somebody-invite/">Influence Somebody</a>. Shane shares how difficult this task was going in and even stumbles on a bit of writers block. Shane doesn&#8217;t go out daily to try and find somebody to profoundly impact. He goes about his day in an unassuming way as he just does what he does &#8211; shares knowledge just because it needs to be shared. Shane is aware of the impact as people have met him and thanked him personally for his contributions to the community. That&#8217;s a win win!</p>
<blockquote><p>I’ve had some great surprises from people in the community about stuff they’ve seen on here.</p>
<p>It’s nice to know that when you’re shouting into the void, that the void sometimes shouts back.</p>
<p><strong>Each token of appreciation, each expression of gratitude is a replenishment to my morale.</strong></p>
<p>Just a way to say that all efforts put in, while not showing straight away, build up. &#8211; Shane O&#8217;Neill</p></blockquote>
<p>I am sure many of us have felt that replenishment to morale from the various tokens of gratitude. The sincere and personal sharing of appreciation carries so much more weight and replenishes the morale so much more completely.</p>
<p><strong>Rob Farley</strong> (<a href="http://blogs.lobsterpot.com.au/">b</a> | <a href="https://twitter.com/rob_farley">t</a>) &#8211; <a href="http://blogs.lobsterpot.com.au/2018/12/12/people-i-influence/">People I Influence</a>. Rob is a humble kind and caring person! He struggled with the topic as he illustrated on twitter. All of that aside, he hit on a note I was hoping somebody would hit on &#8211; employees and coworkers. Employees are a reflection of leadership. If the leader is a class act, s/he will impact the employees in a positive manner for the better of the company and the employee.</p>
<p>That aside, Rob is hopeful of being an influence to other people outside of work. Rob is not comfortable with thinking about whether he is influential or not and I get it. I don&#8217;t think many of us think regularly about our sphere of influence &#8211; until somebody gives us that token of gratitude for some small action we performed.</p>
<blockquote><p>For a while now, I’ve thought that I would rather employ MVPs than be one myself (although I hope this doesn’t actually cause me to lose my status), and I have often looked for opportunity to get my team in front of people.</p></blockquote>
<p>As an employer who encourages his staff to be community minded and on the path to being MVPs like Rob is, I think this an outstanding level of influence that is merely demonstrative of the humility that resonates within Rob.</p>
<p><strong>Jason Brimhall</strong> (me) &#8211; <a href="https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/">To Influence or be Influenced</a>. I share a couple of experiences in my entry for the month. More important than the stories is the message that as one gives of themselves, there is a gain that will be returned to that person at some point that is likely exponential in nature to the little token of giving that happened in the first place. Give and you will receive! Steve hit on that same note.</p>
<p>And in case you are still curious what this TSQL Tuesday thing is, here are the details&#8230;</p>
<h3>What is T-SQL Tuesday?</h3>
<p><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" rel="noopener" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank" rel="noopener">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Steve Jones via the <a href="http://tsqltuesday.com/2018/07/05/request-to-host-t-sql-tuesday/" class="broken_link">tsqltuesday website &#8211; here</a>.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday, December 11e, 2018, and 00:00 GMT Wednesday December 12e, 2018.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank" rel="noopener">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4769" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/">T-SQL Tuesday 109: Influence Somebody Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/18/t-sql-tuesday-109-influence-somebody-recap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Synonyms in SQL Server &#8211; Good and Bad</title>
		<link>https://jasonbrimhall.info/2018/12/14/synonyms-in-sql-server-good-and-bad/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=synonyms-in-sql-server-good-and-bad</link>
					<comments>https://jasonbrimhall.info/2018/12/14/synonyms-in-sql-server-good-and-bad/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 14 Dec 2018 13:30:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4746</guid>

					<description><![CDATA[<p>How you use a synonym can be a huge asset or it can be a significant dampener to performance.  There are benefits and uses for these nifty little things.  Check them out and let us know how you have been able to put synonyms to use to benefit you.</p>
The post <a href="https://jasonbrimhall.info/2018/12/14/synonyms-in-sql-server-good-and-bad/">Synonyms in SQL Server – Good and Bad</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>When SQL Server 2005 was released, a nifty little feature was included called synonyms.  Despite being around since SQL Server 2005, I think this feature is often under-utilized or, more importantly, it is implemented in a very bad way.</p>
<p>Today I want to share a couple of examples.  We will take a look at examples of both good and bad implementations of synonyms.</p>
<p>First, let&#8217;s take a look at the syntax for creating a synonym.  Per <a href="http://msdn.microsoft.com/en-us/library/ms177544.aspx">BOL</a> (and for the fun of it, here is the 2005 <a href="http://msdn.microsoft.com/en-us/library/ms177544(v=sql.90).aspx">link</a>).</p><pre class="urvanov-syntax-highlighter-plain-tag">-- SQL Server Syntax

CREATE SYNONYM [ schema_name_1. ] synonym_name FOR &amp;lt;object&amp;gt;

&amp;lt;object&amp;gt; :: =
{
    [ server_name.[ database_name ] . [ schema_name_2 ]. object_name 
  |  database_name . [ schema_name_2 ].| schema_name_2. ] object_name
}
-- Windows Azure SQL Database Syntax

CREATE SYNONYM [ schema_name_1. ] synonym_name FOR &amp;lt; object &amp;gt;

&amp;lt; object &amp;gt; :: =
{
    [database_name. [ schema_name_2 ].| schema_name_2. ] object_name
}</pre><p>So a sample implementation of a Synonym could be something like the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE SYNONYM [syn].[Staging_Cardumum] FOR [Cardamum_UAT].[dbo].[cardamum_staging]
GO</pre><p>Before we delve into that sample synonym, lets look at an example of a really bad implementation.</p>
<h2>The BAD</h2>
<p>While working with a client, I received a request to look into why a linked server query was failing.  (This isn&#8217;t necessarily the bad, just hang in there for a bit.)  The message was something like this:</p>
<blockquote><p>The OLE DB provider &#8220;SQLNCLI10&#8221; for linked server &#8220;blahblahblah&#8221; indicates that either the object has no columns or the current user does not have permissions on that object.</p></blockquote>
<p>The error message seems at least semi-descriptive and gives a starting point.  In this case, I decided to verify the linked server was created properly, verified that the permissions were done properly and even tested the linked server.  On the source (linked) and destination server (let&#8217;s call the Source server ServerA and the Destination server we will call ServerB), I verified that permissions were in place for each database to be touched.  Still no dice!</p>
<p>Well, let&#8217;s go take a look and see if that referenced table actually exists.  It did not!  Does it exist as a view?  It did not!  Alas, the table existed as a synonym.  This is where it gets wonky.  In looking at the definition of the synonym, I found that the table defined in the synonym had a linked server table as its source.  To top things off, the linked server was back on the originating server that was coming across the link in the first place.  So yes, that would be ServerB initiated a query against ServerA to pull data back to ServerB.  But the data needed (as defined by the vendor) was available on ServerA &#8211; supposedly.  Reality had that data actually sitting on ServerB the whole time.</p>
<p>At any rate, thanks to having a synonym for each and every table sitting on ServerA that referenced a table across a linked server on ServerB, we had mass confusion.  In the end, the query was far simpler to execute by just pulling it from the originating query server (ServerB).</p>
<p>This implementation of a synonym was not the best.  All it did was cause confusion, create documentation inaccuracies and delay the developer from accomplishing her task.  Do you really need 1000s of synonyms in your database?  Do you need all of them going across a linked server?  If you do, did you ever think about the potential for performance issues?  (The vendor in this case used those linked servers and synonyms to perform a data conversion that took 36 hrs each time for a rather small dataset &#8211; ouch!!!!).</p>
<h2>On the other Hand</h2>
<p>Imagine, if you will, two databases sitting on the same box.  One database will be for your user data, and the other for &#8220;staging&#8221; data for processes such as those related to ETL.  Imagine further that, for some inane reason, the naming standard of your databases must include the suffix denoting the environment of the database.</p>
<p>Now picture an SSIS package that must utilize tables from both databases in data sources somehow.  At least one of the tables has millions of records.  And both of the tables have nearly 100 columns.  Even just pulling in the minimum amount of data using a query from each source can cause memory issues.  Two separate data sources means you will likely have a sort transformation (for each source) as well as a join transformation.</p>
<p>Trying to reduce the amount of data in the larger table source could be done via TSQL.  But to reference a database in one environment versus another environment means a code change with each deployment (due to the TSQL &#8211; think three part naming).  So you have been hampered by the environment.  Or have you?</p>
<p>By using a synonym in this situation, the data can be joined in a tsql data source by referencing that synonym.  Let&#8217;s look back at the sample synonym posted earlier in this article.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE SYNONYM [syn].[Staging_Cardumum] FOR [Cardamum_UAT].[dbo].[cardamum_staging]
GO</pre><p>You can see that this synonym follows the same sort of naming standards as was just laid out in the preceding scenario.  If I create a synonym in each environment by the same name, and referencing the appropriate environment named database, I have just opened up a performance tweak for my SSIS datasource.</p>
<p>By implementing this slight tweak, I have been able to gain a 10x performance improvement in package performance.  I am now requiring SSIS to ingest fewer records and thus chew up less memory.  Fewer transformations are required and the package can just fly into the required transformations, rather than tinkering around with the transformations needed to just get the data into a usable state for those transformations.</p>
<p>There are other benefits within SSIS to using synonyms for databases on the same server as well.  Especially when dealing with this kind of naming standard that requires the databases to be named differently in each environment.</p>
<h2>Conclusion</h2>
<p>How you use a synonym can be a huge asset or it can be a significant dampener to performance.  There are benefits and uses for these nifty little things.  Check them out and let us know how you have been able to put synonyms to use to benefit you.</p>
<p>Check out some of these other articles on synonyms <a href="http://jasonbrimhall.info/2016/04/12/awesome-sql-server-feature/">here</a> and <a href="http://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4746" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/14/synonyms-in-sql-server-good-and-bad/">Synonyms in SQL Server – Good and Bad</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/14/synonyms-in-sql-server-good-and-bad/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Maintenance Plan Owner &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/12/13/maintenance-plan-owner-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maintenance-plan-owner-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/12/13/maintenance-plan-owner-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 13 Dec 2018 13:55:51 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4736</guid>

					<description><![CDATA[<p>Have you ever taken over a server that had several maintenance plans on it?  Have you ever really checked who the owner of those plans is?  Or, maybe you had a failing job relating to one of these maintenance plans and you changed the job owner, but did you really fix the root cause?  That could be one of those things that you inherited that could be annoying but you just don’t know it yet.</p>
The post <a href="https://jasonbrimhall.info/2018/12/13/maintenance-plan-owner-back-to-basics/">Maintenance Plan Owner – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>We all inherit things from time to time through our profession.  Sometimes we inherit some good things, sometimes we inherit some things that are not so good.  Other times we inherit some things that are just plan annoying.  Yet other times, we inherit things that may be annoying and we probably just haven’t discovered them yet.</p>
<p>Dizzying, I know.</p>
<h2>Inheritance</h2>
<p>Have you ever taken over a server that had several maintenance plans on it?  Have you ever really checked who the owner of those plans is?  Or, maybe you had a failing job relating to one of these maintenance plans and you changed the job owner, but did you really fix the root cause?  That could be one of those things that you inherited that could be annoying but you just don’t know it yet.</p>
<h2>Step by Step</h2>
<p>No this is not New Kids on the Block (I think I just threw up in my mouth thinking that).</p>
<p>Let’s create a generic maintenance plan and see what happens.</p>
<p>The first thing we do is navigate to Maintenance Plans under the Management menu in Management Studio.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplancontext.png"><img loading="lazy" class="wp-image-4737 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplancontext.png" alt="" width="248" height="158" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplancontext.png 660w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplancontext-300x191.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplancontext-50x32.png 50w" sizes="(max-width: 248px) 85vw, 248px" /></a></p>
<p>&nbsp;</p>
<p>Right Click the Maintenance Plan folder and select New Maintenance Plan… from the context menu.  This will prompt us with the following dialog box.</p>
<p><img class="wp-image-1687 aligncenter" title="maintplanowner" sizes="(max-width: 354px) 100vw, 354px" srcset="http://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner.png 354w, http://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner-300x105.png 300w" alt="" width="309" height="109" /></p>
<p>In this box, we can type a name for this Maintenance Plan that is to be created.  I chose MaintPlanOwner, since that is the topic of this article.</p>
<p><img class="wp-image-1689 alignright" title="modifyplan" sizes="(max-width: 258px) 100vw, 258px" srcset="http://jasonbrimhall.info/wp-content/uploads/2012/06/modifyplan.png 258w, http://jasonbrimhall.info/wp-content/uploads/2012/06/modifyplan-215x300.png 215w" alt="" width="213" height="297" /></p>
<p>After clicking ok on this dialog box, you will be presented with a blank canvas with which to design your maintenance plan.  I have chose a simple task for the purposes of this article.</p>
<p>I will create a subplan named Statistics and add the Update Statistics task to the canvas.</p>
<p>You can see this illustrated to the left.  I chose to update the statistics on all databases and left all other options as the default option – for simplicity of this article.</p>
<p>At this point, the only thing left to do is to save this Maintenance Plan.  Once the plan is saved, then we can move on to the next step – some fun with TSQL.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Fun with TSQL</h2>
<p>This is the stage of the article where we get to play with TSQL and investigate at a high level the Maintenance Plan we just created.</p>
<p>Within the msdb database, we have some system tables that store information about SSIS packages, DTS packages, and Maintenance Plans.  We will be investigating from a SQL 2008 and SQL 2005 standpoint (it changed in 2005 and then again in 2008).</p>
<p>In SQL 2005, we can query the sysdtspackages90 and sysdtspackagefolders90 to gain insight into who owns these Maintenance Plans.  In SQL 2008 and up, we can query sysssispackages and sysssispackagefolders to gain the same insight.  These system tables are within the msdb database.</p>
<p>In SQL Server, we can use the following to find that I am now the owner of that maintenance plan we just created.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
DECLARE @ServerMajorVersion DECIMAL(4, 2)
		,@SQLProduct VARCHAR(24)
		,@SQL VARCHAR(MAX);

SELECT @ServerMajorVersion = CONVERT(DECIMAL(4, 2), PARSENAME(dt.fqn, 4) + '.'
		+ PARSENAME(dt.fqn, 3))
	FROM ( SELECT CONVERT(VARCHAR(20), SERVERPROPERTY('ProductVersion'))
			) dt ( fqn );
IF OBJECT_ID('tempdb.dbo.#SQLVersions') IS NOT NULL
BEGIN
	DROP TABLE #SQLVersions;
END

CREATE TABLE #SQLVersions
	(VersionID INT IDENTITY(1,1)
		, Product VARCHAR(32)
		, ServerMajorVersion DECIMAL(4, 2) --INDEX CI_ServerMajorVer CLUSTERED
	);
CREATE CLUSTERED INDEX CI_ServerMajorVer ON	#SQLVersions (VersionID);

INSERT INTO	#SQLVersions
		( Product
			, ServerMajorVersion
		)
	VALUES
		( 'SQL Server 2008', 10.00)
		,( 'SQL Server 2008R2', 10.50)
		,( 'SQL Server 2012', 11.00)
		,( 'SQL Server 2014', 12.00)
		,( 'SQL Server 2016', 13.00)
		,( 'SQL Server 2017', 14.00)
		,( 'SQL Server 2019', 15.00)
		,( 'SQL Server 2005', 9.00);

SELECT @SQLProduct = Product
	FROM #SQLVersions sv
	WHERE sv.ServerMajorVersion = @ServerMajorVersion;

SET @SQL = '
SELECT	p.name AS PackageName
		, '''+ @SQLProduct + ''' AS SQLVersion
		, p.createdate
		, pf.foldername AS PackageType
		, sp.name AS PrincipalName
	FROM ' + CASE WHEN @ServerMajorVersion &lt; 10 THEN 'msdb.dbo.sysdtspackages90 p
		INNER JOIN dbo.sysdtspackagefolders90 pf
			ON p.folderid = pf.folderid'
			ELSE 'msdb.dbo.sysssispackages  p
		INNER JOIN dbo.sysssispackagefolders pf
			ON p.folderid = pf.folderid' END + '
		LEFT OUTER JOIN master.sys.server_principals sp
			ON p.ownersid = sp.sid
	WHERE pf.foldername = ''Maintenance Plans''
	ORDER BY PackageName;'

EXECUTE (@SQL);

IF OBJECT_ID('tempdb.dbo.#SQLVersions') IS NOT NULL
BEGIN
	DROP TABLE #SQLVersions;
END</pre><p>Notice that in this query, I delve out to the sys.server_principals catalog view.  I did this to retrieve the name of the owner of the package that was found in the sysdtspackages90 and sysssispackages tables respective to version of SQL Server. I also am running a dynamic SQL query to support both views dependent on version of SQL Server.  I figured this might be a tad more helpful than the previous version <a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/">here</a>. This query would yield the following result set for that new &#8220;Maintenance Plan&#8221; that was just created.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results.png"><img loading="lazy" class="aligncenter wp-image-4741 size-large" title="owner" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results-1024x86.png" alt="" width="560" height="47" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results-1024x86.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results-300x25.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results-768x65.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_results.png 1131w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<h2>Caveat</h2>
<p>Let’s assume that this package is scheduled via a SQL Agent job on a production server.  I then get moved to a different department and no longer have permissions on this particular production server.  The job will start failing due to the principal not having access.  One fix would be to change the owner of the job.</p>
<p>That will work.  However, there is a problem with that fix.  As soon as somebody opens and saves the Maintenance Plan, the owner of the job will revert back to the owner of the Maintenance Plan.  When that happens, then the job will fail again.</p>
<p>A permanent fix is needed.  The permanent fix is to change the owner of the Maintenance Plan.  The following will change the owner to ‘sa’ for both SQL 2005 and SQL 2008 (and up).</p>
<h3>SQL 2005</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
UPDATE p
SET ownersid = 0x01
FROM msdb.dbo.sysdtspackages90  p
	INNER JOIN dbo.sysdtspackagefolders90 pf
		ON p.folderid = pf.folderid
WHERE pf.foldername = 'Maintenance Plans';</pre><p></p>
<h3>SQL 2008</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
UPDATE p
SET ownersid = 0x01
From msdb.dbo.sysssispackages  p
	INNER JOIN dbo.sysssispackagefolders pf
		ON p.folderid = pf.folderid
WHERE pf.foldername = 'Maintenance Plans';</pre><p>Now if you run the code used earlier to investigate, you will find that the owner has indeed changed.  The results of that query should be similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed.png"><img loading="lazy" class="aligncenter wp-image-4742 size-large" title="owner_changed" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed-1024x91.png" alt="" width="560" height="50" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed-1024x91.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed-300x27.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed-768x68.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/12/maintplanowner_changed.png 1105w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>There you have it.  No more hair tugging over something as benign as the owner of a Maintenance Plan.  This is one of those things that should be looked at as soon as you inherit a new server.</p>
<h2>The Wrap</h2>
<p>In this article I took a rather long route to a simple fix. It&#8217;s easy to try each of the steps I showed in this article thinking it will help. It isn&#8217;t illogical to try some of those steps. They just don&#8217;t work unfortunately. In the end, getting to know the settings in the database and what the errors are really trying to get at is most helpful. Sometimes, it just takes a few more steps to get to the real meaning of the error.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4736" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/13/maintenance-plan-owner-back-to-basics/">Maintenance Plan Owner – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/13/maintenance-plan-owner-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>To Influence or Be Influenced?</title>
		<link>https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=to-influence-or-be-influenced</link>
					<comments>https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Dec 2018 13:44:31 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4732</guid>

					<description><![CDATA[<p>Getting feedback from others is that little check that is needed to help progress and move in the right direction. When allowing time and opportunity for feedback from others, you are doing yourself a service as well as them.</p>
The post <a href="https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/">To Influence or Be Influenced?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>How have you impacted somebody in the community?</h2>
<p><a href="http://jasonbrimhall.info/2018/12/04/influence-somebody-invite/"><img loading="lazy" class="alignright wp-image-4643" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png" alt="" width="247" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png 190w, https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection-50x46.png 50w" sizes="(max-width: 247px) 85vw, 247px" /></a>Well, have I come up with a doozy of a topic for this month for the <a href="http://tsqltuesday.com/">TSQLTuesday</a> party. Its not easy to step out of ones own comfort zone. Its even more difficult to fathom the thought and action of performing a self review. That is in essence the task at hand &#8211; self review or have somebody else review your personal contributions to the community.</p>
<p>In the <a href="http://bit.ly/2rlSH9O">invite</a>, I mentioned how many of us have been able to come up with lists of people that have impacted us personally. Using that previous exercise would be a pretty good resource for some to maybe find out more how it was they influenced another person in the community.</p>
<p><span style="text-decoration: underline;"><em>To be candid, the invite is not just for those who have influenced others but also for those who have been influenced. If somebody had an impact on your career or your personal identity, take a minute to chat with them and let them know!</em></span></p>
<h2 style="text-align: left;">Surprises</h2>
<p>How great is it to provide a service to somebody and then to receive a legitimate and meaningful thank you? The SQL community gives and gives and gives and all too often there is no personal note of gratitude for the help given. Every once in a blue moon, that thank you comes and a really cool calming feeling may just overwhelm you. That is when you know you have done good and have meant something to somebody in their life or career.</p>
<p>I am not talking about the flippant thumbs ups, or likes as you may see in social media. Granted, seeing those likes and retweets is probably nice to see on occasion. It just doesn&#8217;t bring a real valid connection to the people you are trying to help.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/12/tropical.jpg"><img loading="lazy" class="wp-image-4734 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/12/tropical.jpg" alt="" width="366" height="244" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/12/tropical.jpg 612w, https://jasonbrimhall.info/wp-content/uploads/2018/12/tropical-300x200.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/12/tropical-50x33.jpg 50w" sizes="(max-width: 366px) 85vw, 366px" /></a>These kind of personal connections are the types of things that build friendships, networks, and long lasting relationships. Someday, this relationship may turn into a client or co-worker or even future mentor (we all can learn something new from other people).</p>
<p>I have had this kinds of conversations more than a few times with the most recent just occurring today from a client. The latest opportunity came as a candid conversation after taking a week long vacation. The client asked me over for a quick chat and reminded me of how thankful they are for the effort and long hours I have given them. The stability they now see with the environment has brought peace of mind and comfort knowing the database will be up when they need them. It has been a culture shift in how databases are viewed there and it has been a good and meaningful shift. This organization is now setup to bring on more talent to a database team.</p>
<p>Just as meaningful is the opportunity I had to chat with another MVP. This person pulled me aside at a very popular conference. I must admit this one blew me away because I had no idea. This person proceeded to tell me how thankful he was that I was a good example as a friend and mentor. He was also appreciative of the time I would take to answer his technical or non-technical questions. Unbeknownst to me, this was happening while he was hitting a rough patch (his words).</p>
<p>This second experience was extremely humbling to me. I share this because I was unaware of the profound impact I was having on this person who later became an MVP. I didn&#8217;t do anything super special. I just did what I felt was right. The experience reminded me of why I do the things I do in the community. While extremely gratifying to give and help, it is also very humbling to be able to give, help and be reminded of how a little effort can have a profound effect.</p>
<p>For me, this reminder came when I was personally getting a little down. I needed the reminder to keep it humble and continue to give. I enjoy helping in various ways in the SQL community and I was getting a little sidetracked from doing those things I enjoy. So by these people pulling me aside and telling me about the influence I had on them, they unwittingly also had an impact on me. <a href="http://jasonbrimhall.info/2018/05/08/giving-back/">As I have said multiple times</a>, when you give, you also get something in return. That is the nature of service.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Circling Back</h3>
<p><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>Just because you give to the community doesn&#8217;t mean you can&#8217;t also receive. It also doesn&#8217;t mean that it has to be done without ever knowing the true impact of your giving. You simply cannot improve yourself if you have no clue how well you are doing.</p>
<p>Getting feedback from others is that little check that is needed to help progress and move in the right direction. When allowing time and opportunity for feedback from others, you are doing yourself a service as well as them. As I noted, these people that gave me this feedback not only told me about how much I helped them, but they also impacted me at the right moment to help me remember the reasons behind why I like to help. Give a little and you will also get a little!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4732" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/">To Influence or Be Influenced?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/11/to-influence-or-be-influenced/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Capture the Flag &#8211; The Trace Flag</title>
		<link>https://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=capture-the-flag-the-trace-flag</link>
					<comments>https://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 06 Dec 2018 13:54:07 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2703</guid>

					<description><![CDATA[<p>Despite the controls in place there always seems to be some change that is unknown or even some cowboy that makes changes as s/he sees fit and forgets to notify people or follow process.</p>
The post <a href="https://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/">Capture the Flag – The Trace Flag</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Many people work in a tightly controlled environment. Every change requires a change control form and approval to make a change. In some environments, things are more lax, but you still wish you could tell when certain changes were made. That is even true in some <a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="233" height="233" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 233px) 85vw, 233px" /></a>of those tightly controlled environments. You know what I am talking about. Despite the controls in place there always seems to be some change that is unknown or even <strong>some cowboy that makes changes</strong> as s/he sees fit and forgets to notify people or follow process.</p>
<p>Then come the times when you are new to an environment and you really need to know some basic information about the servers you have just inherited. Well, truth be told, you don&#8217;t necessarily have to be new to a job to inherit some new servers. Sometimes, blackbox servers end up getting dropped into your realm of responsibility.</p>
<p>When you run into something like this, you really need to have some means to figure out what changed, when it changed and who changed it. Having that information as a base, you would then have the tools to inquire as to why it might have been changed. One of the things that would be nice to know is around the trace flags that can be enabled in SQL Server. There are trace flags (or knobs) for so many different things within SQL Server that it would be nice to get a handle on them if they do happen to be enabled or even disabled.</p>
<p>As a DBA in SQL Server, you should know by now that there are<strong> multiple different ways</strong> to do all sorts of things within SQL Server. Today we will discuss three different methods that you could use to perform this investigation for yourself.</p>
<h3>Report Style</h3>
<p>Did you know that Management Studio comes with a dashboard report? It does! In that report, one will find a pretty decent amount of overview information as a first pass to get to know your server. If you were to right click the instance within SSMS, you can browse to the Reports/Standard Reports submenus. From there you can select the Dashboard report. The path to the reports is similar to what is displayed in the following screen capture.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/ReportMenu.png"><img loading="lazy" class="aligncenter size-full wp-image-4626" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/ReportMenu.png" alt="" width="631" height="157" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/ReportMenu.png 631w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ReportMenu-300x75.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ReportMenu-50x12.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>The report that is of interest is circled in red in the preceding image.</p>
<p>If you have any trace flags enabled (globally) you can see those listed in the report similarly to the following image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard.png"><img loading="lazy" class="aligncenter size-full wp-image-4625" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard.png" alt="" width="802" height="434" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard.png 802w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard-300x162.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard-768x416.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ServerDashboard-50x27.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Once again, I have encircled the relevant data in red. From this instance that I queried, I currently have one trace flag enabled. As it stands, this particular trace flag is the one that disables the noise of successful backups from being recorded to your log.</p>
<p>This is one particularly easy method to retrieve that information. A benefit from this method is that you will be able to see some graphs and charts and so forth by using the report.</p>
<h3>SQL Query</h3>
<p>As logic would dictate, it would seem that we should be able to trap that information through the use of our most frequently used tool &#8211; TSQL. Case in point is that the report itself requires the use of TSQL to produce the dataset for the nice display we would see when the report is rendered.</p>
<p>Using similar code to what is used to produce the Dashboard report, we can get a decent understanding of the trace flags that might be employed on your particular instance.  Let&#8217;s take a quick look at what we could do.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #tracestatus(
        TraceFlag nvarchar(40)
,       Status tinyint
,       Global tinyint
,       Session tinyint
);

insert into #tracestatus 
	exec('dbcc tracestatus')
update #tracestatus 
	set TraceFlag = 'Traceflag ('+TraceFlag+')'

select 1 as l1
,       TraceFlag as name
,       convert(nvarchar(15), Status) as run_value
,       '0' as default_value
,       1 as msg  
from #tracestatus 
where Global=1 order by name

GO</pre><p>As you can see, that code is terribly simple. The crux of the code boils down to a DBCC command to return the results of TRACESTATUS. Granted, this is a bit over the top and designed to dump the data into a table for later consumption (for good reason). You can legitimately get away with simply running DBCC TRACESTATUS. The results of this would produce the following for the same instance of SQL Server shown in the Server Dashboard report we already explored. Those results look like the following.</p>
<p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/11/queryout.png"><img loading="lazy" class="alignnone wp-image-1698 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/11/queryout.png" alt="queryout" width="471" height="58" /></a></p>
<p>So far, so good. If I had several trace flags enabled globally on this instance then <strong>I would see every single one of them</strong> in the result set just displayed. Cool!</p>
<p>To this point, this is wonderful for anything that might be currently enabled on the instance. Should any of those trace flags be disabled shortly after being enabled, or even be disabled months after being enabled but before you run either of the two preceding methods, then you are up a creek without a paddle. <strong>That is a problem</strong>. How would you trap that cowboy sysadmin or cowboy DBA in that case? Well, you could go with a full blown audit. Or you could try a similar approach but on a somewhat smaller scale.</p>
<p><em>If you are paying close attention, you are probably thinking to yourself that the query just demonstrated seems more complex than it need be.  After all, the documentation for DBCC TRACESTATUS says that I can run that command with a -1 parameter and just have it return the global trace flags.  And in the script I am showing, I filter on Global = 1.  Well, as it turns out, the -1 option in DBCC TRACESTATUS does not work as documented.  The -1 parameter does not return the appropriate result set and that is reproducible.  If you were curious, the MSDN reference is <a href="http://msdn.microsoft.com/en-us/library/ms187809.aspx">here</a>.  The use of that parameter value still returns session flags as well.</em></p>
<h3>Extended Event</h3>
<p>Oh my, we are talking about something really abstract and difficult now! No, not really.  This is a pretty <strong>straightforward approach and easy enough to implement</strong>. Within XE, there is an event called trace_flag_changed. If you were curious, you could use a query such as the following to find any events that might be related. The key is finding the correct key terms to find what you need/want.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.object_name as EventName,o.description as EventDescription
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.object_name
			and o.package_guid = c.object_package_guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND c.object_name like '%flag%'
	Order By o.package_guid;</pre><p>Running that query will return just one result. You might find a few more if you expand your search criteria to include the term &#8220;flag&#8221; within the description field. It&#8217;s up to you to explore a bit more. As the description and name imply for this particular event, you can presume correctly that it tracks when a TF is either enabled or disabled (the state of the TF changes). Let&#8217;s call this a mini audit for a very targeted type of event.</p>
<p>Knowing the name of the event, let&#8217;s go ahead and look at a possible setup for an event session to trap data:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [TrackTFChange] ON SERVER 
ADD EVENT sqlserver.trace_flag_changed(
    ACTION (sqlserver.database_name,sqlserver.client_hostname,sqlserver.client_app_name,
            sqlserver.sql_text,
			sqlserver.session_id)
    WHERE sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense')
ADD TARGET package0.ring_buffer
WITH (MAX_DISPATCH_LATENCY=5SECONDS, TRACK_CAUSALITY=ON)
GO

ALTER EVENT SESSION TrackTFChange 
ON SERVER 
STATE = START;
GO</pre><p>This gets us to a point where we can now trap all changes to a trace flag status (enabled/disabled). At this point, a bit of a caution is that the event appears to fire twice for every time it occurs. There is one case where it will not produce a double result for each change. That case happens to be if the TF is already set to the same setting to which you are attempting to change it to. So if it is enabled, trying to enable it again just records one event to fire. However, trying to enable or disable the TF when it is in the opposite state, you will see two occurrences of the event firing. Here is a sample output to help show what happens.</p>
<p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/11/xe_results.png"><img loading="lazy" class="alignnone wp-image-1699" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/11/xe_results.png" alt="xe_results Trace Flag" width="1200" height="425" /></a></p>
<p>Displayed in the preceding image, you will notice both scenarios. In the scenario where the TF was not enabled, and I attempted to enable it, you will see two entries. And then when I disabled that TF after enabling it, I once again got a double entry. A corresponding example is encircled by the green. Now, when I tried to disable a TF that was not currently enabled, you see there is a single entry. That occurrence is marked via the orange circle.</p>
<p>A problem does present itself here with this result set and the use of XE.  How in the heck did I get the results from the XE Session so I could peruse it? Here is a sample script that will help parse this session data.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Query the XE */

SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
	,event_data.value('(event/@timestamp)[1]','varchar(max)') as timestamp
    ,event_data.value('(event/data[@name="flag"]/value)[1]', 'bigint') AS TraceFlag
	,event_data.value('(event/data[@name="type"]/text)[1]', 'varchar(max)') AS FlagType
	,case event_data.value('(event/data[@name="new_value"]/value)[1]','int') 
		When 0 then 'Enabled'
		When 1 then 'Disabled'
		END as NewValue
	,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	,event_data.value('(event/action[@name="database_name"]/value)[1]', 'varchar(max)') AS DBQueryExecutedFrom
	,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'varchar(max)') AS ClientHost
	,event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'varchar(max)') AS appname
	,event_data.value('(event/action[@name="session_id"]/value)[1]', 'varchar(max)') AS session_id
FROM(    SELECT evnt.query('.') AS event_data
        FROM
        (    SELECT CAST(target_data AS xml) AS TargetData
            FROM sys.dm_xe_sessions AS s
            INNER JOIN sys.dm_xe_session_targets AS t
                ON s.address = t.event_session_address
            WHERE s.name = 'TrackTFChange'
              AND t.target_name = 'ring_buffer'
        ) AS tab
        CROSS APPLY TargetData.nodes ('RingBufferTarget/event') AS split(evnt) 
    ) AS evts(event_data)
WHERE event_data.value('(event/@name)[1]', 'varchar(50)') = 'trace_flag_changed'
ORDER BY timestamp asc;</pre><p>Now isn&#8217;t that really helpful?</p>
<h3>Conclusion</h3>
<p>Today I covered three different means to help isolate the trace flags in use or the changes to the state of those trace flags. This is good information that <strong>any DBA should want to know</strong>. It is information to help get an understanding of the health and operating environment of your instance. It is also a means to help identify what might be changing under your nose!</p>
<p>For more uses of Extended Events, I recommend my series of articles designed to help you <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">learn XE little by little</a>.</p>
<p>Need a little help with extensive audits of your servers, check out <a href="http://jasonbrimhall.info/?s=audit">these articles</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2703" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/">Capture the Flag – The Trace Flag</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday 109: Influence Somebody Invite</title>
		<link>https://jasonbrimhall.info/2018/12/04/influence-somebody-invite/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=influence-somebody-invite</link>
					<comments>https://jasonbrimhall.info/2018/12/04/influence-somebody-invite/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 04 Dec 2018 12:42:36 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4633</guid>

					<description><![CDATA[<p>Building on the work of these three fine individuals, here comes the difficult task. You have been the benefactor of some awesome help from somebody else. You even wrote about it and in a way, told that person how they impacted you, your career, or both. You have set goals for yourself to become a better you after some personal reflection, meditation, introspection. Then you have given back to the community in some way.</p>
<p>I am not asking you to be braggy, just aware and cognizant. What have you done to impact somebody else in the last 13 months?</p>
The post <a href="https://jasonbrimhall.info/2018/12/04/influence-somebody-invite/">T-SQL Tuesday 109: Influence Somebody Invite</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>How have you impacted somebody in the community?</h2>
<p>It has now been 28 months since the last time I hosted a TSQL Tuesday, that was TSQL Tuesday 81. I <a href="http://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/">recapped that event here</a> with the <a href="http://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/">original invite here</a>. It continues to amaze me how quickly time flies and how easily years can blow by in between hosting this awesome party!</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png"><img loading="lazy" class="wp-image-4643 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png" alt="" width="247" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection.png 190w, https://jasonbrimhall.info/wp-content/uploads/2018/11/introspection-50x46.png 50w" sizes="(max-width: 247px) 85vw, 247px" /></a>The last time I hosted, I issued a difficult task. I dare say this one might be just a touch more difficult. First, I want to jump back into the time machine and visit a few of  TSQLTuesday topics that might be relevant to this month&#8217;s challenge.</p>
<p>In <a href="https://sqlonice.com/tsql-tuesday-96-folks-who-have-made-a-difference/">November 2017</a>, Ewald Cress (<a href="https://sqlonice.com/">b</a> | <a href="https://twitter.com/sqlOnIce">t</a>) invited everybody to talk about and basically give thanks to people that have helped impact their careers or lives. Check out the <a href="https://sqlonice.com/tsql-tuesday-96-round-up/">roundup here</a>.</p>
<p>In <a href="https://curiousaboutdata.com/2017/12/04/t-sql-tuesday-97-setting-learning-goals-for-2018/">December 2017</a>, Mala Mahadevan (<a href="https://curiousaboutdata.com/">b</a> | <a href="https://twitter.com/sqlmal">t</a>) invited everybody to set goals for themselves. These goals were supposed to be about learning. But when you get down to the nitty gritty, anything that helps build character and career really comes from something that must be learned. It all starts with a bit of introspection. It is this introspection that I ask you to use as a building block for the party this month.</p>
<p>Lastly, in <a href="https://scribnasium.com/2018/05/giving-back-t-sql-tuesday-102-invite/">May 2018</a>, Riley Major (<a href="https://scribnasium.com/">b</a> | <a href="https://twitter.com/RileyMajor">t</a>) asked everybody to reflect a bit on the theme from Ewald. This time though, the task was to give back to the community. Pay it forward, if you will, given that you had previously benefited from the kindness of somebody else.</p>
<h2 style="text-align: left;">Invitation</h2>
<p>Building on the work of these three fine individuals, here comes the difficult task. You have been the benefactor of some awesome help from somebody else. You even wrote about it and in a way, told that person how they impacted you, your career, or both. You have set goals for yourself to become a better you after some personal reflection, meditation, introspection. Then you have given back to the community in some way.</p>
<p>I am not asking you to be braggy, just aware and cognizant. What have you done to impact somebody else in the last 13 months?</p>
<p>How do you know you have impacted them? This is really the hard question. I want stories of how you impacted somebody else for the better. This may mean you will need to talk to some people and have a little retrospective with them.</p>
<h2>Why?</h2>
<p>This past year we lost some real juggernauts in the SQL Community such as Robert Davis (<a href="http://sqlsoldier.com/wp/" class="broken_link">blog</a>). We all know he impacted many people. We can also <em>assume</em> that he knew he impacted peoples lives. How great would it have been to sit down and have a personal discussion with him to let him know for certain how he impacted your career?</p>
<p>At PASS Summit, I had the opportunity to have such a discussion with somebody completely out of the blue. I know how much that meant to me. I also know that I was rather unaware of the influence I had on this individual.</p>
<h2>How?</h2>
<p>If you have not already had the opportunity to discuss your influence, make the opportunity. If you have mentored somebody, have a chat with them. If you work with somebody that you might have influenced, have a candid chat. Ask them directly if you have been able to be a good influence to them. Ask them how you might be able to better help them.</p>
<p>I know, this gets us all out of our comfort zones &#8211; but we need to do things like this. It is a method of both giving thanks as well as just giving (it is the season).</p>
<p>If you are reading this and don&#8217;t feel you have influenced somebody, then talk to somebody that has influenced you. Let them know how you influenced them.</p>
<p>Then, after having this candid chat, please write about both the experience (even the awkwardness), anything you learned from the conversation, as well as some details around what it is you did that impacted said individual.</p>
<p>Doing this little exercise will not only help you to become a more involved team member, community member, and leader it will also help you improve on some of the interpersonal skills used for networking as well as public speaking.</p>
<h3>What is T-SQL Tuesday?</h3>
<p><a href="http://tsqltuesday.com/"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" rel="noopener" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank" rel="noopener">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Steve Jones via the <a href="http://tsqltuesday.com/2018/07/05/request-to-host-t-sql-tuesday/" class="broken_link">tsqltuesday website &#8211; here</a>.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday, December 11e, 2018, and 00:00 GMT Wednesday December 12e, 2018.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank" rel="noopener">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4633" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/12/04/influence-somebody-invite/">T-SQL Tuesday 109: Influence Somebody Invite</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/12/04/influence-somebody-invite/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>My Book Contributions</title>
		<link>https://jasonbrimhall.info/2018/11/30/my-book-contributions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=my-book-contributions</link>
					<comments>https://jasonbrimhall.info/2018/11/30/my-book-contributions/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 30 Nov 2018 13:09:27 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4708</guid>

					<description><![CDATA[<p>One of the really super cool things about the SQL community is the frequent opportunity one could have to get involved.</p>
<p>One of my favorite methods of getting involved is the varied ways to participate on a book project.</p>
The post <a href="https://jasonbrimhall.info/2018/11/30/my-book-contributions/">My Book Contributions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>It&#8217;s a Wonderful Life</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_books2.png"><img loading="lazy" class="wp-image-4711 size-full alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_books2.png" alt="" width="144" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/db_books2.png 144w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_books2-37x50.png 37w" sizes="(max-width: 144px) 85vw, 144px" /></a>One of the really super cool things about the SQL community is the frequent opportunity one could have to get involved.</p>
<p>One of my favorite methods of getting involved is the varied ways to participate on a book project. To be involved in a book project does not require that one be an author. One can be a contributor, technical editor, technical consultant, author, or even provide technical reviews after the book is ready for publication.</p>
<p>Each method does come with some sort of invite from either the principle author or the publisher.</p>
<p>I have had a number of various opportunities to be involved with a book. As one ages, it becomes a little more difficult to remember all of the contributions so I just wanted to bring it all together in a single place to help me remember.</p>
<h3>Author</h3>
<p><a href="https://www.amazon.com/gp/product/1430242000/ref=dbs_a_def_rwt_bibl_vppi_i0">SQL Server 2012 T-SQL Recipes</a>. This book came out in 2012 and I had a few people helping me with this first book. I enjoyed this experience even with the difficulties of learning the whole publication process and just getting through the massive job that it was.</p>
<p><a href="https://www.johnsansom.com/dba-jumpstart/">DBA Jumpstart</a>.  This was a community effort headed up by John Sansom in 2013. You can check out my contribution <a href="http://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/">here</a>.</p>
<p><a href="https://www.amazon.com/gp/product/1484200624/ref=dbs_a_def_rwt_bibl_vppi_i1">SQL Server T-SQL Recipes</a>. This book was released for SQL Server 2014 in 2015. Yeah it came a little late and that is because we had a bit of a late start. This was a follow up edition of the recipes book, only this time with a much smaller bunch of authors.</p>
<h3>Consultant</h3>
<p><a href="https://www.amazon.com/gp/product/B01FGMZEOI/ref=dbs_a_def_rwt_bibl_vppi_i1">Healthy SQL</a>. This book was released in 2015. I helped Robert get it started and helped him get it across the finish line. This kind of effort included discussions about topics, scripts, and technical edits. If not for time, I was supposed to do a chapter or two and just got too busy to help as an author.</p>
<h3>Technical Editor</h3>
<p><a href="https://www.amazon.com/gp/product/B00ACC6B8G/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i2">SQL Server 2012 Data Integration Recipes</a>.  I came fresh off the writing of the T-SQL recipes book in 2012 to immediately plunge into tech editing this book. Tech editor is a pretty good way to get involved because you are immersed in the publication process and you get to validate the content before printing.</p>
<h3>Contributor</h3>
<p>This is kind of a weird category. Each of the books here has a section from me. So in a sense it is kind of like a small author contribution.</p>
<p><a href="https://www.amazon.com/Data-Professionals-Work-Malathi-Mahadevan-ebook/dp/B07FY6HCZM/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1543446065&amp;sr=1-1">Data Professionals at Work</a>. This book was released in 2018 and is a compilation from several Microsoft MVPs about their personal experiences. I wrote a review about the book <a href="http://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/">here</a>.</p>
<p><a href="https://www.amazon.com/gp/product/B07K5NKRQK/ref=dbs_a_def_rwt_bibl_vppi_i0">How to be an MVP in Life</a>. This book was also published in 2018. This book is another group of MVPs from tech and sport discussing various qualities of an MVP. You can read more of what I said about the book <a href="http://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/">here</a>.</p>
<h3>Technical Reviewer</h3>
<p>This type of participation comes after publication when a publisher asks for your assistance with a technical review.</p>
<p><a href="https://www.red-gate.com/library/sql-server-transaction-log-management">SQL Server Transaction Log Management</a>. This book came out in 2013 and was a project by a close friend &#8211; Gail Shaw. I do recommend this book to anybody who is working on SQL Server. You can read my review <a href="http://jasonbrimhall.info/2013/10/07/transaction-log-management/">here</a>.</p>
<p><a href="https://www.red-gate.com/library/defensive-database-programming">Defensive Database Programming</a>. My first experience with publishers and books came back in 2010 when I was asked to review this book. There are ten articles in the series &#8211; starting with <a href="http://jasonbrimhall.info/2010/11/29/drumroll-please/">chapter 10 here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4708" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/30/my-book-contributions/">My Book Contributions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/30/my-book-contributions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Data Professionals at Work Book</title>
		<link>https://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=influence-somebody-invite-2</link>
					<comments>https://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 29 Nov 2018 13:51:11 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4661</guid>

					<description><![CDATA[<p>Not only will you encounter some interesting stories, but I believe you will also encounter some interesting insight into some of the contributors for this book: Data Professionals at Work.</p>
The post <a href="https://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/">Data Professionals at Work Book</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Working as a Data Professional</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionals.png"><img loading="lazy" class="wp-image-4668 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionals.png" alt="" width="273" height="181" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionals.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionals-50x33.png 50w" sizes="(max-width: 273px) 85vw, 273px" /></a></p>
<p>An old friend Malathi Mahadevan (<a href="https://curiousaboutdata.com/">b</a> | <a href="https://twitter.com/sqlmal">t</a>) asked me one day if I would be interested in helping with her first book project. Anybody who has participated in the writing of a book knows this can be a rather daunting task &#8211; no matter the level of participation. Certainly, the principal author on a book has the grunt of the work, but there is plenty of work to be done for all.</p>
<p>I must say, I gladly accepted the opportunity. Firstly, this was a friend asking. Secondly, I liked the topic and method Mala had chosen. Lastly, I sometimes enjoy a little challenge. Ok, I probably enjoy challenges a little more than the average Joe.</p>
<h2 style="text-align: left;">Wowzas</h2>
<p>Mala was able to gather quite a stunning group of people together to bring this book to reality. Check out this list (hyperlinks take you to the individuals chapter at Safari): <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_1_Chapter.xhtml">Mindy Curnutt</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_2_Chapter.xhtml">Julie Smith</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_3_Chapter.xhtml">Kenneth Fisher</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_4_Chapter.xhtml">Andy Leonard</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_5_Chapter.xhtml">Jes Borland</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_6_Chapter.xhtml">Kevin Feasel</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_7_Chapter.xhtml">Ginger Grant</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_8_Chapter.xhtml">Vicky Harp</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_9_Chapter.xhtml">Kendra Little</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_10_Chapter.xhtml">Jason Brimhall</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_11_Chapter.xhtml">Tim Costello</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_12_Chapter.xhtml">Andy Mallon</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_13_Chapter.xhtml">Steph Locke</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_14_Chapter.xhtml">Jonathan Stewart</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_15_Chapter.xhtml">Joseph Sack</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_16_Chapter.xhtml">John Q. Martin</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_17_Chapter.xhtml">John Morehouse</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_18_Chapter.xhtml">Kathi Kellenberger</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_19_Chapter.xhtml">Argenis Fernandez</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_20_Chapter.xhtml">Kirsten Benzel</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_21_Chapter.xhtml">Tracy Boggiano</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_22_Chapter.xhtml">Dave Walden</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_23_Chapter.xhtml">Matt Gordon</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_24_Chapter.xhtml">Jimmy May</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_25_Chapter.xhtml">Drew Furgiuele</a>, <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_26_Chapter.xhtml">Marlon Ribunal</a>, Kevin Kline and <a href="https://www.oreilly.com/library/view/data-professionals-at/9781484239674/html/463664_1_En_27_Chapter.xhtml">Joseph Fleming</a>.</p>
<p>Kevin Kline out of that bunch contributed the foreword. If you follow the links, you will notice that the authors appear in order of their chapters.</p>
<p>All of these authors came together to share experiences and insights into the world of a data professional. None of the stories are the same. None of the experiences are the same (not on the micro level anyway). That said, all of the stories do bring the reader an opportunity to learn from the people that have been there and experienced some cool stuff in their careers.</p>
<p><img loading="lazy" class="alignright wp-image-4669" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionalsbook.jpg" alt="" width="220" height="333" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionalsbook.jpg 330w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionalsbook-198x300.jpg 198w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dataprofessionalsbook-33x50.jpg 33w" sizes="(max-width: 220px) 85vw, 220px" /></p>
<p>Not only will you encounter some interesting stories, but I believe you will also encounter some interesting insight into some of the contributors. Each person unravels a little bit of their own unique personality while trying to share their passion and love for this field we all excel at (at least sometimes).</p>
<p>If you read closely enough, you might even find a steamy romance hidden between the covers of the book. Then again, maybe that can only be found on a <a href="https://littlekendra.com/2018/10/01/i-helped-write-a-book-no-not-those-books/">Little blog</a>.</p>
<p>Oh, did you know you can also reach each of the authors on twitter? <a href="https://twitter.com/Kendra_Little/lists/data-pros-at-work/members">Check out this list here</a>! Missing from the list is Kevin Kline, but you can find him on twitter <a href="https://twitter.com/kekline">here</a>.</p>
<p>&nbsp;</p>
<h3>Go Get the Book!</h3>
<p>With so much great stuff to learn from so many awesome people, you must be asking where you can find the book?</p>
<p>That&#8217;s easy! Head on over to <a href="https://www.amazon.com/Data-Professionals-Work-Malathi-Mahadevan-ebook/dp/B07FY6HCZM/ref=sr_1_1?s=digital-text&amp;ie=UTF8&amp;qid=1543358891&amp;sr=1-1">Amazon</a> and snag the book (in ebook or paper formats) now! Even with sooo many people contributing to this book, it is a rather short read, coming in at just under 400 pages. It&#8217;s also lightweight enough, it could be easily carried around during the lunch break or to and from work.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4661" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/">Data Professionals at Work Book</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/29/influence-somebody-invite-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to be an MVP Book</title>
		<link>https://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-be-an-mvp-book</link>
					<comments>https://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 28 Nov 2018 14:03:33 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4662</guid>

					<description><![CDATA[<p>When it comes to characteristics of an MVP, the two groups (geek and jock) are no longer at the opposite ends of the spectrum. Rather, they are very similar in nature which makes this such a great tool to help relate to many teams of different types. Business leaders, youth leaders, coaches, and the it crowd can all benefit from reading this book.</p>
The post <a href="https://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/">How to be an MVP Book</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>How to be an MVP in LIFE</h2>
<p><a href="https://www.amazon.com/dp/B07K5NKRQK"><img loading="lazy" class="alignright wp-image-4663" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/mvpbook.jpg" alt="" width="214" height="319" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/mvpbook.jpg 335w, https://jasonbrimhall.info/wp-content/uploads/2018/11/mvpbook-201x300.jpg 201w, https://jasonbrimhall.info/wp-content/uploads/2018/11/mvpbook-34x50.jpg 34w" sizes="(max-width: 214px) 85vw, 214px" /></a>One of the fun things about being involved in the community is the opportunity to meet new people. Sometimes, meeting new people leads to new opportunities. Most of the time, those meetings turn into friendships of varying degrees.</p>
<p>One person I met at an event is David Lundell (<a href="https://www.davidplundell.com/">b</a> | <a href="https://twitter.com/DavidLundell">t</a>). We had an opportunity to sit down and get to know each other just a little bit. Then we ran into each other at a few more events &#8211; funny how that happens. We have a lot in common such as our mindset toward community and being involved in many different ways (coaching sports, scouting, speakings, writing, tech, MVP etc).</p>
<p>After meeting David, I had the opportunity to participate in one of his projects. David was looking to write a book about the MVP mindset and character. Well, the book is now finished! You can find this book on <a href="https://www.amazon.com/dp/B07K5NKRQK">Amazon &#8211; here</a>!</p>
<p>David put a lot of work and effort into this book. Not only does he interview Microsoft MVPs, but there is also an interview with the 2016 World Series MVP <a href="http://www.espn.com/mlb/player/_/id/28536/ben-zobrist">Ben Zobrist. </a>He strives, in this book, to illustrate the MVP character and how that character is something that helps to build up a team. An MVP may receive a lot of recognition, but usually that recognition also includes higher achievement for the team and more recognition for the team overall.</p>
<p>This book will help you learn how to elevate yourself and your team as you uncover some of the traits related to those MVPs in life, sports, or even work. This book is not just about how to be an MVP for Microsoft, but rather how to elevate yourself or your team to a higher standard in life. Check it out and bring a whole new attitude to how you balance your life and efforts.</p>
<h3>Just for techies right?</h3>
<p>While the book is predominantly comprised of experiences and interviews from Microsoft MVPs, don&#8217;t be fooled into thinking this is a tech book or that it is just for the IT crowd. This book also contains stories and interviews from sports MVPs as well.</p>
<p>Combining the geek crowd and the sports crowd into one book that can relate to all is quite a feat. Those two groups are at pretty disparate ends of the spectrum if you recall your school days at all.</p>
<p>When it comes to characteristics of an MVP, the two groups (geek and jock) are no longer at the opposite ends of the spectrum. Rather, they are very similar in nature which makes this such a great tool to help relate to many teams of different types. Business leaders, youth leaders, coaches, and the it crowd can all benefit from reading this book. The book is just under 200 pages and is available in e-book format on <a href="https://www.amazon.com/dp/B07K5NKRQK">Amazon</a> right now!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4662" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/">How to be an MVP Book</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/28/how-to-be-an-mvp-book/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Auditing when Database Files Change</title>
		<link>https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=auditing-when-database-files-change</link>
					<comments>https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 27 Nov 2018 13:59:08 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2706</guid>

					<description><![CDATA[<p>As a Database Administrator, something that should be part of your database audit is monitoring the growth of files. That means tracking when the log file grows and tracking when the data file(s) grow(s).</p>
The post <a href="https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/">Auditing when Database Files Change</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As a Database Administrator, something that should be part of your database audit is monitoring the growth of files. That means tracking when the log file grows and tracking when the data file(s) grow(s). Many will argue that there is nothing worse than not knowing when a database-related file changed in size except maybe when it rapidly and constantly grows until the disk is filled.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png"><img loading="lazy" class="aligncenter wp-image-2585" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png" alt="" width="375" height="274" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png 537w, https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange-300x218.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange-50x36.png 50w" sizes="(max-width: 375px) 85vw, 375px" /></a>Beyond just trapping when these events occur, the DBA usually also wants to know what caused the file to grow or shrink. This has been a problem that has plagued many a DBA over time. Sure there are plenty of methods to assist in the capture of such things. I even wrote about that quite some time ago <a href="http://www.sqlservercentral.com/articles/Log+growth/69476/">here</a>. In that article, I gave the tools to help track when a transaction log grew. <strong>Today</strong>, I am looking to share a different method on how to trap the executing SQL that causes a file to grow. And unlike that previous method, this method will also help to track when a file <strong>decreases</strong> in size.</p>
<p>I do want to point out that there is an alternate method to capture the shrink events if you wish to read more. I wrote previously about using the default trace to capture when a shrink occurs within the instance. This can be captured thanks to the default trace. You can read all about that over <a href="http://bit.ly/19eAcUW">here</a>. Despite the availability of the information within the default trace, I think the method I share here will be lightweight enough that it won&#8217;t hurt to have it running—at least occasionally.</p>
<h3>Enter the Database Audit</h3>
<p>If you have become accustomed to reading my articles, you will probably surmise that there is some degree of setup that needs to be done before I get to the meat of the matter. That holds true today. It just wouldn&#8217;t be right to share a method to do something without a harness to show how to get there. So, let&#8217;s get the setup out of the way.</p><pre class="urvanov-syntax-highlighter-plain-tag">Use master;
Go
IF DB_ID('Sandbox2') IS NULL 
BEGIN
	EXECUTE ('CREATE DATABASE Sandbox2');
END
GO

/*We Need The database ID of the newly created Sandbox2 Database - just file it away */
SELECT db_id('Sandbox2') as DatabaseID</pre><p>Since we will be wanting to create something that will track when a file changes in size, we will need to have a baseline of the size of the files for the newly created Sandbox2 database. Let&#8217;s capture that with the following query. <strong>Small note on this query</strong> is that I am including the tempdb related file sizes. You don&#8217;t need to include that, but it may be of interest for future testing.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DB_NAME(database_id) AS DBName,name AS FileName,size/124.0 AS size_mb
	FROM master.sys.master_files
	WHERE database_id in (2, DB_ID('Sandbox2'));</pre><p>That is all the setup that is needed at this point. We are now ready to implement a tool that can help us monitor these changes. This tool is lightweight and pretty efficient at capturing the info that would be essential for the exceptional DBA to keep on top of the changes occurring in his/her environment. This tool comes to us in the form of an extended event. Let&#8217;s do a little checking into what is available before we dive into the actual XE session itself.</p>
<p>First, when you are curious, if there is an extended event that may be sufficient for your needs, you should check the event store to see what is there. We can do that via a query similar to the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.object_name as EventName,p.name as PackageName,o.description as EventDescription
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.object_name
			and o.package_guid = c.object_package_guid
		INNER JOIN sys.dm_xe_packages p
			on o.package_guid = p.guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND (c.object_name like '%file_size%'
			or c.object_name like '%growth%')
	Order By o.package_guid;</pre><p>This query may return something along the lines of what we see in the following image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8.png"><img loading="lazy" class="aligncenter size-large wp-image-5447" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8-1024x139.png" alt="" width="560" height="76" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8-300x41.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8-768x104.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_events_2k8-50x7.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From that list, we can immediately see that we have some options to help us try and capture what is happening with our databases when our back is turned. From here, we can query to find what kind of data is captured with each of these events. To do that, we simply need to run a query such as the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Let's take a look at the columns available for each of the events picked out
*/

SELECT * FROM sys.dm_xe_object_columns
WHERE object_name = 'databases_data_file_size_changed'
AND column_type != 'readonly';

SELECT * FROM sys.dm_xe_object_columns
WHERE object_name = 'databases_log_file_size_changed'
AND column_type != 'readonly';

SELECT * FROM sys.dm_xe_object_columns
WHERE object_name = 'databases_log_growth'
AND column_type != 'readonly';</pre><p>Looking at the available data points in each of these sessions can prove promising. It is indeed promising enough that we can now proceed with the creation of an XE session.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [TrackDBFileChange] ON SERVER 
ADD EVENT sqlserver.databases_data_file_size_changed(
	ACTION(sqlserver.session_id,sqlserver.database_id,sqlserver.client_hostname,
            sqlserver.sql_text)
	)
,ADD EVENT sqlserver.databases_log_file_size_changed(
	ACTION(sqlserver.session_id,sqlserver.database_id,sqlserver.client_hostname,
            sqlserver.sql_text)
	)
ADD TARGET  package0.asynchronous_file_target(
     SET filename='C:\XE\DBFileSizeChange.xel',max_file_size = 5,max_rollover_files = 4
         ,metadatafile='C:\XE\DBFileSizeChange.xem') --if the path does not exist, a nasty error will be thrown
,
ADD TARGET package0.ring_buffer		-- Store events in the ring buffer target
	(SET max_memory = 4096)
WITH (MAX_MEMORY = 4MB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, TRACK_CAUSALITY = ON, MAX_DISPATCH_LATENCY = 1 SECONDS,startup_state = ON)
GO

ALTER EVENT SESSION TrackDBFileChange 
ON SERVER 
STATE = START;
GO</pre><p>I decided to just focus on the two events that included file_size_changed in the name of the event. You can also see that I chose to send this to two targets. You would be fine to just send this to an asynchronous file target. Just bear in mind that you do need to specify a path for the file_target that does exist or an error will be thrown. I have also specified that this session will restart on server startup and then I turned the session to the started state.</p>
<h3>Does it work?</h3>
<p>That is a really good question. Now that we have a test database and a session to trap events, all we need is to figure out how to test it. We would want to do a few different things to test—like grow and shrink a file in some way. And that is exactly what we are going to do at this point.</p>
<p>First test, since we have a really small empty database, is to try and force the database to grow by inserting some data. We will do that with this next query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT TOP 100000
        SomeID       = IDENTITY(INT,1,1),
        SomeInt      = ABS(CHECKSUM(NEWID()))%50000+1,
        SomeLetters2 = CHAR(ABS(CHECKSUM(NEWID()))%26+65)
                     + CHAR(ABS(CHECKSUM(NEWID()))%26+65),
        SomeMoney    = CAST(ABS(CHECKSUM(NEWID()))%10000 /100.0 AS MONEY),
        SomeDate     = CAST(RAND(CHECKSUM(NEWID()))*3653.0+36524.0 AS DATETIME),
        SomeHex12    = RIGHT(NEWID(),12)
		 ,TheBlob		= REPLICATE('Hey, Dracula!! Why do you say blah, blah blah?',10)
   INTO Sandbox2.dbo.millionrowtest
   FROM Master.dbo.SysColumns t1,
        Master.dbo.SysColumns t2
 
--drop table millionrowtest
GO


SELECT DB_NAME(database_id) AS DBName,name AS FileName,size/124.0 AS size_mb
	FROM master.sys.master_files
	WHERE database_id  in (2,DB_ID('Sandbox2'));</pre><p>I didn&#8217;t post the numbers earlier for my files for the Sandbox2 database, but they were small. I had a 2MB data file and a 1mb log file. Now, when I look at the results from that last query that included the file size information, I will see a database that has grown a fair amount.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/newfilesize.png"><img loading="lazy" class="aligncenter size-full wp-image-5448" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/newfilesize.png" alt="" width="499" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/newfilesize.png 499w, https://jasonbrimhall.info/wp-content/uploads/2018/11/newfilesize-300x123.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/newfilesize-50x20.png 50w" sizes="(max-width: 499px) 85vw, 499px" /></a></p>
<p>That should be enough of a change to have triggered something in our extended event session. Let&#8217;s take a look at the session. To do that, I am going to pull out a query to help parse the XML and see what has happened. Here is that query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
	,event_data.value('(event/@timestamp)[1]','varchar(max)') as timestamp
    ,event_data.value('(event/data[@name="count"]/value)[1]', 'bigint') AS DbSizeChangeTo_KB
	,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	,db_name(event_data.value('(event/action[@name="database_id"]/value)[1]', 'int')) AS DBQueryExecutedFrom
	,db_name(event_data.value('(event/data[@name="database_id"]/value)[1]','int')) as AffectedDB
	,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'varchar(max)') AS ClientHost
	,event_data.value('(event/action[@name="session_id"]/value)[1]', 'varchar(max)') AS session_id
FROM(    
        SELECT CAST(event_data AS xml) AS TargetData
            FROM sys.fn_xe_file_target_read_file('C:\XE\DBFileSizeChange*.xel','C:\XE\DBFileSizeChange*.xem',NULL, NULL)
        
    ) AS evts(event_data)
WHERE event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_log_file_size_changed'
	or event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_data_file_size_changed'
	--or event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_log_growth'
ORDER BY timestamp asc;</pre><p>Despite having two targets in my session, we will only cover the query that helps parse the data from the asynchronous file target. When I run that query against the files that exist for this session I get a result set of 90 records on my system. That probably seems like a ton of results for such a small increase in the database. As it would happen, I left the growth settings at the default growth increments (don&#8217;t do that in a production system) and this means I get a ton of growth activities at very small numbers (1mb for the data file and 10% for the log file). Here is a sample of the output:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow.png"><img loading="lazy" class="aligncenter wp-image-5449 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow-1024x684.png" alt="" width="560" height="374" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow-300x200.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow-768x513.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_grow-50x33.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>You can see how this might be helpful for when a process runs hog wild in the environment. What about going in the other direction though? What if we need to know about when the database is shrunk or when a file is shrunk? Well, let&#8217;s do that too. Let&#8217;s try the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [Sandbox2]
GO
DBCC SHRINKFILE (N'Sandbox2' , 1)
GO

USE [Sandbox2]
GO
DBCC SHRINKFILE (N'Sandbox2_log' , 1)
GO

SELECT DB_NAME(database_id) AS DBName,name AS FileName,size/124.0 AS size_mb
	FROM master.sys.master_files
	WHERE database_id  in (2,DB_ID('Sandbox2'));

GO</pre><p>Again, I check for a baseline on the files to see if the file sizes changed. In this case, you can run that final query and compare or just trust me on it. Having shrunk both files in the Sandbox2 database, let&#8217;s check the XE session data again:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink.png"><img loading="lazy" class="aligncenter size-large wp-image-5450" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink-1024x191.png" alt="" width="560" height="104" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink-1024x191.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink-300x56.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink-768x143.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink-50x9.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_output_shrink.png 1559w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Check that out! We have captured the shrink events too! There are multiple shrink events in this case only because I ran the shrink statements multiple times. This is excellent news for everybody that is trying to keep an eye on these database size changes. You can see in the XE session that I applied the sql_text() action. I have done this so I will be able to see what query caused the growth or shrink event to occur. Even better news is that this event session is perfect for those of you still on SQL 2008.</p>
<p>If you enjoyed this article, check out some of the follow-up articles: <a href="http://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">Data Growth Audits</a> or <a href="http://jasonbrimhall.info/2016/04/12/awesome-sql-server-feature/">Mysterious Growth</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2706" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/">Auditing when Database Files Change</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Ghosts in your Database</title>
		<link>https://jasonbrimhall.info/2018/11/26/ghosts-in-your-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ghosts-in-your-database</link>
					<comments>https://jasonbrimhall.info/2018/11/26/ghosts-in-your-database/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 26 Nov 2018 13:51:58 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2701</guid>

					<description><![CDATA[<p>Yes Virginia, there are ghosts in your database.  More specifically, there are ghosts in your SQL Server database.  They are not there to haunt you.  They are not there just for this holiday season (speaking of Halloween Month).</p>
<p>How can there be ghosts in the database?</p>
<p>Why would there be ghosts in the database?</p>
<p>Do they happen because somebody issued a KILL statement?</p>
The post <a href="https://jasonbrimhall.info/2018/11/26/ghosts-in-your-database/">Ghosts in your Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Yes Virginia, there are ghosts in your database.  More specifically, there are ghosts in your <a href="http://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/"><img loading="lazy" class="alignright wp-image-4602" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_ghosts.png" alt="" width="185" height="184" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_ghosts.png 225w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_ghosts-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_ghosts-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_ghosts-65x65.png 65w" sizes="(max-width: 185px) 85vw, 185px" /></a>SQL Server database.  They are not there to haunt you.  They are not there just for this holiday season (speaking of Halloween Month).</p>
<p>How can there be ghosts in the database?</p>
<p>Why would there be ghosts in the database?</p>
<p>Do they happen because somebody issued a KILL statement?</p>
<p>Let&#8217;s address each of those in turn.   A database ghost record is (in a very basic form) one that&#8217;s just been deleted in an <em>index</em> on a table . Delete operations don&#8217;t actually physically remove records from pages – they only mark them as having been deleted (ghosted). Now why is it done this way?  The answer here is largely performance based.  This is a performance optimization that allows delete operations to complete more quickly. Additionally, it allows the rollback of delete operations to process more quickly.  The rollback processes faster because all that needs to happen is to &#8220;flip the flag&#8221; for the records as being deleted/ghosted, instead of having to reinsert the deleted records.  That may be a bit over-generalized, but I hope you get the gist.  In short, records are marked as &#8220;ghosted&#8221; when a delete operation is performed; and to rollback, you simply undo that mark.</p>
<p>Now, what about this KILL statement thing?  The kill statement is pure Halloween fun and does not create ghost records.</p>
<h3>Ghost Hunting</h3>
<p>Now that we have established the purpose of Ghosts in the database, how do you verify the existence of Ghosts?  In other words, what can we do to prove there really are spectral things in the database?  This is where the fun really begins.  First, we need to get out the equipment and tools (as any good ghost hunter would do) so we can capture these phantasms.  Let&#8217;s call the first tool the &#8220;trap&#8221;.  Here is what you will need for it.</p><pre class="urvanov-syntax-highlighter-plain-tag">Use master;
Go
IF DB_ID('Sandbox') IS NULL 
BEGIN
	EXECUTE ('CREATE DATABASE Sandbox');
	ALTER DATABASE [Sandbox] SET RECOVERY SIMPLE WITH NO_WAIT
	ALTER DATABASE [Sandbox] MODIFY FILE ( NAME = N'Sandbox', SIZE = 6144000KB , FILEGROWTH = 262144KB )
	ALTER DATABASE [Sandbox] MODIFY FILE ( NAME = N'Sandbox_log', SIZE = 131072KB , FILEGROWTH = 131072KB )
END
GO
Use Sandbox;
Go

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
IF SCHEMA_ID('Halloween') IS NULL EXECUTE ('CREATE SCHEMA Halloween');
GO

IF OBJECT_ID('Halloween.Ghosts','U') IS NOT NULL
BEGIN
DROP TABLE Halloween.Ghosts
END
GO


DECLARE @BeginDate DATE = '2014-10-01'
		,@EndDate DATE = '2014-10-31'

 SELECT TOP 1000000
        Pinky       = IDENTITY(INT,1,1),
        Blinky		= 'GHOST ITEM ' + CONVERT(VARCHAR(20),ISNULL('', 0)),
        CandyMan	= ABS(CHECKSUM(NEWID()))%50000+1,
        Sadako		= CHAR(ABS(CHECKSUM(NEWID()))%26+65)
                     + CHAR(ABS(CHECKSUM(NEWID()))%26+65),
        Slimer		= DATEADD(DAY,RAND(CHECKSUM(NEWID())) * ( 1 + DATEDIFF(DAY, @EndDate,@BeginDate) ), @EndDate),
        Poltergeist	= RIGHT(NEWID(),12),
        MalcomCrowe	= CAST(ABS(CHECKSUM(NEWID()))%10000 /100.0 AS MONEY),
        TheBlob		= REPLICATE('Hey, Dracula!! Why do you say blah, blah blah?',1000)
   INTO Halloween.Ghosts
   FROM Master.dbo.SysColumns t1,
        Master.dbo.SysColumns t2 --Lack of join criteria makes this a CROSS-JOIN

/* let's get our Blinky updated properly */
Update hg
	Set Blinky = 'GHOST ITEM ' + CONVERT(VARCHAR(20),ISNULL(Pinky, 0))
	From Halloween.Ghosts hg;

--===== A table is not properly formed unless a Primary Key has been assigned
     -- Takes about 1 second to execute.
  ALTER TABLE Halloween.Ghosts
        ADD PRIMARY KEY CLUSTERED (Pinky)

/* Make sure the soylent green blob is BIG */
--UPDATE Halloween.Ghosts
--	SET TheBlob = TheBlob + REPLICATE('Casper is not a real Poltergeist! Frankenstein hates being called Frankenmeanie.',15000);
--GO

/* additional index to show the ghosts */

Create NonClustered Index IX_GhostPinky on Halloween.Ghosts (Pinky)</pre><p>This trap, err database, can be a bit large.  As currently configured, we will need about 16GB of disk space to support it.  If that is too much, I recommend removing the last column &#8211; &#8220;TheBlob&#8221;.  As you can see, we are setting a rather large trap.  The table we create (Halloween.Ghosts) will receive One Million records.  This is most probably overkill to catch these ghosts, so you can also cut back on the number of records to be affected.</p>
<p>Now, to make sure we have some data and that we can use the table, let&#8217;s just run a little test query.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select top 100 *
	From Halloween.Ghosts</pre><p>Excellent, we have a good sample of data.</p>
<p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/datasample.png"><img loading="lazy" class="alignnone wp-image-1601 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/datasample.png" alt="database ghost records" width="630" height="414" /></a></p>
<p>At this point, it is important to note that we have done nothing that will cause database ghost records.  All that has been done is to set the framework so we can see the ghosts.  With the framework in place, let&#8217;s try to catch some ghosts.  To do so, we need to try to delete something.  Since we just happen to have had a clerical error in our database, we have 666 prime candidates to try and fix.  We happen to have several records that were supposed to be given a Slimer date of Halloween.  The clerk, being absent minded, thought that Halloween was supposed to be on Oct. 30.  Our business model dictates that the invalid records must be deleted first and then we can try to enter the replacement records.  So, let&#8217;s go ahead and try to remove those records.</p>
<p>Before we remove the records though, we need to discuss one important requirement for us to be able to see the ghosts.  Let&#8217;s call it spectral vision goggles.  In the database realm, we call it a trace flag.  In order to see the the ghosts on the pages, we need to enable TF 661.  We can do that with the following statement.  There is a serious side effect to this method too &#8211; it alters the behavior of the Ecto Containment Unit or automatic ghost cleanup process.  If you enable this, you will need to disable it later and/or manually run a ghost cleanup.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* tweak the ghost cleanup with an undocumented TF 
Required for DBCC Page results to show which pages have a GHOST entry
Don't try this at home - we are what you call experts (besides this is only a lab box!!) */
DBCC TRACEON (661, -1)
GO</pre><p>Now that we have the last piece of equipment in place, let&#8217;s go ahead and try to delete some records.</p><pre class="urvanov-syntax-highlighter-plain-tag">Delete top(666)
	From Halloween.Ghosts
	WHERE Slimer = '10/30/2014';</pre><p>With all of those records deleted (all 666 of them), let&#8217;s see what we might have captured.  First, let&#8217;s take a look at some index stats.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* ghost_record_count */
Set transaction Isolation level read uncommitted
SELECT DB_NAME(database_id) AS DBName,schema_name(so.schema_id) + '.' + so.name as ObjName, record_count,index_type_desc
	,ghost_record_count,version_ghost_record_count
FROM sys.dm_db_index_physical_stats(db_id('sandbox'), OBJECT_ID('Halloween.Ghosts'), NULL, NULL , 'DETAILED') ps
	INNER JOIN sys.objects so
		ON ps.object_id = so.object_id
WHERE index_level = 0
	;</pre><p>If we look at the output of this query, we will see that we did indeed attempt to delete 666 records.  Those records will now display in the ghost_record_count column.  We will also see that, since we had two indexes on the table, there are 666 ghost records marked on each index.</p>
<p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/idxstats_ghostcount.png"><img loading="lazy" class="alignnone wp-image-1602 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/idxstats_ghostcount.png" alt="idxstats_ghostcount" width="525" height="50" /></a></p>
<p>Very cool!  We are definitely on the track to capturing those ghosts.  We have a trail that they exist in the database.  Let&#8217;s keep going and see where we can see them.  You should note that there is an additional column in our result set that looks like it might be related to ghost records.  We are going to leave the discovery of version_ghost_record_count as a homework experiment for you to perform.  It is beyond the current scope of this article.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Use Fn_dblog to get Pages with Ghost Counts */
Select Operation,Context,[Transaction ID],[Page ID] AS [File:PageIDHex],AllocUnitId,[Slot ID],PartitionId
		,CONVERT(INT,CONVERT(VARBINARY,'0x' + RIGHT([Page ID], 8),1)) AS PageID
	From fn_dblog(null,null) fn
	Where CONTEXT = 'LCX_MARK_AS_GHOST';</pre><p>Now this is getting exciting.  We have stronger evidence in the log showing that these ghosts are hanging around in the database.  Not only are they hanging around in the database, we can see which pages in the database on which they are trying to hide.</p>
<p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/dblog_output.png"><img loading="lazy" class="alignnone wp-image-1603 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/dblog_output.png" alt="dblog_output" width="627" height="370" /></a></p>
<p>This is really solid information!  fn_dblog is giving us just about everything we need in order to get those ghosts.  It took a little bit of work since the log reports the page number in hex.  Converting that to an integer page number is essential for us to look at the page (besides integer values are easier to interpret for most people).  Now I can take that PageID and pass that number, for any of the records reported by fn_dblog, and pass it into yet another undocumented procedure known as DBCC Page.</p>
<p>When looking to use DBCC page, we can either look at the PFS Page and see more pages that have ghost record counts.  Or we can take the results seen from the fn_dblog output  and then look at the contents of the page and catch those ghosts.  We will take a quick look at the PFS page first.  Then we will take a look at an index page next.  In this database that we have created, the PFS page will show several other pages that have ghost records on them.  Due to the size (over 2 million pages), we only see index pages with ghost records in that result.  If our database were smaller, we would quite possibly see data pages in our first PFS page of the database.  Let&#8217;s see a sample from the first PFS in this database.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC PAGE('Sandbox',1,1,3) WITH TABLERESULTS
GO</pre><p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghost_displayedonpageduetotf.png"><img loading="lazy" class="alignnone wp-image-1604 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghost_displayedonpageduetotf.png" alt="ghost_displayedonpageduetotf" width="670" height="95" /></a></p>
<p>We can follow that link from this point to page 126.  Page 126 happens to be an index page similar to the following.  There are a couple of indicators that this is an index page.  First being that when we run DBCC Page with a format of 3, we will see two result sets.  The second result set will show statistics and index information.  The second being in the image attached after the query.  We will leave it as an exercise to you to see other ways to demonstrate that this is an index page.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC PAGE('Sandbox',1,126,3) WITH TABLERESULTS
GO</pre><p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghost_indexpage.png"><img loading="lazy" class="alignnone wp-image-1605 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghost_indexpage.png" alt="ghost_indexpage" width="641" height="155" /></a></p>
<p>That is great, but we have more ghosts to find.  Let&#8217;s look at a ghost on a data page.  Randomly picking a PageID from that list that was output from fn_dblog, let&#8217;s see what DBCC Page will provide to us.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC PAGE('Sandbox',1,1522936,3) WITH TABLERESULTS
GO</pre><p><a href="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghstcntondatapage.png"><img loading="lazy" class="alignnone wp-image-1606 size-full" src="http://www.sqlsolutionsgroup.com/wp-content/uploads/2014/10/ghstcntondatapage.png" alt="ghstcntondatapage" width="601" height="156" /></a></p>
<h3>Conclusion</h3>
<p>Well, isn&#8217;t that just cool!  We have trapped a bunch of ghosts and were even able to see them.  This has been a fantastic deep dive into the crypts of the database.  This is merely a scratch on the surface though.  We hope this will encourage you to explore a bit and at least try one of the homework assignments we left behind in this article.</p>
<p>With all of that, we have a bit of cleanup to do.  The cleanup comes in one of two methods.  Method one involves manual labor.  Method two involves our friendly little trace flag we already used.  Since most DBAs prefer the automated mechanisms over manual, let&#8217;s just discuss method two for now.  It is extremely effortless.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC TRACEOFF (661, -1)
GO</pre><p>That will put the system back to the way it was when we started (and of course we trust that nobody did this on their prod box).</p>
<p>This has been one of a few articles about ghosts in the database. You can check out some of the others <a href="http://bit.ly/rnnrGhosts2">here</a> and <a href="http://bit.ly/rnnrGhosts1">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2701" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/26/ghosts-in-your-database/">Ghosts in your Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/26/ghosts-in-your-database/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure Data Studio and XEvents</title>
		<link>https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=azure-data-studio-and-xevents</link>
					<comments>https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 21 Nov 2018 20:04:06 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[ADS]]></category>
		<category><![CDATA[Azure Data Studio]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4582</guid>

					<description><![CDATA[<p>Azure Data Studio (ADS) is getting all sorts of love and attention these days. So much so that they have finally gotten around to adding Extended Events (XE) to the tool - sort of. Now we have the power to run traces on SQL Server via ADS. </p>
The post <a href="https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/">Azure Data Studio and XEvents</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png"><img loading="lazy" class="wp-image-4545 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png" alt="" width="223" height="223" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield.png 256w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_shield-65x65.png 65w" sizes="(max-width: 223px) 85vw, 223px" /></a><a href="https://azure.microsoft.com/en-us/updates/azure-data-studio-is-now-available/">Azure Data Studio (ADS)</a> is getting all sorts of love and attention these days. So much so that they have finally gotten around to adding Extended Events (XE) to the tool &#8211; sort of. Now we have the power to run traces on SQL Server via ADS.</p>
<p>The presence of XE in ADS comes via an extension and comes with a few other caveats. I will explore the extension for XE available in ADS in this article and discuss some of the caveats. As you read the article, it might be helpful to go ahead and <a href="https://docs.microsoft.com/en-us/sql/azure-data-studio/download?view=sql-server-2017">download ADS</a> if you do not already have it.</p>
<h2>History</h2>
<p>Roughly 10 years ago Microsoft felt it necessary to introduce a cool tool called Extended Events. Soon after they decided deprecate the features called &#8220;Profiler&#8221; and &#8220;Trace&#8221;. Unfortunately the page with the deprecation announcement is no longer available, but some evidence of how long it has been <a href="https://stackoverflow.com/questions/16108586/sql-server-profiler-deprecation-replacement">deprecated is available here</a>.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated.png"><img loading="lazy" class="aligncenter size-full wp-image-4587" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated.png" alt="" width="967" height="557" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated.png 967w, https://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated-300x173.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated-768x442.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/profiler_deprecated-50x29.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>The <a href="https://www.sqlpassion.at/archive/2012/03/09/deprecated-features-in-the-sql-server-2012-database-engine/">deprecation announcement</a> remains in effect (and <a href="https://docs.microsoft.com/en-us/sql/database-engine/deprecated-database-engine-features-in-sql-server-2016?view=sql-server-2014">online</a>) for all versions since SQL Server 2012. It just may be difficult to find the 2012 announcement as we roll into newer releases of SQL Server.</p>
<p>Now, we have XE Profiler (or XEvent profiler depending on your release of SSMS &#8211; read more <a href="http://bit.ly/2BkPBGC">here</a>). Profiler is deprecated and now we have some confusion in SSMS as to what is Profiler since we are now using that term with the &#8220;XE Profiler&#8221; feature.</p>
<p>Now enter ADS. XE is not included with ADS by default. You have to install an extension to gain access to the feature. So, the first thing you will need to do is visit the extensions node and then search for &#8220;SQL Server Profiler&#8221;. I can hear you right now. It isn&#8217;t even using any part of the real feature name anymore &#8211; they are just calling it the same exact thing as the deprecated feature.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads.png"><img loading="lazy" class="aligncenter size-full wp-image-4590" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads.png" alt="" width="903" height="901" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads.png 903w, https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads-768x766.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/find_profiler_ads-65x65.png 65w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a>And yes, my heart breaks a little more every time I see &#8220;SQL Server Profiler&#8221;. We have been teaching Database Professionals for years to use Extended Events and not SQL Server Profiler. And they have been adopting that change in rather large numbers. This just seems like it will cause so much more confusion. Nevertheless, once you have selected the extension, look to the right hand side and you will see a screen similar to this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads.png"><img loading="lazy" class="aligncenter size-large wp-image-4591" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads-1024x327.png" alt="" width="560" height="179" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads-1024x327.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads-300x96.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads-768x245.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads-50x16.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/install_profiler_ads.png 1304w" sizes="(max-width: 560px) 85vw, 560px" /></a>After installing the extension and the reloading ADS we are ready to start using this extension. <span style="color: #ff0000;"><em><strong>For the remainder of this article, I will just refer to it as &#8220;XE extension&#8221;.</strong></em></span></p>
<h3>Where did it go?</h3>
<p>After the reload of ADS, finding the XE extension is not really that easy. If you read the info page where you clicked install, there is some info there on how to access it. In short, on a Windows machine Alt-P will be your friend. Where you use that key combination is not your friend though. If you are in a script for instance and hit that key combo, no connection will be made to your server &#8211; even if your script is connected.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected.png"><img loading="lazy" class="aligncenter size-large wp-image-4592" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected-1024x170.png" alt="" width="560" height="93" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected-1024x170.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected-300x50.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected-768x127.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ads_notconnected.png 1821w" sizes="(max-width: 560px) 85vw, 560px" /></a>In addition to that not-so-obvious message, there is a more obvious message box that pops up in the bottom right corner letting you know a connection could not be established. Unfortunately, the problem can&#8217;t be resolved from this screen. Just close the tab and try again from the instance connection as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/focus_instance_ads.png"><img loading="lazy" class="aligncenter size-full wp-image-4593" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/focus_instance_ads.png" alt="" width="698" height="518" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/focus_instance_ads.png 698w, https://jasonbrimhall.info/wp-content/uploads/2018/11/focus_instance_ads-300x223.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/focus_instance_ads-50x37.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>While a bit annoying, I can manage with that little caveat &#8211; just as long as I remember between uses what I did. After the XE extension is open, you should see a screen similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe.png"><img loading="lazy" class="aligncenter size-large wp-image-4594" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe-1024x795.png" alt="" width="560" height="435" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe-1024x795.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe-300x233.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe-768x596.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe-50x39.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/connected_xe.png 1834w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In the preceding picture, I show three indicators of a connection being established. The top right corner in the example is difficult to tell that there is a server name there but it is. In my example I am just using the shorthand notation to connect to my server or &#8220;.&#8221; (a dot) which connects me to the localhost instance.</p>
<p>The top left indicator is a drop down list of all XE sessions I have on the server.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/session_list.png"><img loading="lazy" class="aligncenter size-full wp-image-4595" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/session_list.png" alt="" width="695" height="796" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/session_list.png 695w, https://jasonbrimhall.info/wp-content/uploads/2018/11/session_list-262x300.png 262w, https://jasonbrimhall.info/wp-content/uploads/2018/11/session_list-44x50.png 44w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Beyond that, I don&#8217;t find it terribly useful. I can&#8217;t edit a session or script it from this tool yet.</p>
<p>Managing a session doesn&#8217;t appear to be possible at this point, so let&#8217;s try to create a new session and see what happens.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/new_session.png"><img loading="lazy" class="aligncenter size-large wp-image-4596" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/new_session-943x1024.png" alt="" width="560" height="608" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/new_session-943x1024.png 943w, https://jasonbrimhall.info/wp-content/uploads/2018/11/new_session-276x300.png 276w, https://jasonbrimhall.info/wp-content/uploads/2018/11/new_session-768x834.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/new_session-46x50.png 46w, https://jasonbrimhall.info/wp-content/uploads/2018/11/new_session.png 1319w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Sweet! The create session does something useful. I can create a new session. Unfortunately, all I can do is use one of three templates similar to the XE Profiler tool in SSMS. The full feature XE GUI tool has a much more complete list of templates and possibilities ever since SQL Server 2012. I <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">documented that in this article</a>.</p>
<p>Unfortunately, I have no use for the three default templates. So, for me, this tool drives me back to needing to use TSQL to create my sessions if I want to use ADS. Here is the big takeaway from that statement. The use of TSQL has been the biggest detractor for most Data Professionals when using XE. They want a full featured GUI. So, you are using ADS and must create an XE session, you will need to pull out your TSQL skills and probably need to pull down some of my <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">helper scripts</a> to get you going. The alternative would be to use SSMS where there is a full featured GUI that is more powerful than you might think.</p>
<h2>Conclusion</h2>
<p>There surely will continue to be more development around this idea of an XE style profiler. More development generally means that the product will mature and get better over time. This article shows how there is more being added to the feature to try and give you better control over the tool. We love control so the addition of these options is actually a good thing. Is it enough to sway me away from using the already established, more mature, and high performing tools that have been there for several generations? Nope! I will continue to use TSQL and the GUI tools available for XE that predated the XEvent Profiler.</p>
<p>Some say that data professionals really want the &#8220;Profiler&#8221; tool. In my opinion, that is certainly not the majority and now calling XE by the name &#8220;Profiler&#8221; is going to cause confusion at the least. Some say that maybe this tool needs to integrate a way to shred XML faster. To that, I say there are methods already available for that such as Powershell, the live data viewer, the Target Data viewer, or even my tools I have provided in the <a href="http://bit.ly/XE60Days">60 day series</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4582" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/">Azure Data Studio and XEvents</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How Long is That Event Taking</title>
		<link>https://jasonbrimhall.info/2018/11/20/how-long-is-that-event-taking/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-long-is-that-event-taking</link>
					<comments>https://jasonbrimhall.info/2018/11/20/how-long-is-that-event-taking/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Nov 2018 19:11:34 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4575</guid>

					<description><![CDATA[<p>Knowing just how long an event takes is a common requirement when troubleshooting. Sometimes, figuring out the unit of time is a bit troublesome. Is it milliseconds, seconds or microseconds?</p>
The post <a href="https://jasonbrimhall.info/2018/11/20/how-long-is-that-event-taking/">How Long is That Event Taking</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="253" height="253" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 253px) 85vw, 253px" /></a></p>
<p>Knowing just how long an event takes is a common requirement when troubleshooting. Sometimes, figuring out the unit of time is a bit troublesome. Is it milliseconds, seconds or microseconds?</p>
<p>It is really easy to mistakenly use milliseconds when microseconds is required. It is also really easy to forget that one event is measured in seconds while another might be measured in milliseconds. To add to the confusion, what if the unit of measure changes between one version of SQL Server and the next?</p>
<p>While none could think it should be easy and consistent to figure out time, sometimes it just takes a little more effort. The same unit of time just isn&#8217;t applicable for every type of event. That is not just true in SQL Server but in life in general. You wouldn&#8217;t want to use hours when timing muzzle velocity, but hours could be entirely applicable to a surgery or training seminar.</p>
<p>Where does that leave us SQL Geeks when looking at timing of internal events inside of SQL Server? Well, we either need to do a little digging or we could simply read the rest of this article to find a simple script that can do the bulk of the work for us.</p>
<p>When dealing with events inside of SQL Server, the tool of choice to use is <strong>Extended Events (XE)</strong>.<strong> </strong>If you are unfamiliar with XE, I really encourage you to take a look at <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">these resources</a> to become more familiar with the tool.</p>
<h2>Time</h2>
<p>None of us want to translate or interpret time incorrectly. Imagine the CIO looming over your shoulder asking how long before the database is back online. If you miscalculate the time and tell him 30 seconds when it really is 5 hours, the level of frustration and anger probably becomes exponentially worse.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock.png"><img loading="lazy" class="wp-image-4576 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock.png" alt="" width="166" height="165" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock.png 225w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_red_clock-65x65.png 65w" sizes="(max-width: 166px) 85vw, 166px" /></a>While that may seem like a bit of an exaggeration, it&#8217;s not an experience any DBA likes to encounter. On a slightly smaller scale, when a developer asks how long a piece of code is running in production, you do want to be as accurate as possible. If the code takes 5 minutes to execute, the developer needs to know it was 5 minutes and not a miscalculated 3.9 seconds. 3.9 seconds may be entirely within the realm of acceptable for the project and thus be dismissed by the development team.</p>
<p>While trapping the precise time and calculating it may seem trivial, it is important (as previously mentioned) to use the correct time unit. There are many events within XE that provide a time unit of measure. The unit of measure is different through most of the events so a different calculation may be required depending on what you are troubleshooting at the moment.</p>
<p>Thankfully, there is some means to figure out if the time measurement is in seconds, milliseconds, microseconds or something different. We just need to pull it all out from the metadata views. Here is how we get to that data.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ServerMajorVersion DECIMAL(4, 2)
SELECT @ServerMajorVersion = CONVERT(DECIMAL(4, 2), PARSENAME(dt.fqn, 4) + '.'
		+ PARSENAME(dt.fqn, 3))
	FROM ( SELECT CONVERT(VARCHAR(20), SERVERPROPERTY('ProductVersion'))
			) dt ( fqn );

SELECT CASE WHEN @ServerMajorVersion = 15.00 THEN 'SQL Server 2019'
			WHEN @ServerMajorVersion = 14.00 THEN 'SQL Server 2017'
			WHEN @ServerMajorVersion = 13.00 THEN 'SQL Server 2016'
			WHEN @ServerMajorVersion = 12.00 THEN 'SQL Server 2014'
			WHEN @ServerMajorVersion = 11.00 THEN 'SQL Server 2012'
		END AS SQLVer
	, @ServerMajorVersion AS SvrVersion
	, xp.name package_name
	, xo.name event_name
	, xoc.name event_field
	, DurationUnit = 
		CASE WHEN xoc.description LIKE '%milliseconds%' 
			THEN 'MilliSeconds'
			WHEN xoc.description LIKE '%microseconds%' 
			THEN 'MicroSeconds'
			WHEN xoc.description LIKE '%seconds%' 
			THEN 'Seconds'
			ELSE NULL
		END
	, xoc.type_name AS DataType
	, xoc.description AS DurationDesc
	, xo.description AS PayloadDesc
	, ch.Channel
	, ca.map_value AS SearchKeyword
FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_packages xp
			ON xo.package_guid = xp.guid
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.name = xoc.object_name
		OUTER APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = xoc.object_name) ca
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
							AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = xoc.object_name
			AND ch.PkgGuid = xoc.object_package_guid
WHERE xo.object_type = 'event'
	AND xoc.name = 'duration'
ORDER BY xp.name,xo.name;</pre><p>Holy crap! That doesn&#8217;t look easy. That is a ton more code than you might have expected. True. However, I like to have as much information as possible at my finger tips. In this case, I want to know the SQL Server version, <a href="http://jasonbrimhall.info/2015/09/09/extended-events-categories/">channels, and search terms (keywords)</a> related to the event.</p>
<p>Why have the extra data? When troubleshooting, it is nice to know if there are other events that might be related in nature that could shed a bit more light on the problem from a different angle. The use of keywords (think google search) and channels is perfect for helping me find those other events.</p>
<p>Here is what a snippet of that data might look like.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit.png"><img loading="lazy" class="aligncenter size-large wp-image-4577" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit-1024x539.png" alt="" width="560" height="295" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit-1024x539.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit-300x158.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit-768x404.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit-50x26.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/durationunit.png 1440w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>With this snippet, I can see there are multiple different units of measure but there are also multiple different keywords. These keywords can be essential to the troubleshooting process.</p>
<p>You will also see from that image that there are some events that don&#8217;t define the time unit very clearly. In fact it is just a null value for the description. That is a bit of a problem &#8211; but significantly less troublesome than not knowing the unit of measure for any of the events.</p>
<h2>Conclusion</h2>
<p>Figuring out the correct unit of time measurement can mean the difference between accurate troubleshooting or leaping down the wrong path. Figuring out the time units is made easier when you are able to query the metadata efficiently and have all of the pertinent details at your fingertips.</p>
<p>Extended Events is a powerful tool to help in troubleshooting and tuning your environment. I recommend investing a little time in reading the <a href="http://bit.ly/XE60Days">60 day series</a> about Extended Events. This is not a short series but is designed to provide an array of topics to help learn the tool over time. Don&#8217;t forget to go back and read the companion article showing how to <a href="http://bit.ly/2qISjlL">audit these events via the default trace</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4575" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/20/how-long-is-that-event-taking/">How Long is That Event Taking</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/20/how-long-is-that-event-taking/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PowerShell ISE Crashes</title>
		<link>https://jasonbrimhall.info/2018/11/19/powershell-ise-crashes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=powershell-ise-crashes</link>
					<comments>https://jasonbrimhall.info/2018/11/19/powershell-ise-crashes/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 19 Nov 2018 19:40:26 +0000</pubDate>
				<category><![CDATA[DatabaseMasters Syndication]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4568</guid>

					<description><![CDATA[<p>Working with PowerShell brings a lot of advantages and power to help manage a server. The more current your PoSh version, the more efficiently you will be able to manage your server. Sometimes getting to the current PoSh versions comes with a little pain such as ISE crashes.</p>
The post <a href="https://jasonbrimhall.info/2018/11/19/powershell-ise-crashes/">PowerShell ISE Crashes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p style="text-align: left;">Working with PowerShell brings a lot of advantages and power to help manage a server. The more current your PoSh version, the more efficiently you will be able to manage your server. Sometimes getting to the current PoSh versions comes with a little pain such as ISE crashes.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/ise_crash.png"><img loading="lazy" class="wp-image-4569 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/ise_crash.png" alt="" width="244" height="222" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/ise_crash.png 600w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ise_crash-300x272.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/ise_crash-50x45.png 50w" sizes="(max-width: 244px) 85vw, 244px" /></a></p>
<p style="text-align: left;">I recently had the mis-adventure of working through some ISE crashes after bringing some systems up to PoSh 5.1 that were either PoSh 2.0 or 3.0. It&#8217;s not a very fun situation to run a WMI update and then run into a crash of any type when testing if it worked. Your first thought is something terrible has happened.</p>
<p>As it stands, the problem is more of a nuisance than a critical failure. That said, it is enough of a problem that anyone who uses the ISE or .Net applications may experience a slight cardiac event.</p>
<h3>Fonts</h3>
<p>As you work to quickly recover from your missed heart beat, you start digging through logs and then hitting good old trusty google.</p>
<p style="text-align: left;">Diving through the logs, you might just happen across an error similar to the following:</p>
<blockquote><p><strong><em>Problem signature: Problem Event Name: PowerShell NameOfExe: PowerShell_ISE.exe FileVersionOfSystemManagementAutomation: 6.1.7600.16385 InnermostExceptionType: System.Xml.XmlException OutermostExceptionType: System.Reflection.TargetInvocation<br />
DeepestPowerShellFrame: indows.PowerShell.GuiExe.Internal.GPowerShell.Main DeepestFrame: indows.PowerShell.GuiExe.Internal.GPowerShell.Main ThreadName: unknown.</em></strong></p></blockquote>
<p>Maybe the first error you encounter might look like this one instead:</p>
<blockquote><p><em><strong>System.TypeInitializationException</strong></em></p>
<p><em><strong>“FileFormatException: No FontFamily element found in FontFamilyCollection </strong></em><br />
<em><strong>that matches current OS or greater: Win7SP1”.</strong></em></p>
<p><em><strong>Inner exception originates from: CompositeFontParser</strong></em></p></blockquote>
<p>Either way, the error shoots us back to the same fundamental problem. The ISE won&#8217;t load, you get an error message and you can&#8217;t confirm that the WMI patch was applied properly.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo.png"><img loading="lazy" class="wp-image-4572 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo.png" alt="" width="98" height="98" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo.png 500w, https://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/posh_book_logo-65x65.png 65w" sizes="(max-width: 98px) 85vw, 98px" /></a>As you work your fingers faster and faster through the pages on google, you discover that this problem is caused more explicitly by a <a href="https://support.microsoft.com/help/4055002">patch for the .Net framework</a> and not necessarily the work to upgrade your PoSh version. It only waited to manifest itself after the upgrade.</p>
<p>That&#8217;s gravy and all, but how does one fix the problem? For me, the quickest and most reliable fix was to simply jump straight to the root of the problem &#8211; fonts. The ISE is a WPF application and it also requires a fallback font (if a character isn&#8217;t present in your font set, then the app chooses a substitute from the fallback font &#8211; or something like that).</p>
<p>The fix is extremely simple and really underscores why this is merely a nuisance issue and not a critical problem. Thus it shouldn&#8217;t cause any sort of sinking internal feelings of any sort. There are a few plausible fixes floating around out there. I recommend just doing a manual font replacement. It is all but <span style="text-decoration: underline;"><strong>three</strong></span> simple steps:</p>
<ol>
<li>Download <a href="https://dotnetbinaries.blob.core.windows.net/kbassets/KB4074906/GlobalUserInterface.CompositeFont" rel="nofollow" class="broken_link">GlobalUserInterface.CompositeFont</a></li>
<li>XCOPY the font to <span style="color: #ff0000;">%windir%\Microsoft.NET\Framework\v4.0.30319\WPF\Fonts</span></li>
<li>XCOPY the font to <span style="color: #ff0000;">%windir%\Microsoft.NET\Framework64\v4.0.30319\WPF\Fonts</span></li>
</ol>
<p>After you have copied the font to those two directories, then all that is needed to be done is launch the ISE. I ran into the same problem on three or four servers and the fix took no more than 5 minutes on each of the servers.</p>
<h3>Conclusion</h3>
<p>I <a href="http://jasonbrimhall.info/2018/11/13/new-horizons-beyond-sql-server/">previously mentioned</a> that I have been working more and more with PoSh to try and improve my skillset there. This is one of those very low-level trinkets that I ran into as I have been working to hone my skills in that tech. For other, possibly, interesting articles about my experiences with PowerShell, you can check out <a href="http://jasonbrimhall.info/?s=powershell">these articles</a>.</p>
<p>Given this job is tightly related to the system_health black box sessions (sp_server_diagnostics and system_health xe session), I recommend fixing the job. In addition, I also recommend reading the following series about XE and some of those black box recorder sessions &#8211; <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4568" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/19/powershell-ise-crashes/">PowerShell ISE Crashes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/19/powershell-ise-crashes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Monitor Database Offline Events</title>
		<link>https://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=monitor-database-offline-events</link>
					<comments>https://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 15 Nov 2018 14:17:24 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4544</guid>

					<description><![CDATA[<p>Hopefully, a database being taken offline is a known event and not a surprise. Occasionally there are gremlins, in the form of users with too many permissions, that tend to do very strange things.</p>
The post <a href="https://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/">Monitor Database Offline Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png"><img loading="lazy" class="wp-image-4347 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png" alt="" width="253" height="253" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero-65x65.png 65w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_flysuperhero.png 1500w" sizes="(max-width: 253px) 85vw, 253px" /></a></p>
<p>The other day, I shared an article showing how to <a href="http://jasonbrimhall.info/2018/11/13/audit-database-offline-events/">audit database offline events via the default trace</a>. Today, I will show an easier method to both audit and monitor for offline events. What is the difference between audit and monitor? It largely depends on your implementation, but I generally consider an audit as something you do after the fact. Monitor is a little more proactive.</p>
<p>Hopefully, a database being taken offline is a known event and not a surprise. Occasionally there are gremlins, in the form of users with too many permissions, that tend to do very strange things to databases and database servers.</p>
<p>Having read the previous article, you already know one method to try and find these database offline anomalies. That method may not be the most sleek solution nor most reliable given the possibility that events can quickly roll out of your default trace files. The better more reliable method is use Extended Events (XE) to monitor explicitly for those types of events. If you are unfamiliar with XE, I really encourage you to take a look at <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">these resources</a> to become more familiar with the tool.</p>
<h2>Monitor</h2>
<p>Beyond the power of XE to be able to better diagnose problems and trace events in your server, there is the ability to monitor for specific events as well. I won&#8217;t go into details about how to monitor with XE until a later article, but suffice it say I can monitor for Events to occur and immediately alert necessary parties to get more immediate action. This is quite some power for a built in tool and it is better than event notifications or agent alerts when it comes to ease of use and reliability.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline_word.png"><img loading="lazy" class=" wp-image-4563 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline_word.png" alt="" width="209" height="66" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline_word.png 383w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline_word-300x95.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline_word-50x16.png 50w" sizes="(max-width: 209px) 85vw, 209px" /></a>As I look to monitor for these odd unplanned database offline events, I have several events within XE that can provide the requisite information: sqlserver.object_altered, sqlserver.database_started, sqlserver.database_stopped, and sqlserver.errorlog_written. I can hear you asking already &#8220;Wait, this seems to be a bit like a drill sergeant &#8211; very overbearing!&#8221;</p>
<p>Yes, it is probably a bit excessive for this session. However, I prefer to be comprehensive and the ability to link events together so I can better understand if it is a single one-off or if there is a bigger problem with the entire instance. Databases being stopped, started or set to offline should be rare and far between really. With that rarity in mind, the session should be relatively quiet.</p><pre class="urvanov-syntax-highlighter-plain-tag">IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'DBStateChange' )
	DROP EVENT SESSION DBStateChange 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION DBStateChange ON SERVER
ADD EVENT sqlserver.object_altered ( SET collect_database_name = ( 1 )
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,sqlserver.session_id ) 
	WHERE object_type = 'DATABASE' --16964
		AND (sql_text LIKE '%ONLINE%'
			OR sql_text LIKE '%OFFLINE%')
	),
ADD EVENT sqlserver.database_started(
ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,sqlserver.session_id ) 
	--WHERE object_type = 'DATABASE' --16964
	),
ADD EVENT sqlserver.database_stopped(
ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,sqlserver.session_id ) 
	--WHERE object_type = 'DATABASE' --16964
	),
ADD EVENT sqlserver.errorlog_written(
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,sqlserver.session_id ) 
	WHERE (sql_text LIKE '%ONLINE%'
			OR sql_text LIKE '%OFFLINE%'))
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\DBStateChange.xel' )
WITH (STARTUP_STATE = ON
	,TRACK_CAUSALITY = ON);

/* start the session */
ALTER EVENT SESSION DBStateChange 
ON SERVER 
STATE = START;
GO</pre><p>If I have that session running and then take a database online/offline or vise versa, I will see something very similar to this output.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange.png"><img loading="lazy" class="aligncenter size-large wp-image-4558" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange-1024x247.png" alt="" width="560" height="135" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange-1024x247.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange-300x72.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange-768x185.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/xe_dbstatechange-50x12.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>Starting from the bottom and working my way up, I can see that a command was issues to bring the <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f47b.png" alt="👻" class="wp-smiley" style="height: 1em; max-height: 1em;" />s database ONLINE. The very first thing that occurs is the request is written to the error log. Then I see that the database is in the stopped state. Next a message that the database is starting up (because it was stopped). Then we see two events for object_altered (similar to the default trace) due to the begin and commit phases of that transaction.</p>
<p>After that database was brought ONLINE, you can see that I immediately took <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f47b.png" alt="👻" class="wp-smiley" style="height: 1em; max-height: 1em;" />s back offline &#8211; starting with the errorlog event, then a stopped event and the object_altered begin and commit events.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline.png"><img loading="lazy" class="size-full wp-image-4561 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline.png" alt="" width="251" height="49" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline.png 251w, https://jasonbrimhall.info/wp-content/uploads/2018/11/db_offline-50x10.png 50w" sizes="(max-width: 251px) 85vw, 251px" /></a>Capturing each of the events I noted previously, not only gives me a complete picture of the event, it also can help me to identify if something happens in between the various &#8220;expected&#8221; events. If I use this session in my monitoring setup, then I can be quickly alerted to problems with a database as well as have the archive of the events to go back in time and AUDIT or troubleshoot the event of a database being offline or unable to come online.</p>
<p>With this XE Session running, I can be more confident that I have trapped and correlated the correct events in each of the sources. Using the default trace method, I have to make some highly likely correlations but there is still some &#8220;magic&#8221; involved. With the XE session, you will be far less likely to see any of those events roll out of the log as well. I can&#8217;t underscore the importance of that fact enough. <strong>The data will be there when you need it!</strong></p>
<h2>Conclusion</h2>
<p>We all aspire to having a perfect database environment where nothing surprising or unexpected happens. Unfortunately, that is the desire of dreams and fairy tales. The unexpected will happen. A database can unexpectedly be taken offline. Are you prepared to address the problem fully to the CTO should it happen? This XE session can help you with that.</p>
<p>Extended Events is a powerful tool to help in troubleshooting and tuning your environment. I recommend investing a little time in reading the <a href="http://bit.ly/XE60Days">60 day series</a> about Extended Events. This is not a short series but is designed to provide an array of topics to help learn the tool over time. Don&#8217;t forget to go back and read the companion article showing how to <a href="http://bit.ly/2qISjlL">audit these events via the default trace</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4544" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/">Monitor Database Offline Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/15/monitor-database-offline-events/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Refresh SQL Modules</title>
		<link>https://jasonbrimhall.info/2018/11/09/refresh-sql-modules/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=refresh-sql-modules</link>
					<comments>https://jasonbrimhall.info/2018/11/09/refresh-sql-modules/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 09 Nov 2018 13:52:26 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4519</guid>

					<description><![CDATA[<p>As is true in most facets of life, things tend to get stale and old. Sometimes this staleness can be visibly represented as the wrinkles on your face. Other times, as with SQL Server, it may mean that a stored procedure or view stops working.</p>
The post <a href="https://jasonbrimhall.info/2018/11/09/refresh-sql-modules/">Refresh SQL Modules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/elephant.png"><img loading="lazy" class="wp-image-4521 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/elephant-999x1024.png" alt="" width="263" height="270" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/elephant.png 999w, https://jasonbrimhall.info/wp-content/uploads/2018/11/elephant-293x300.png 293w, https://jasonbrimhall.info/wp-content/uploads/2018/11/elephant-768x787.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/elephant-50x50.png 50w" sizes="(max-width: 263px) 85vw, 263px" /></a>As is true in most facets of life, things tend to get stale and old. Sometimes this staleness can be visibly represented as the wrinkles on your face. Other times, as with SQL Server, it may mean that a stored procedure or view stops working.</p>
<p>Unfortunately, when it comes to SQL Server, the symptoms are not as readily visible as aging lines would be. In SQL Server, the symptoms may be as random and difficult to recognize as a stored procedure just suddenly stops working.</p>
<p>What makes this even more difficult is that the stored procedure (that is no longer working) may appear to be entirely unchanged. These failures can occur when other changes have occurred to the system as well as when no change has occurred. Imagine the joys you could experience while trying to troubleshoot this kind of problem.</p>
<p>If you were keen, you would probably implement any number of Extended Event Sessions to help troubleshoot the issue. If you are unfamiliar, you might want a refresher course on how to setup an XE session which you could read from one of these articles, <a href="http://bit.ly/1iy9srM">here</a> and <a href="http://bit.ly/1iA7M0N">here</a>.</p>
<p>If you are curious, there are <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">more XE articles on my blog &#8211; here</a>.</p>
<h2>Metadata</h2>
<p>There are many possible causes for the metadata to become fouled up inside the SQL modules on the database server. Invariably, according to the interested parties, nothing has changed in months! Right or wrong, there is still a problem to fix. Fortunately, the problem is easy enough to fix.</p>
<p>Sure, all of the modules could be re-deployed from source control. But, given that the modules don&#8217;t to appear to have lost any of the code within them, re-deploying code seems to be a bit of overkill. We don&#8217;t need to go that far. We can simply run sp_refreshsqlmodule for the stored modules (procs, triggers, functions, views etc). This would be pretty simple with the following script:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdventureWorks2014;
GO

SELECT o.name AS ObjName, sm.definition, o.type_desc
	,'EXECUTE sys.sp_refreshsqlmodule ''['+ SCHEMA_NAME(o.schema_id) + '].['  + o.name + ']'';' AS RefreshStmt
	, CASE	WHEN o.type IN ( 'TR','P', 'FN', 'FT', 'TF', 'PC', 'FS', 'AF', 'IF' )
				THEN 1
				WHEN o.type = 'V' THEN 2
				WHEN o.type IN ( 'F', 'D' ) THEN 3
				WHEN o.type = 'SO' THEN 4
				WHEN o.type = 'UQ' THEN 5
				WHEN o.type = 'PG' THEN 6
			END AS ProcessOrder
		FROM sys.all_sql_modules sm
		INNER JOIN sys.objects o
			ON sm.object_id = o.object_id
	ORDER BY ProcessOrder DESC,o.type_desc, o.name
		;</pre><p>In this script, I am just going to refresh all modules in the database (Adventureworks2014 in this case). I could modify the script to trim it down to a specific module or set of modules. Instead, I leave that as homework for you.</p>
<p>That said, I do have a slightly different alternative that looks for any tables changed on a specific date. After finding those changed tables, then I update all modules related to the changed table(s). Here is how that would look:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdventureWorks2014;
GO

DECLARE @ChangeDate DATE = '2014-07-17 16:11:39.583';

SELECT DISTINCT o.name AS ObjName, sm.definition, o.type_desc
	,'EXECUTE sys.sp_refreshsqlmodule ''['+ SCHEMA_NAME(o.schema_id) + '].['  + o.name + ']'';' AS RefreshStmt
	, CASE	WHEN o.type IN ( 'TR','P', 'FN', 'FT', 'TF', 'PC', 'FS', 'AF', 'IF' )
				THEN 1
				WHEN o.type = 'V' THEN 2
				WHEN o.type IN ( 'F', 'D' ) THEN 3
				WHEN o.type = 'SO' THEN 4
				WHEN o.type = 'UQ' THEN 5
				WHEN o.type = 'PG' THEN 6
			END AS ProcessOrder
	FROM sys.all_sql_modules sm
		INNER JOIN sys.objects o
			ON sm.object_id = o.object_id
		INNER JOIN sys.sql_expression_dependencies ed
			ON o.object_id = ed.referencing_id
	WHERE ed.referenced_id IN (
		SELECT object_id
			FROM sys.tables t
			WHERE CONVERT(DATE,t.modify_date) = @ChangeDate)
	ORDER BY ProcessOrder DESC,o.type_desc, o.name
		;</pre><p>From here, suppose you want to check for a range of dates where tables were modified. Again, I will leave that as homework for you.</p>
<p>After executing these scripts, I will have an output similar to the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output.jpg"><img loading="lazy" class="aligncenter wp-image-4527 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output-1024x123.jpg" alt="" width="560" height="67" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output-1024x123.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output-300x36.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output-768x92.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/refreshmodule_output-50x6.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This leaves you with one more step to perform &#8211; copy the values from the RefreshStmt column to a new query window and execute the statements.</p>
<h2>The Wrap</h2>
<p>In this article I showed a very simple solution to a problem that plagues some environments &#8211; out of date metadata. Forcing a module refresh will often resolve these types of issues.</p>
<p>With such a beautifully simple solution, I could have grouped this article into my &#8220;Back to Basics&#8221; series, but I did not. That said, there are some pretty interesting articles in the series including (but not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>. Check them out!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4519" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/09/refresh-sql-modules/">Refresh SQL Modules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/09/refresh-sql-modules/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Cannot Use the Special Principal &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/11/07/cannot-use-the-special-principal-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cannot-use-the-special-principal-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/11/07/cannot-use-the-special-principal-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 07 Nov 2018 14:14:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4509</guid>

					<description><![CDATA[<p>Cannot use the special principal 'dbo'. This error message can be misleading. This article will take you on a journey of common mis-steps along with the appropriate fix for this error.</p>
The post <a href="https://jasonbrimhall.info/2018/11/07/cannot-use-the-special-principal-back-to-basics/">Cannot Use the Special Principal – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png"><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>I recently had a client call me out of the blue because he happened to be getting an error while trying to add a user to a database role. The error he was getting was &#8220;Cannot use the special principal &#8216;dbo&#8217;.&#8221;</p>
<p>This error has probably cropped up on me more than a few times. And on more than a few occasions, I have forgotten about the previous experiences. Some of that is because the fix is rather easy and after a few times seeing it, muscle memory takes over and you just fix it without thinking about it too much.</p>
<p>Until you get to that muscle memory moment though, you may flounder a bit trying this and that and failing then proceeding on to a level of frustration that has you losing precious hair.</p>
<p>As luck would have it, this is an article about security and principals and is similar in nature to some other articles I wrote about some fundamental misconceptions about permissions <a href="http://jasonbrimhall.info/2017/03/02/sql-server-permissions-database-roles/">here</a> and <a href="http://bit.ly/2mMcYp2">here</a>.</p>
<p>I do hope that there is something you will be able to learn from this basics article. If you are curious, there are <a href="http://jasonbrimhall.info/tag/back-to-basics/">more basics articles on my blog &#8211; here</a>.</p>
<h2>Meet Prince Apole and Rolle&#8230;</h2>
<p>Adding a user to the db_datareader database fixed role is a pretty simple task. Most of us can likely do that in our sleep. Even using the GUI is usually pretty reliable to do that. Every now again though, somebody has decided to get tricky on us. Maybe a mistake was made somewhere in a setting on the server and nobody has caught it because nothing was &#8220;broken&#8221; &#8211; until it was.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/err15405.png"><img loading="lazy" class="aligncenter size-large wp-image-4511" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/err15405-1024x325.png" alt="" width="560" height="178" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/err15405-1024x325.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/err15405-300x95.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/err15405-768x244.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/err15405-50x16.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/err15405.png 1084w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In the aforementioned case, I was asked to help resolve the issue and I found that there was a problem in how the database owner was set. Not only was it a problem in the current database but in 12 other databases on the same server. The systems admin was at wits end. He was dealing with something that was just not in his knowledge-base yet. I remember being in the same boat &#8211; so no big deal there. We talked about some of the things he had tried and how none of it was working. I am going to recreate the same basic scenario along with some of the attempted fixes in this article.</p>
<p>First, we need to create a database (best to break a database designed to be broken instead of an existing one used for something else already).</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE DATABASE [DummyDB]
GO
USE [master]
GO
ALTER DATABASE [DummyDB] SET RECOVERY SIMPLE WITH NO_WAIT
GO

USE [master]
GO
CREATE LOGIN [mydomain\svc_dummy] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
GO</pre><p>That is pretty straight forward &#8211; the database will be created with the data files in the default directories on your SQL Server instance. In addition, a login called mydomain\svc_dummy will be created as a windows login.</p>
<p>Now let&#8217;s try to set the owner of the database and then add the svc_dummy account to the datareader role.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [DummyDB]
GO
/*set db owner to the dummy account */
ALTER AUTHORIZATION ON DATABASE::[DummyDB] TO [saeopssql01\svc_dummy]
GO

USE [DummyDB]
GO
ALTER ROLE [db_datareader] ADD MEMBER [dbo]
GO</pre><p>There is a point of interest here. I said I was going to add svc_dummy to the datareader role &#8211; not dbo. Well, I set the database owner in the preceding step to svc_dummy so it basically became dbo. When I try to perform the role addition in the GUI and then script the change, this is the script that is produced. I will show why in a few moments.</p>
<p>The execution of the second part of the script results in the following:</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15405, Level 16, State 1, Line 18</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Cannot use the special principal &#8216;dbo&#8217;.</span></p>
</blockquote>
<p>That is obviously not going to work. Let&#8217;s try fixing the script and add the svc_dummy principal instead of dbo.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [DummyDB]
GO
ALTER ROLE [db_datareader] ADD MEMBER [mydomain\svc_dummy]
GO</pre><p>Unfortunately, this results in the following:</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15151, Level 16, State 1, Line 22</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Cannot add the principal &#8216;mydomain\svc_dummy&#8217;, because it does not exist or you do not have permission.</span></p>
</blockquote>
<p>Well, maybe the problem is because the user doesn&#8217;t exist then? Let&#8217;s try to create the user and see what happens.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [DummyDB]
GO
CREATE USER [mydomain\svc_dummy] FOR LOGIN [mydomain\svc_dummy]
GO</pre><p>Now we should see this message:</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15063, Level 16, State 1, Line 32</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">The login already has an account under a different user name.</span></p>
</blockquote>
<p>Oy vey. We seem to be going in circles. Nothing is working. The user is there but not really there. Let&#8217;s try to drop the user and just try to clean things up and start over.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [DummyDB]
GO
/* GUI Generated - the user dbo is mapped to the dummy login */
DROP USER [dbo]
GO</pre><p>I hope you see the problem with this one. Trying to drop dbo. I dunno but we should see an error here &#8211; and we do get an error.</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15150, Level 16, State 1, Line 27</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Cannot drop the user &#8216;dbo&#8217;.</span></p>
</blockquote>
<p>Let&#8217;s fix the user then and try to drop the svc_dummy user instead of dbo.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [DummyDB]
GO
/* let's fix it to the correct user */
DROP USER [mydomain\svc_dummy]
GO</pre><p>Which in turn generates yet another error.</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15151, Level 16, State 1, Line 52</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Cannot drop the user &#8216;mydomain\svc_dummy&#8217;, because it does not exist or you do not have permission.</span></p>
</blockquote>
<p>If I can&#8217;t resolve the problem by changing the user in the database, maybe I can just blow it out of the water by dropping the server login.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [master]
GO
DROP LOGIN [mydomain\svc_dummy]
GO</pre><p>Yet another failure message will ensue. This time the message is:</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Msg 15174, Level 16, State 1, Line 55</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Login &#8216;mydomain\svc_dummy&#8217; owns one or more database(s). Change the owner of the database(s) before dropping the login.</span></p>
</blockquote>
<p>So far we have been able to skirt around the problem and generate six different error messages. The last one kind of gives us the best information on what we could do to resolve the issue. The login owns a database and therefore, we need to undo that ownership. Before we do that, let&#8217;s take a look at the database principal &#8216;dbo&#8217;.</p>
<p>We already know that svc_dummy is mapped to a user in the DummyDB database. We also know that we cannot add the svc_dummy user because of that prior mapping. We have also learned that when scripting the permissions change from the gui on the svc_dummy login and then generate the script it scripts out the user &#8216;dbo&#8217;. Due to this, let&#8217;s look in the sys.database_principals view at the dbo user and see what it tells us.</p><pre class="urvanov-syntax-highlighter-plain-tag">select dp.name, dp.type_desc, dp.owning_principal_id, dp.authentication_type_desc
	From sys.database_principals dp
where name = 'dbo';</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select.png"><img loading="lazy" class="aligncenter size-large wp-image-4515" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select.png" alt="" width="560" height="96" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select.png 802w, https://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select-300x52.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select-768x132.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/basic_dbprincipals_select-50x9.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>See how the dbo database principal says it is mapped to a windows account type? With this in mind, let&#8217;s join to the sys.server_principals and see what windows account is mapped to the dbo database user.</p><pre class="urvanov-syntax-highlighter-plain-tag">select dp.name as DBUser, sp.name as ServerLogin, dp.type_desc, dp.owning_principal_id, dp.authentication_type_desc
	From sys.database_principals dp
		inner join sys.server_principals sp
			on dp.sid = sp.sid
where dp.name = 'dbo';</pre><p><img loading="lazy" class="aligncenter size-large wp-image-4514" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select-1024x131.png" alt="" width="560" height="72" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select-1024x131.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select-300x38.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select-768x98.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select-50x6.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/11/extend_dbprincipals_select.png 1032w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Now we see a bit more clearly. Combined with the error messages and the principal information for both the login and the user, we have a better view of the puzzle now. Changing the database owner indeed mapped the windows account to dbo for us and is now restricting us to certain activities when trying to manage permissions for the windows login in the database. From here, we can easily fix the issue by changing the database owner, creating a user mapped to the windows login and then adding that principal to the datareader role.</p><pre class="urvanov-syntax-highlighter-plain-tag">--fix
USE [DummyDB]
GO
/*set db owner to the sa account */
ALTER AUTHORIZATION ON DATABASE::[DummyDB] TO [sa]
GO
USE [DummyDB]
GO
CREATE USER [mydomain\svc_dummy] FOR LOGIN [mydomain\svc_dummy]
GO
USE [DummyDB]
GO
ALTER ROLE [db_datareader] ADD MEMBER [mydomain\svc_dummy]
GO</pre><p>And if we run that script for svc_dummy we will see a successful execution as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix.png"><img loading="lazy" class="aligncenter size-full wp-image-4516" src="http://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix.png" alt="" width="954" height="672" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix.png 954w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix-768x541.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/11/dummy_fix-50x35.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<h2>The Wrap</h2>
<p>In this article I took a rather long route to a simple fix. It&#8217;s easy to try each of the steps I showed in this article thinking it will help. It isn&#8217;t illogical to try some of those steps. They just don&#8217;t work unfortunately. In the end, getting to know the settings in the database and what the errors are really trying to get at is most helpful. Sometimes, it just takes a few more steps to get to the real meaning of the error.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4509" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/11/07/cannot-use-the-special-principal-back-to-basics/">Cannot Use the Special Principal – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/11/07/cannot-use-the-special-principal-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Quickly Change SQL Job Owners</title>
		<link>https://jasonbrimhall.info/2018/07/16/quickly-change-sql-job-owners/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quickly-change-sql-job-owners</link>
					<comments>https://jasonbrimhall.info/2018/07/16/quickly-change-sql-job-owners/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 16 Jul 2018 19:40:07 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Agent Job]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Agent]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4480</guid>

					<description><![CDATA[<p>It is not unusual to find a server where some random user created a bunch of jobs to be run by SQL Agent. Sometimes, the user creating the job(s) sets themself as the owner of the job. Learn how to efficiently manage the proper change of such job owners.</p>
The post <a href="https://jasonbrimhall.info/2018/07/16/quickly-change-sql-job-owners/">Quickly Change SQL Job Owners</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/tag/back-to-basics/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>It is not unusual to find a server where some random user created a bunch of jobs to be run by SQL Agent. Sometimes, the user creating the job(s) sets themself as the owner of the job. There are certain cases where this behavior is hard to avoid like when creating a <a href="http://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/">maintenance plan</a>.</p>
<p>And of course, there are times when the user just doesn&#8217;t know any better. There is of course, the rare occasion when setting the job owner to be ones self makes the most sense -but that is few and far between in the grand scheme. Usually, you will want a non-expiring account such as a service account or a principal without &#8220;logon&#8221; permissions to be the owner.</p>
<p>The primary reason being simple &#8211; humans have an expiration date for every job they will ever have. When that expiration occurs, you may end up with any number of unwanted side effects. Unwanted side effects is exactly what we try to avoid in our jobs run via SQL Agent.</p>
<h2>No Expiration Date</h2>
<p>There are two basic means to change the owner of every job on your server. Either you open each job one by one and set the owner to an acceptable principal. This method is rather tedious and you will be fighting off the boredom if you have a few hundred jobs on the server. Or, the alternative, change the job owners group by group (set-based theory). This second method can be far less tedious and far more efficient. The second method is by far my preferred method. Let&#8217;s take a look at how to make all of these changes in groups.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO

DECLARE @OwnerChangeFrom VARCHAR(256) = 'MyDomain\Gomer.Clown'
	, @OwnerChangeTo VARCHAR(256) = 'sa'
	, @OwnerSidChangeTo VARBINARY(85);

SELECT	@OwnerSidChangeTo = sp.sid
	FROM sys.server_principals sp
	WHERE sp.name = @OwnerChangeTo;

BEGIN TRAN;
	SELECT	j.name AS JobName
			, sc.name AS CategoryName
			, ISNULL(sp.name, SUSER_SNAME(j.owner_sid)) AS OwnerName
			, j.owner_sid
			, j.date_created
		FROM	dbo.sysjobs j
				LEFT OUTER JOIN sys.server_principals sp
					ON j.owner_sid = sp.sid
				INNER JOIN syscategories sc
					ON j.category_id = sc.category_id
		WHERE j.owner_sid = SUSER_SID(@OwnerChangeFrom);

	UPDATE	j
		SET owner_sid = @OwnerSidChangeTo
		FROM	dbo.sysjobs j
				LEFT OUTER JOIN sys.server_principals sp
					ON j.owner_sid = sp.sid
				INNER JOIN syscategories sc
					ON j.category_id = sc.category_id
		WHERE sp.name = @OwnerChangeFrom
			--OR sp.name IS NULL
			OR j.owner_sid = SUSER_SID(@OwnerChangeFrom);

	SELECT	j.name AS JobName
			, sc.name AS CategoryName
			, sp.name AS OwnerName
			, j.owner_sid
			, j.date_created
		FROM	dbo.sysjobs j
				INNER JOIN sys.server_principals sp
					ON j.owner_sid = sp.sid
				INNER JOIN syscategories sc
					ON j.category_id = sc.category_id;

--ROLLBACK TRANSACTION;
--COMMIT TRANSACTION;</pre><p>There are three basic sections to this script. First I fetch what should be changed, then I make the change, and lastly I verify the change. If the change doesn&#8217;t look right, then I can rollback the change. If the change is what I expected, then I can commit the change. Those are the broad strokes.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/07/job_owners.png"><img loading="lazy" class=" wp-image-4481 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/07/job_owners.png" alt="" width="218" height="210" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/07/job_owners.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/07/job_owners-50x48.png 50w" sizes="(max-width: 218px) 85vw, 218px" /></a>At a more detailed glimpse, I have setup a few variables to compare what I want to change, what the new job owner should be and then I fetch the sid of that new job owner. In my example, I am setting everything to &#8216;sa&#8217;. Why? Because it is easy for the sake of the example in the article &#8211; nothing more!</p>
<p>Since sometimes the owner of the job may only have access to the SQL instance via a Domain Group, I also take advantage of a couple of functions to double check that it is the correct account. These functions I am using are <a href="https://docs.microsoft.com/en-us/sql/t-sql/functions/suser-sid-transact-sql?view=sql-server-2017">SUSER_SID()</a> and <a href="https://docs.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql?view=sql-server-2017">SUSER_SNAME()</a>.</p>
<p>When all is done as I am expecting, then I should see something similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/07/jobowner_quickchange.png"><img loading="lazy" class="aligncenter size-full wp-image-4485" src="http://jasonbrimhall.info/wp-content/uploads/2018/07/jobowner_quickchange.png" alt="" width="638" height="286" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/07/jobowner_quickchange.png 638w, https://jasonbrimhall.info/wp-content/uploads/2018/07/jobowner_quickchange-300x134.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/07/jobowner_quickchange-50x22.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Since the change is what I expect, then at this point I would proceed with the commit transaction statement.</p>
<h2>The Wrap</h2>
<p>As you can see, making job ownership changes at group scale instead of one by one is pretty easy. This only takes a matter of seconds to run against hundreds of jobs. That same kind of task done one at a time could easily take more than 40 minutes. I am not sure I want to spend that much time on such an innocuous task. I hope you are now able to use what you have learned to improve your skills and become a rock-star DBA. ENJOY!</p>
<p>If you feel the need to read more about single-user mode, here is an <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-with-minimal-configuration?view=sql-server-2017">article</a> and <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-in-single-user-mode?view=sql-server-2017">another</a> on the topic.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4480" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/07/16/quickly-change-sql-job-owners/">Quickly Change SQL Job Owners</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/07/16/quickly-change-sql-job-owners/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Use SSMS with a Different Windows Account &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=use-ssms-with-a-different-windows-account-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 28 Jun 2018 15:09:25 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4452</guid>

					<description><![CDATA[<p>Runas should be a very common tool in the toolbox of all IT professionals - not just Data Professionals. Learning how to test different accounts is essential to being an effective and efficient professional that can provide solid results.</p>
The post <a href="https://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/">Use SSMS with a Different Windows Account – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/tag/back-to-basics/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>One of the tasks I find myself doing on a fairly regular basis is running SSMS as a different Windows User. The two biggest use cases for this are: a) to test an account to prove that it is working (or not) and has the appropriate level of access, and b) to use SSMS to connect to a Domain SQL Server from a computer in a different domain (or not on the domain).</p>
<p>In addition to needing to do these tasks for myself, I find that I need to show somebody else how to do the same thing on a fairly consistent basis. Considering the finite keystrokes we all have (<a href="http://jasonbrimhall.info/2018/05/08/giving-back/">which I referenced here</a>), it is time for me to &#8220;document&#8221; how to do this task.</p>
<p>I will cover two really easy and quick methods to perform this task. One from a command line and the other from the GUI. Both methods will involve a variation of the runas utility.</p>
<h2>RUNAS</h2>
<p>Let&#8217;s start with the easiest of the two methods. In this case, you will need to test windows account (let&#8217;s call it a domain account) from a computer which is on the same domain. This requirement allows us to take advantage of the shortcuts from within the GUI to access the runas utility.</p>
<p>To access the runas from Windows, one will first locate the icon for SSMS from the Start Menu, then right click that icon as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu.png"><img loading="lazy" class="aligncenter size-full wp-image-4458" src="http://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu.png" alt="" width="288" height="287" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu.png 288w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_contextmenu-65x65.png 65w" sizes="(max-width: 288px) 85vw, 288px" /></a>After right clicking the icon, you will see a menu pop up on the screen. Select &#8220;Run as different user&#8221; from that menu. Once you have selected the appropriate &#8220;run as&#8221; option, a login prompt will appear as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/login_prompt.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4460" src="http://jasonbrimhall.info/wp-content/uploads/2018/06/login_prompt.jpg" alt="" width="436" height="310" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/06/login_prompt.jpg 436w, https://jasonbrimhall.info/wp-content/uploads/2018/06/login_prompt-300x213.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/06/login_prompt-50x36.jpg 50w" sizes="(max-width: 436px) 85vw, 436px" /></a></p>
<p>Enter the appropriate credentials at the prompt and then SSMS will launch. In this case, I may want to test the account <span style="color: #ff0000;">myidomain\domain.useracc</span>. So, I merely need to enter the domain credentials for that account. A caveat here is that the account you are testing will need to have the necessary permissions to &#8220;logon&#8221; to the workstation in order to launch the app &#8211; unlike the second method.</p>
<h3>CMD Line</h3>
<p>This second method has a few advantages over the GUI method with the biggest advantage being that you can use this method from any machine on the domain or even a machine not joined to the domain (so long as you have the ability to authenticate to the domain). And of course the additional advantage that the account you are testing does not require &#8220;logon&#8221; permissions on the machine you are using.</p>
<p>Let&#8217;s start with the basic command.</p><pre class="urvanov-syntax-highlighter-plain-tag">runas.exe /netonly /user:myidomain\domain.useracc "Ssms.exe"</pre><p>I can run that from a command line, or I can throw that into a desktop shortcut (the shortcut method is much more convenient). After I hit &#8220;enter&#8221; from the command line, I am prompted for a password for the account to be used for that session. Here&#8217;s an example of how that would look.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/runas_cmd.png"><img loading="lazy" class="aligncenter size-full wp-image-4461" src="http://jasonbrimhall.info/wp-content/uploads/2018/06/runas_cmd.png" alt="" width="675" height="342" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_cmd.png 675w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_cmd-300x152.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_cmd-50x25.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>You won&#8217;t be able to see the password being typed (don&#8217;t fat finger the password <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ), but after you enter it successfully and press &#8220;enter&#8221; then you will see SSMS start to launch. After a successful SSMS launch, you should see something similar to the following:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-4459" src="http://jasonbrimhall.info/wp-content/uploads/2018/06/runas_connected.png" alt="" width="560" height="205" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_connected.png 650w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_connected-300x110.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/06/runas_connected-50x18.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>I have a few things highlighted here of interest. First, in the red box, you will note that the user shown as connected to the server is my &#8220;local&#8221; test box account instead of the domain account. However, if I verify the authenticated account, I can see that the domain account is indeed accessing the <strong><span style="color: #339966;">SomeServer</span> </strong>SQL Server (as demonstrated by the green box on the right).</p>
<h2>The Wrap</h2>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon.png"><img loading="lazy" class=" wp-image-4462 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon.png" alt="" width="232" height="171" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/06/sql_jargon-50x37.png 50w" sizes="(max-width: 232px) 85vw, 232px" /></a>Sometimes what may be ridiculously easy for some of us may be mind-blowing to others. Sometimes we may use what we think are common terms only to see eyes start to glaze over and roll to the backs of peoples heads. This just so happens to be one of those cases where launching an app as a different principal may be entirely new to the intended audience. In that vein, it is worthwhile to take a step back and &#8220;document&#8221; how the task can be accomplished.</p>
<p>Runas should be a very common tool in the toolbox of all IT professionals &#8211; not just Data Professionals. Learning how to test different accounts is essential to being an effective and efficient professional that can provide solid results.</p>
<p>If you feel the need to read more about single-user mode, here is an <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-with-minimal-configuration?view=sql-server-2017">article</a> and <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-in-single-user-mode?view=sql-server-2017">another</a> on the topic.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4452" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/">Use SSMS with a Different Windows Account – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/06/28/use-ssms-with-a-different-windows-account-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Single User Mode &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/05/31/single-user-mode-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=single-user-mode-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/05/31/single-user-mode-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 31 May 2018 21:05:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4437</guid>

					<description><![CDATA[<p>Starting SQL Server in single-user mode should be a tool every data professional holds in the bag. This is an essential tool that can be used in multiple scenarios and ensure you are able to fully maintain and control your server. This article will show how to start in single-user mode via two methods.</p>
The post <a href="https://jasonbrimhall.info/2018/05/31/single-user-mode-back-to-basics/">Single User Mode – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/tag/back-to-basics/"><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>In a recent article, I took you on a trip through how to <a href="http://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/">hack (ethically) a SQL Server to regain sysadmin access</a>. In that article, I made quick mention of restarting SQL Server into single-user mode. It only makes sense to show quickly how to get into single-user mode.</p>
<p>Before getting into that, I do hope that there is something you will be able to learn from this basics article. If you are curious, there are <a href="http://jasonbrimhall.info/tag/back-to-basics/">more basics articles on my blog &#8211; here</a>.</p>
<h2>Single-User</h2>
<p>So, what exactly is this single-user mode thing? Single-user mode is basically the official back-door into SQL Server for various reasons such as:</p>
<ul>
<li>Somebody deleted all of the logins that were in the sysadmin role.</li>
<li>The sa account is disabled or the password has been forgotten.</li>
<li>Somebody deleted any Windows groups that were members of the sysadmin role.</li>
<li>All members of the sysadmin role are no longer with the company.</li>
<li>You need to restore the master database</li>
<li>You want to keep SQL Server all to yourself because you are greedy!</li>
</ul>
<p>These are some pretty solid reasons to need to be able to use the back door. But how exactly do we get to the back door?</p>
<h2>Two Paths</h2>
<p>As luck would have it, there are two ways to enable single-user mode. You can either get there by making some changes for the SQL Server service in Configuration Manager, or you can utilize a command prompt. I won&#8217;t cover the gui path beyond the gentle reminder that you <strong>must</strong> remember to undo your change when using that method.</p>
<p>My preferred method is through the command line. Using my SQL Server 2017 as the experiment, I would navigate to the Binn directory for that instance. In this case, as shown in the next image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/sqlserverbinn.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4439" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/sqlserverbinn.jpg" alt="" width="674" height="345" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/sqlserverbinn.jpg 674w, https://jasonbrimhall.info/wp-content/uploads/2018/05/sqlserverbinn-300x154.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/sqlserverbinn-50x26.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Before getting too far ahead of myself, I am going to stop my SQL Server.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/stopsqlserver.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4440" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/stopsqlserver.jpg" alt="" width="674" height="343" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/stopsqlserver.jpg 674w, https://jasonbrimhall.info/wp-content/uploads/2018/05/stopsqlserver-300x153.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/stopsqlserver-50x25.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>Notice, I also queried to find all of my services related to SQL before stopping the MSSQLServer service via the net stop mssqlserver command. We will come back to some net start and net stop commands later.</p>
<p>With the service successfully stopped, I can now restart the service in single-user mode.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/startup_command.png"><img loading="lazy" class="aligncenter size-large wp-image-4442" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/startup_command.png" alt="" width="560" height="286" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/startup_command.png 674w, https://jasonbrimhall.info/wp-content/uploads/2018/05/startup_command-300x153.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/startup_command-50x26.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a>And then the validation that we are indeed starting in single-user mode&#8230;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/singleuser_mode.png"><img loading="lazy" class="aligncenter size-full wp-image-4441" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/singleuser_mode.png" alt="" width="676" height="343" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/singleuser_mode.png 676w, https://jasonbrimhall.info/wp-content/uploads/2018/05/singleuser_mode-300x152.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/singleuser_mode-50x25.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>But wait, did you notice that bit of trickery on the startup command?</p><pre class="urvanov-syntax-highlighter-plain-tag">sqlservr.exe -m"SQLCMD"</pre><p>This is a pro-tip for when you must use single-user mode. Inevitably, somebody will steal the single-user connection and you will be locked out of the session. By using an app name after the single-user switch, you are telling SQL Server to only accept connections for that specific application. Since most apps will not be using sqlcmd, you will have far less contention to gain that connection and you will be able to complete your task much easier.</p>
<p>You could also pass something like this instead&#8230;</p><pre class="urvanov-syntax-highlighter-plain-tag">sqlservr.exe -m"Microsoft SQL Server Management Studio - Query"</pre><p>In this case, I would be limiting the connections to a query from SSMS (and not object explorer).</p>
<p>Now that I have a single-user connection, I can add a sysadmin or restore the master database or just sit on it and play devious. It all depends on what your objective for the single-user session happens to be.</p>
<h3>More Command Line</h3>
<p>Remember that reference to the NET commands? Well, it turns out we can also start SQL Server in single-user via net start. Let&#8217;s check it out.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/netstart_single.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4443" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/netstart_single.jpg" alt="" width="672" height="336" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/netstart_single.jpg 672w, https://jasonbrimhall.info/wp-content/uploads/2018/05/netstart_single-300x150.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/netstart_single-50x25.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>The command is pretty simple:</p><pre class="urvanov-syntax-highlighter-plain-tag">net start mssqlserver -m"SQLCMD"</pre><p>The effect here is the same as navigating to the Binn directory and starting SQL Server with the sqlservr.exe executable. The big difference is considerably less typing and less verbose output of the service startup.</p>
<p>When using the net start method, you do need to know the service name of the SQL Server instance. To get that, I do recommend the following powershell script.</p><pre class="urvanov-syntax-highlighter-plain-tag">get-service -name *sql* |format-table -auto</pre><p>This will produce results similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/posh_sqlservice.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4444" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/posh_sqlservice.jpg" alt="" width="644" height="183" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/posh_sqlservice.jpg 644w, https://jasonbrimhall.info/wp-content/uploads/2018/05/posh_sqlservice-300x85.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/posh_sqlservice-50x14.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>From the results, I can pick the SQL Server service and then pass that to the net start command fairly easily.</p>
<h2>The Wrap</h2>
<p>Starting SQL Server in single-user mode should be a tool every data professional holds in the bag. This is an essential tool that can be used in multiple scenarios and ensure you are able to fully maintain and control your server. I have shown how to get to single-user mode via two command line methods and mentioned a GUI method. The nice thing about the command line methods is that you don&#8217;t have to remember to undo the startup switch like you do with the GUI method.</p>
<p>If you feel the need to read more about single-user mode, here is an <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-with-minimal-configuration?view=sql-server-2017">article</a> and <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/start-sql-server-in-single-user-mode?view=sql-server-2017">another</a> on the topic.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4437" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/05/31/single-user-mode-back-to-basics/">Single User Mode – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/05/31/single-user-mode-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Lost that SQL Server Access?</title>
		<link>https://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lost-that-sql-server-access</link>
					<comments>https://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 30 May 2018 22:12:34 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[collation]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4420</guid>

					<description><![CDATA[<p>Losing access to a SQL instance is never a desirable situation - for the DBA. When the people that are supposed to have access, lose that access, all hope is not lost. There are plenty of methods available to regain the requisite access to manage the server. Today, I shared one such method that I view as being extremely easy. If you lose access, I would recommend taking the steps shown in this article to regain that access.</p>
The post <a href="https://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/">Lost that SQL Server Access?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/db_bio_lock.png"><img loading="lazy" class="wp-image-4421 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/db_bio_lock.png" alt="" width="152" height="149" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/db_bio_lock.png 203w, https://jasonbrimhall.info/wp-content/uploads/2018/05/db_bio_lock-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/db_bio_lock-65x65.png 65w" sizes="(max-width: 152px) 85vw, 152px" /></a></p>
<p>As a data professional can you recall the last time you needed to support a SQL Server instance for which you had no access? What if you used to have access and then that access magically disappeared?</p>
<p>I know I run into this dilemma more than I would probably like to. It is rather annoying to be under a crunch to rapidly provide support only to discover you are stuck and have to wait on somebody else who hopefully has access.</p>
<p>It&#8217;s one thing to not have access in the first place. This is usually an easy fix in most cases. The really unpleasant access issue is the one when you have confirmed prior access to the instance and then to be completely locked out. More succinctly, <a href="https://www.youtube.com/watch?v=uOnYY9Mw2Fg">you have lost that SQL access</a>!</p>
<h2>Whoa is Me!</h2>
<p>All hope is now lost right? OK, that isn&#8217;t entirely true. Or is it? What if everybody else from the team is also locked out and there is no known sysadmin account. In essence everybody is locked out from managing the instance and now you have a real crisis, right? Well, not so fast. You can still get back in to the instance with sysadmin access. It should be no real secret that you could always <a href="https://msdn.microsoft.com/en-us/library/dd207004.aspx">restart the SQL instance in single-user mode</a>. Then again, that probably means bigger problems if the server is a production server and is still servicing application requests just fine.</p>
<p>What to do? What to do?</p>
<h2>Restart Prohibited</h2>
<p>If you really cannot cause a service disruption to bounce the server into single-user mode, my friend Argenis Fernandez (<a href="https://www.0xsql.com/" class="broken_link">b</a> | <a href="https://twitter.com/DBArgenis">t</a>) has this <a href="https://www.0xsql.com/2012/01/12/leveraging-service-sids-to-logon-to-sql-server-2012-2014-and-new-2016-instances-with-sysadmin-privileges/" class="broken_link">pretty nifty trick that could help you</a>. Truth be told, I have tested that method (even on SQLExpress) several times and it is a real gem. Is this the only alternative?</p>
<p>Let&#8217;s back it up just a step or two first. Not having access to SQL Server is in no way the same thing as not having access to the server. Many sysadmins have access to the windows server. Many DBAs also have access to the Windows server or can at least work with the sysadmins to get access to the Windows server in cases like this. If you have admin access to windows &#8211; then not much is really going to stop you from gaining access to SQL on that same box. It is a matter of how you approach the issue. Even to restart SQL Server in single-user mode, you need to have access to the Windows server. So, please keep that in mind as you read the article by Argenis as well as the following.</p>
<p>Beyond the requirement of having local access to the server, one of the things that may cause heartburn for some is the method of editing the registry as suggested by Argenis. Modifying the registry (in this case) is not actually terribly complex but it is another one of those changes  that must be put back the way it was. What if there was another way?</p>
<p>As luck would have it, there is an alternative (else there wouldn&#8217;t be this article). It just so happens, this alternative is slightly less involved (in my opinion). Let&#8217;s start with a server where I don&#8217;t have SQL access (beyond public) but I do have Windows access.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access.png"><img loading="lazy" class="aligncenter size-large wp-image-4427" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access-1024x640.png" alt="" width="560" height="350" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access-1024x640.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access-300x188.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access-768x480.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access-50x31.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/no_server_access.png 1272w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>We can see on this SQLExpress instance on the TF server that my &#8220;Jason&#8221; does not exist. Since I don&#8217;t have access, I can&#8217;t add my own account either. Time to fix that. In order to fix it, I am going to create Scheduled task in Windows that will run a SQLCMD script from my C:\Database folder. The folder can be anywhere, but I generally have one with scripts and such somewhere on each server that I can quickly access.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask.png"><img loading="lazy" class="aligncenter size-large wp-image-4430" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask-1024x757.png" alt="" width="560" height="414" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask-1024x757.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask-300x222.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask-768x568.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask-50x37.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/create_scheduledtask.png 1102w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From here, you will want to click on the &#8220;Change User or Group&#8221; button to change it to an account that does have access to SQL Server. The account that I use is not a &#8220;user&#8221; account but rather it is a &#8220;system&#8221; account called &#8220;NT AUTHORITY\SYSTEM&#8221; that is present all the way through SQL Server 2017.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity.png"><img loading="lazy" class="aligncenter size-large wp-image-4431" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity-1024x747.png" alt="" width="560" height="409" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity-1024x747.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity-300x219.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity-768x560.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/scheduledtask_changesecurity.png 1100w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>To locate the &#8220;NT AUTHORITY\SYSTEM&#8221; account, just type &#8220;SYSTEM&#8221; into the new window and click &#8220;Check Names&#8221;. The account will resolve and then you can click OK out of the &#8220;Select User or Group&#8221; window.</p>
<p>With the account selected that will run this task, we can now focus our attention on the guts of the task. We will now go to the &#8220;Actions&#8221; tab.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action.png"><img loading="lazy" class="aligncenter size-large wp-image-4432" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-1024x767.png" alt="" width="560" height="419" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-1024x767.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-300x225.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-768x575.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-50x37.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action-320x240.png 320w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action.png 1092w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Click the new button, and here we will configure what will be done.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config.png"><img loading="lazy" class="aligncenter size-full wp-image-4433" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config.png" alt="" width="795" height="857" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config.png 795w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config-278x300.png 278w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config-768x828.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_action_config-46x50.png 46w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>I do recommend putting the full path to SQLCMD into &#8220;Program/Script&#8221; box. Once entered, you will add the following to the parameter box.</p><pre class="urvanov-syntax-highlighter-plain-tag">-S YourServer\yourinstance -i c:\database\myscript.sql</pre><p>If you do not have an instance, then just the server name will suffice after the -S parameter. The -i parameter specifies the path to the SQL script file that will be created and placed in the C:\database directory (or whichever directory you have chosen).</p>
<p>That is it for the setup of the task. Now let&#8217;s look at the guts of the script file.</p><pre class="urvanov-syntax-highlighter-plain-tag">create login [mydomain\jason] from windows
exec sp_addsrvrolemember 'mydomain\jason','sysadmin';
go</pre><p>Save that into a script document named myscript.sql in the aforementioned directory and then execute the windows task. After executing the Windows task, it is time to verify if it worked or not.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify.png"><img loading="lazy" class="aligncenter size-full wp-image-4434" src="http://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify.png" alt="" width="697" height="525" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify.png 697w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify-300x226.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/05/schedtask_verify-320x240.png 320w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Boom! From no access to a sysadmin in a matter of seconds. Here is that quick verify script &#8211; generalized.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT	spr.name AS SvrRole
	, sp.name AS SvrPrincipal
FROM	sys.server_principals sp
		INNER JOIN sys.server_role_members rm
			ON sp.principal_id = rm.member_principal_id
		INNER JOIN sys.server_principals spr
			ON rm.role_principal_id = spr.principal_id
WHERE spr.name = 'sysadmin';</pre><p></p>
<h2>The Wrap</h2>
<p>Losing access to a SQL instance is never a desirable situation &#8211; for the DBA. When the people that are supposed to have access, lose that access, all hope is not lost. There are plenty of methods available to regain the requisite access to manage the server. Today, I shared one such method that I view as being extremely easy. If you lose access, I would recommend taking the steps shown in this article to regain that access.</p>
<p>While not in the back to basics series, I do recommend checking out my other posts in that series. Some topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>. I would also recommend reading this <a href="http://bit.ly/2C7UYgV">audit</a> article. If you are able to elevate your permissions, then obviously anybody with server access can elevate their permissions too. For that reason, you should regularly audit the permissions and principals in SQL Server.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4420" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/">Lost that SQL Server Access?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/05/30/lost-that-sql-server-access/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Change SQL Server Collation &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/04/12/change-sql-server-collation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=change-sql-server-collation</link>
					<comments>https://jasonbrimhall.info/2018/04/12/change-sql-server-collation/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 12 Apr 2018 21:42:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[collation]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4385</guid>

					<description><![CDATA[<p>Every now and again we have to deal with a sudden requirements change. When that happens, we sometimes just need to take a step back and evaluate the entire situation to ensure we are proceeding down the right path. It is better to be pensive about the course of action rather than to knee jerk into the course of action. Do you want to spend 5 minutes on the solution or 30-40 minutes doing the same thing? Changing collation can be an easy change, or it can be one met with a bit of pain doing a reinstall (more painful if more user databases are present). Keep that in mind and keep cool when you need to make a sudden change.</p>
The post <a href="https://jasonbrimhall.info/2018/04/12/change-sql-server-collation/">Change SQL Server Collation – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png"><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>One of my most favorite things in the world is the opportunity to deal with extremely varying database and environment requirements. Many vendors and databases seem to have a wide swath of different requirements. Some of the reasons for these requirements are absurd and some are not. That is a discussion for a different day.</p>
<p>When dealing with vendors, sometimes you get good documentation and requirements for the app. If you happen across one of these opportunities, you should consider buying a lottery ticket. Most of the time, the requirements and documentation are poorly assembled and then suffer from linguistic shortcomings.</p>
<p>What do you do when you run into poor documentation from a vendor? The typical answer would be to either call them or make a best guess (even if you call them, you are likely stuck with a best guess anyway). Then what do you do when you find that your best guess was completely wrong? Now it is time to back pedal and fix it, right?</p>
<p>When that mistake involves the server collation setting, the solution is simple &#8211; right? All you need to do is uninstall and reinstall SQL Server. That is the common solution and is frankly a horrific waste of time. This article will show some basics around fixing that problem quickly without a full reinstall.</p>
<p>I do hope that there is something you will be able to learn from this basics article. If you are curious, there are <a href="http://jasonbrimhall.info/tag/back-to-basics/">more basics articles on my blog &#8211; here</a>.</p>
<h2>Reinstall Prohibited</h2>
<p>I am not a huge fan of wasting time doing something, especially if there is a more efficient way of achieving the same end result. I am not talking about cutting corners. If you cut corners, you likely just end up with having more work to do to fix the problems your sloppiness will have caused. That to me is not the same end result.</p>
<p>Having run into a bit of a problem with a vendor recently (with lacking requirements), I found myself with a server that was installed with the wrong collation instead of what the vendor wanted (never-mind they said nothing of it until a month after the server was setup and ready for them to use). The vendor needed the collation fixed immediately (basically it needed to be fixed yesterday). I really did not want to do a reinstall of the server and the sysadmins were just about to click through the uninstall and redo the install.</p>
<p>Oy Vey! Everybody hold up just a second here! First things first &#8211; verify with certainty there is good reason to need to change the server collation. It is perfectly legit to give the vendor the third degree here. Make sure they understand why they need the change. If they can answer the questions satisfactorily, then proceed with the change.</p>
<p>Next, just because the vendor says you have to uninstall/reinstall (or reboot) the server to make a certain change, does not mean they know what they are talking about. I have run into too many cases where the vendor thinks you must reboot the server to change the max memory setting in SQL Server (<a href="http://jasonbrimhall.info/2010/08/25/memory/">not true for sure</a>).</p>
<p>Sure, common myth would say that you must reinstall SQL Server in order to change the default server collation. That is not entirely accurate. Reinstall is just one option that exists.</p>
<p>In the case of this vendor, they required that the SQL_Latin1_General_CP850_CS_AS collation be used. The server was set for SQL_Latin1_General_CP1_CI_AS. So, let&#8217;s see how we can change the collation without a reinstall.</p>
<p>The first thing to do is to confirm the collation we have set.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4387" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate.jpg" alt="" width="346" height="259" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate.jpg 346w, https://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate-300x225.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate-50x37.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/04/revert_collate-320x240.jpg 320w" sizes="(max-width: 346px) 85vw, 346px" /></a>We can see from these results that indeed the collation is wrong and we need to change it in order to comply with the request from the vendor. Next we will need to stop the SQL Server services.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/sqlconfmgr.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4394" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/sqlconfmgr.jpg" alt="" width="706" height="284" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/sqlconfmgr.jpg 706w, https://jasonbrimhall.info/wp-content/uploads/2018/04/sqlconfmgr-300x121.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/sqlconfmgr-50x20.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>I think that is pretty clear there what to do. As a reminder, the preferred method to stop and start SQL Server services is via the SQL Server Configuration Manager. We won&#8217;t do every start/stop from here for this article for good reason.</p>
<p>Once the services are stopped, then we need to open an administrative command prompt and navigate to the SQL Server binn directory as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/binn_cmdprompt.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4393" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/binn_cmdprompt.jpg" alt="" width="674" height="343" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/binn_cmdprompt.jpg 674w, https://jasonbrimhall.info/wp-content/uploads/2018/04/binn_cmdprompt-300x153.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/binn_cmdprompt-50x25.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>This is for a default instance on SQL Server 2017. If you have a named instance or a different version of SQL Server, you will need to navigate the instance folder structure for your instance.</p>
<p>Next is where the magic happens. We enter a command similar to this:</p><pre class="urvanov-syntax-highlighter-plain-tag">sqlservr -m -T4022 -T3659 -q"SQL_Latin1_General_CP850_CS_AS"</pre><p>Here is a quick summary of those flags in this command:</p>
<p>[-m] single user admin mode<br />
[-T] trace flag turned on at startup<br />
[-q] new collation to be applied</p>
<p>There are more such as -s available in <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/database-engine-service-startup-options">books online for your perusal</a>.</p>
<p>If you are curious what is up with those Trace Flags, pretty simple. TF4022 is to bypass startup procs. TF3659 on the other hand is supposed to write errors to the error log (at least in theory).</p>
<p>When the script starts, you will see something like the next two screens:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/attempting_collatechange.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4391" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/attempting_collatechange.jpg" alt="" width="673" height="343" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/attempting_collatechange.jpg 673w, https://jasonbrimhall.info/wp-content/uploads/2018/04/attempting_collatechange-300x153.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/attempting_collatechange-50x25.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a> <a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/collate_change1.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4392" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/collate_change1.jpg" alt="" width="671" height="341" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/collate_change1.jpg 671w, https://jasonbrimhall.info/wp-content/uploads/2018/04/collate_change1-300x152.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/collate_change1-50x25.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>In the first, you can see that it says it is attempting to change the collation. In the second, just before the completion message, it states that the default collation was successfully changed. Let&#8217;s close this command prompt window and then go start SQL Server and validate the change.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/post-change.jpg"><img loading="lazy" class="aligncenter size-full wp-image-4389" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/post-change.jpg" alt="" width="367" height="286" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/post-change.jpg 367w, https://jasonbrimhall.info/wp-content/uploads/2018/04/post-change-300x234.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/04/post-change-50x39.jpg 50w" sizes="(max-width: 367px) 85vw, 367px" /></a></p>
<p>And that is a successful change. See how easy that is? This effort takes all of maybe 5 minutes to complete (validation, starting, stopping and so on). I would take this over a reinstall on most days.</p>
<p>Now that we have changed the collation, all I need to do is repeat the process to set the collation back to what it was originally (in my test lab) and make sure to bookmark the process so I can easily look it up the next time.</p>
<p>There is a bit of a caveat to this. On each change of the collation, I ran into permissions issues with my default logging directory (where the sql error logs are written). I just needed to reapply the permissions and it was fine after that (SQL Server would not start). That said, the permissions issue was not seen on the box related to the change for the vendor. So just be mindful of the permissions just in case.</p>
<h2>The Wrap</h2>
<p>Every now and again we have to deal with a sudden requirements change. When that happens, we sometimes just need to take a step back and evaluate the entire situation to ensure we are proceeding down the right path. It is better to be pensive about the course of action rather than to knee jerk into the course of action. Do you want to spend 5 minutes on the solution or 30-40 minutes doing the same thing? Changing collation can be an easy change, or it can be one met with a bit of pain doing a reinstall (more painful if more user databases are present). Keep that in mind and keep cool when you need to make a sudden change.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4385" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/04/12/change-sql-server-collation/">Change SQL Server Collation – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/04/12/change-sql-server-collation/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
		<item>
		<title>Syspolicy Phantom Health Records</title>
		<link>https://jasonbrimhall.info/2018/04/06/syspolicy-phantom-health-records/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=syspolicy-phantom-health-records</link>
					<comments>https://jasonbrimhall.info/2018/04/06/syspolicy-phantom-health-records/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 06 Apr 2018 21:38:35 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4373</guid>

					<description><![CDATA[<p>SQL Server comes with a default SQL agent job installed (for most installations) to help manage the collection of system health data. I would dare say this job is ignored by most people and few probably even know it exists. This job is the syspolicy_purge_history job.</p>
The post <a href="https://jasonbrimhall.info/2018/04/06/syspolicy-phantom-health-records/">Syspolicy Phantom Health Records</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p style="text-align: left;">SQL Server comes with a default SQL agent job installed (for most installations) to help manage the collection of system health data. I would dare say this job is ignored by most people and few probably even know it exists.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/nurse_health.png"><img loading="lazy" class="size-full wp-image-4375 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/nurse_health.png" alt="" width="259" height="177" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/04/nurse_health.png 259w, https://jasonbrimhall.info/wp-content/uploads/2018/04/nurse_health-50x34.png 50w" sizes="(max-width: 259px) 85vw, 259px" /></a>This topic is not new to me. You may recall a previous article I wrote entailing one type of failure and how to resolve that failure. <a href="http://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/">That article can be found here</a>.</p>
<p style="text-align: left;">I recently ran into a variant of the problem outline in that <a href="http://bit.ly/1dxBInZ">previous article</a> that requires just a bit of a different approach. The errors turn out to be similar on the surface but really are different upon closer inspection.</p>
<h3>Phantom Health Records</h3>
<p>If you are unfamiliar with the topic, I recommend reading the previous article. Then after reading that article, maybe brush up a little bit on the <a href="https://docs.microsoft.com/en-us/sql/ssms/agent/sql-server-agent">SQL Agent</a>. The failures we will be looking at are within the SQL Agent and come from the job called: syspolicy_purge_history.</p>
<p>For this latest bout of failure, I will start basically where I left off in the the last article. The job fails on a server and I have access to other servers of the same SQL version where the job works.</p>
<p style="text-align: left;">Before diving any further into this problem, let&#8217;s look at what the error is:</p>
<p><strong><em>A job step received an error at line 1 in a PowerShell script.<br />
The corresponding line is &#8216;set-executionpolicy RemoteSigned -scope process -Force&#8217;.<br />
Correct the script and reschedule the job. The error information returned by PowerShell is:<br />
&#8216;Security error. &#8216;. Process Exit Code -1. The step failed.</em></strong></p>
<p>Having the error in hand, and knowing that the job works elsewhere, my next logical step (again based on experience from the last article with this job) is to script the job from another server and use it to replace the job on the server where it fails. In principle this is an AWESOME idea.</p>
<p>&nbsp;</p>
<p>Sadly, that idea was met with initial failure. As it turns out, the error remained exactly the same. This is good and unfortunate at the same time. Good in that I was able to confirm that the job was correctly configured with the following script in the job:</p><pre class="urvanov-syntax-highlighter-plain-tag">if ('$(ESCAPE_SQUOTE(INST))' -eq 'MSSQLSERVER') {$a = '\DEFAULT'} ELSE {$a = ''};
(Get-Item SQLSERVER:\SQLPolicy\$(ESCAPE_NONE(SRVR))$a).EraseSystemHealthPhantomRecords()</pre><p>Since the step fails from SQL Server let&#8217;s see what else we can do to make it run. Let&#8217;s take that code and try it from a powershell ise. So, for giggles, let&#8217;s cram that script into powershell and see what blows up!</p><pre class="urvanov-syntax-highlighter-plain-tag">SRVR : The term 'SRVR' is not recognized as the name of a cmdlet, function, 
script file, or operable program. Check the spelling of the name, or if a path 
was included, verify that the path is correct and try again.
At line:2 char:46</pre><p>Now isn&#8217;t that a charming result! This result should be somewhat expected since the code I just threw into the ISE is not entirely powershell. If you look closer at the code, you will notice that it is using sqlcmd like conventions to execute a parameterized powershell script. Now, that makes perfect sense, right? So let&#8217;s clean it up to look like a standard PoSH script. We need to replace some parameters and then try again.</p><pre class="urvanov-syntax-highlighter-plain-tag">(Get-Item sqlserver:\SQLPolicy\MyServer\Default).EraseSystemHealthPhantomRecords()</pre><p>This will result in the following (resume reading after you scratch your head for a moment):</p><pre class="urvanov-syntax-highlighter-plain-tag">Get-Item : Cannot find drive. A drive with the name 'sqlserver' does not exist.
At line:1 char:2
+ (Get-Item 
sqlserver:\SQLPolicy\SPMS1\Default).EraseSystemHealthPhantomRecords()</pre><p>The key in this failure happens to be in the sqlserver. PoSH thinks we are trying to pass a drive letter when we are just trying to access the SQLServer stuff. Depending on your version of server, SQL Server, and PoSH you may need to do one of a couple different things. For this particular client/issue, this is what I had to try to get the script to work.</p><pre class="urvanov-syntax-highlighter-plain-tag">Import-Module “sqlps” -DisableNameChecking;

(Get-Item sqlserver:\SQLPolicy\myserver\Default).EraseSystemHealthPhantomRecords()</pre><p>If you read the previous article, you may notice this command looks very much like the command that was causing the problems detailed in that previous article. Yes, we have just concluded our 180 return to where we started a few years back. Suffice it to say, this is expected to be a temporary fix until we are able to update the system to PoSH 5 and are able to install the updated sqlserver module.</p>
<p>As is, this script is not quite enough to make the job succeed now. To finish that off, I created a ps1 file to house this script. Then from a new step (defined as a sqlcmd step type) in the syspolicy purge job, I execute that powershell script as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">powershell.exe "c:\dba\syshealth.ps1"</pre><p>Tada, nuisance job failure alert is resolved and the system is functioning again.</p>
<h3>Conclusion</h3>
<p>I dare say the quickest resolution to this job is to probably just disable it. I have seen numerous servers with this job disabled entirely for the simple reason that it fails frequently and just creates noise alerts when it fails. Too many fixes abound for this particular job and too few resolve the failures permanently.</p>
<p>I would generally err on the side of fixing the job. Worst case, you learn 1000 ways of what not to do to fix it. <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Given this job is tightly related to the system_health black box sessions (sp_server_diagnostics and system_health xe session), I recommend fixing the job. In addition, I also recommend reading the following series about XE and some of those black box recorder sessions &#8211; <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4373" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/04/06/syspolicy-phantom-health-records/">Syspolicy Phantom Health Records</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/04/06/syspolicy-phantom-health-records/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server Extended Availability Groups</title>
		<link>https://jasonbrimhall.info/2018/04/01/sql-server-extended-availability-groups/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-extended-availability-groups</link>
					<comments>https://jasonbrimhall.info/2018/04/01/sql-server-extended-availability-groups/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sun, 01 Apr 2018 20:05:25 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4363</guid>

					<description><![CDATA[<p>It may come as no surprise to many that Microsoft has hastened the SQL Server development cycle. Furthermore, it may be no surprise to many that Microsoft has also hastened the patch cycle for SQL Server.</p>
The post <a href="https://jasonbrimhall.info/2018/04/01/sql-server-extended-availability-groups/">SQL Server Extended Availability Groups</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/04/ExtendedAvailability-e1522611721144.png"><img loading="lazy" class="wp-image-4364 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/04/ExtendedAvailability-e1522611721144.png" alt="" width="333" height="175" /></a></p>
<p>It may come as no surprise to many that Microsoft has hastened the SQL Server development cycle. Furthermore, it may be no surprise to many that Microsoft has also hastened the patch cycle for SQL Server.</p>
<p>If you were unaware of this, consider this as your notice that Microsoft has indeed hastened the patch cycle. Not only has the patch cycle become more rapid, the idea of Service Packs is more or less a notion of history at this point. Critical Updates (or CUs) is the new norm. This is a pretty good thing due in large part to the rapid improvements that can be made to the product due to Azure.</p>
<p>With all of this considered now, there is some really awesome news. A hint to this awesome news is in the preceding image and title of this post. In a recent CU for SQL Server 2017, Availability Groups and Extended Events both have seen massive upgrades. The upgrades are so big in fact that it is mind blowing. These upgrades were no small feat by any means and it took some major investment and cooperation from the likes of some well known competitors.</p>
<p>Upgrade the first: Availability Groups have now been extended to be able to include nodes from MySQL, PostGres and MariaDB. Frankly, I don&#8217;t understand the MariaDB move there but it&#8217;s all good. I am 100% on board with the MySQL addition and may have to work really hard to find a use case to include PostGres.</p>
<p>Imagine the realm of possibility this change brings!! First we got SQL Server on Linux and now we can include a predominantly Linux flavored DBMS in a SQL Server High Availability solution. LAMP engineers have got to be losing their gourds right about now over this. Microsoft is taking away every anti-MS premise that has been used in recent years and turning the world on its ears to become more global and reachable in the architecture and DBMS world.</p>
<p>Upgrade the second: In order to help support and troubleshoot AGs on these other platforms, we need some tools. The tools of choice happen to be in the form of <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Extended Events</a>. While there is nothing quite yet in place on these other platforms to properly monitor an AG, XE is able to capture some MySQL, PostGres and MariaDB information as transmitted across the wire when these platforms are added to an AG. How COOL is that?</p>
<p>If you are really chomping at the bit, I recommend procuring the latest CU that was recently released. You can find that <a href="https://www.microsoft.com/en-us/download/details.aspx?id=56128">CU from this Microsoft site here</a>.</p>
<h2>The Wrap</h2>
<p>I am in full support of this new direction from Microsoft. Partnering with other large platforms to provide a supremely improved overall product is very next level type of stuff and frankly quite unheard of in this ultra competitive world. It is so unheard of in fact that this was a nicely crafted April Fools joke. Happy April Fools Day!</p>
<p>Having mentioned Extended Events, if you are interested, I do recommend a serious read from any number of articles posted in <a href="http://xevents.jasonbrimhall.info">60 day series</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4363" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/04/01/sql-server-extended-availability-groups/">SQL Server Extended Availability Groups</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/04/01/sql-server-extended-availability-groups/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events File Initialization Failure</title>
		<link>https://jasonbrimhall.info/2018/03/09/extended-events-file-initialization-failure/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-events-file-initialization-failure</link>
					<comments>https://jasonbrimhall.info/2018/03/09/extended-events-file-initialization-failure/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 09 Mar 2018 17:53:28 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4346</guid>

					<description><![CDATA[<p>One of the recommended methods to trap payload data in an XE session is via the use of the event_file target. Sending data to a file has numerous benefits such as being able to take the trace and evaluate the trace file from a different machine (locally to that machine).</p>
The post <a href="https://jasonbrimhall.info/2018/03/09/extended-events-file-initialization-failure/">Extended Events File Initialization Failure</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://xevents.jasonbrimhall.info"><img loading="lazy" class="alignright wp-image-4348" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/poof.png" alt="" width="236" height="170" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/poof.png 546w, https://jasonbrimhall.info/wp-content/uploads/2018/03/poof-300x215.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/poof-50x36.png 50w" sizes="(max-width: 236px) 85vw, 236px" /></a></p>
<p>It should come as no surprise that I write a lot of articles about Extended Events (XE). This happens to be another article on Extended Events. Truth be told, this article is hopefully something that is more of an edge case scenario. Well, I sure hope that is the case and that it is not a common problem.</p>
<p>One of the recommended methods to trap payload data in an XE session is via the use of the event_file target. Sending data to a file has numerous benefits such as being able to take the trace and evaluate the trace file from a different machine (locally to that machine).</p>
<p>Every once in a blue moon you just may run into various issues with the event_file such as explained <a href="http://jasonbrimhall.info/2017/12/27/message-in-a-bottle-of-xe/">here</a> or <a href="http://jasonbrimhall.info/2017/12/31/failed-to-create-the-audit-file/">here</a>. Though slightly different, the net effect is quite similar and should be treated with roughly the same kind of troubleshooting steps.</p>
<h2>Configuration Error</h2>
<p>As luck would have it, I ran into one of these rare opportunities to troubleshoot an error occurring on a client server. Truth be told, I was unfamiliar with the actual error at first. Here is that error.</p>
<blockquote><p><span style="color: #ff0000;">Error: 25602, Severity: 17, State: 22.</span></p></blockquote>
<p>The preceding error was scraped out of the SQL Server error log. Obviously a little more detail was needed because this error is far from useful without that detail. Looking a little deeper, I found some errors like this.</p>
<blockquote><p><span style="color: #ff0000;">Msg 25602, Level 17, State 22, Line 43</span><br />
<span style="color: #ff0000;">The target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.event_file&#8221;, </span><br />
<span style="color: #ff0000;">encountered a configuration error during initialization. Object cannot be added to the event session. </span></p></blockquote>
<p>Some very good clues are actually contained in that particular message. Some of these clues include the following: a) the term &#8220;target&#8221;, b) the term &#8220;event_file&#8221;, and c) the phrase &#8220;event session.&#8221; Ok, I get it at this point. One of my Extended Event Sessions I had put on the server and used previously was broken. But, since it had been working and I know I had fetched data from it, I found myself puzzled as to why it might be busted.</p>
<p>The next logical thing to do at this point was to test the various sessions that are stopped and try to figure out which one is causing the problem and see if the error is reproduced. Finally upon finding the session that is failing, I ran into the complete message.</p>
<blockquote><p><span style="color: #ff0000;">Msg 25602, Level 17, State 22, Line 43</span><br />
<span style="color: #ff0000;">The target, &#8220;5B2DA06D-898A-43C8-9309-39BBBE93EBBD.package0.event_file&#8221;, </span><br />
<span style="color: #ff0000;">encountered a configuration error during initialization. Object cannot be added to the event session. </span><br />
<strong><span style="color: #ff0000;">The operating system returned error 3: &#8216;The system cannot find the path specified.</span></strong><br />
<strong><span style="color: #ff0000;">&#8216; while creating the file &#8216;C:\Database\XEDROPME\SVRLoginAudit_0_131650006658030000.xel&#8217;.</span></strong></p></blockquote>
<p>The additional info that I needed is in bold text in the previous text. So, for some reason, there is a problem with the path for the XE trace file output. Going out to the file system to check it out, I found that the client in this case decided to delete the entire folder. How does that happen? Well, it does! When it happens, the XE traces will start to fail and you will no longer capture the intended trace data. Let&#8217;s take a look at a simulated reproduction of this issue.</p>
<p>First, I will create a session and then start the session, then validate the session exists and then stop the session.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'SVRLoginAudit' )
	DROP EVENT SESSION SVRLoginAudit 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XEDROPME';
GO

CREATE EVENT SESSION SVRLoginAudit ON SERVER
ADD EVENT sqlserver.login ( SET collect_database_name = ( 1 ), collect_options_text = (1)
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence,
	sqlserver.database_id, sqlserver.database_name,
	sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id,
	sqlserver.context_info, sqlserver.client_connection_id ) 
	)
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XEDROPME\SVRLoginAudit.xel' , max_file_size = ( 5120 )
									, max_rollover_files = ( 4 ) )
WITH (STARTUP_STATE = ON
	,TRACK_CAUSALITY = ON);

/* start the session */
ALTER EVENT SESSION SVRLoginAudit 
ON SERVER 
STATE = START;
GO

DECLARE @SessionName VARCHAR(128) = NULL --'BackupThroughput' --'sp_server_diagnostics session' --NULL for all
;

SELECT ISNULL(ses.name,xse.name) AS SessionName
		, CASE
			WHEN ISNULL(ses.name,'') = ''
			THEN 'Private'
			ELSE 'Public'
			END AS SessionVisibility
		, CASE
			WHEN ISNULL(xse.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS SessionRunning
		, CASE
			WHEN ISNULL(xse.name,'') = ''
				AND ISNULL(ses.name,'') = ''
			THEN 'NO'
			ELSE 'YES'
			END AS IsDeployed
	FROM sys.server_event_sessions ses
	FULL OUTER JOIN sys.dm_xe_sessions xse
		ON xse.name =ses.name
	WHERE COALESCE(@SessionName, ses.name, xse.name) = ISNULL(ses.name, xse.name)
	ORDER BY ses.event_session_id;
GO

/* stop the session */
ALTER EVENT SESSION SVRLoginAudit 
ON SERVER 
STATE = STOP;
GO</pre><p>And here is what I see on my test server when I validate the session exists.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/sessionvalidated.png"><img loading="lazy" class="aligncenter size-full wp-image-4352" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/sessionvalidated.png" alt="" width="651" height="209" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/sessionvalidated.png 651w, https://jasonbrimhall.info/wp-content/uploads/2018/03/sessionvalidated-300x96.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/sessionvalidated-50x16.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Perfect so far. Now, let&#8217;s make that trace output directory disappear. For this demo, you might note that I had created the directory as &#8220;C:\Database\XEDROPME&#8221;. My intent in the name was obviously to notify the world that the folder was to be dropped.</p><pre class="urvanov-syntax-highlighter-plain-tag">xp_cmdshell 'rd C:\Database\XEDROPME /Q /s'
GO</pre><p>That statement is easy enough and is performed from my test environment for those getting weary of the use of xp_cmdshell. Now, let&#8217;s try to start that session that we knew was previously running.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4353" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail-1024x413.jpg" alt="" width="560" height="226" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail-1024x413.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail-300x121.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail-768x310.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail-50x20.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/session_fail.jpg 1538w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I re-formatted the output of the error for ease of readability. Otherwise, the output in the preceding image is what will happen when the output directory is dropped. The fix is rather simple at this point &#8211; put the folder structure back into place. To read an introductory post about checking if a session exists or not on your server, <a href="http://bit.ly/1XfzO27">check this out</a> (a more advanced post is coming soon).</p>
<h2>Conclusion</h2>
<p>From time to time we will run into various problems supporting Extended Events. This is bound to happen more frequently as we support more varied environments with more hands in the kitchen (so to speak). We need to learn that even small changes can have a ripple effect to other things that may be running on the server. It is worthwhile to perform a little due diligence and clean things up as we make changes &#8211; or at minimum to observe the system for a time to ensure no unintended consequences have occurred.</p>
<p>Extended Events is a powerful tool to help in troubleshooting and tuning your environment. I recommend investing a little time in reading the <a href="http://bit.ly/XE60Days">60 day series</a> about Extended Events. This is not a short series but is designed to provide an array of topics to help learn the tool over time.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4346" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/03/09/extended-events-file-initialization-failure/">Extended Events File Initialization Failure</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/03/09/extended-events-file-initialization-failure/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Profiler for Extended Events: Quick Settings</title>
		<link>https://jasonbrimhall.info/2018/03/05/profiler-for-extended-events-quick-settings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=profiler-for-extended-events-quick-settings</link>
					<comments>https://jasonbrimhall.info/2018/03/05/profiler-for-extended-events-quick-settings/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Mar 2018 21:44:50 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4337</guid>

					<description><![CDATA[<p>As of SSMS 17.4 we have been given the ability to control XEvents Profiler just a tiny bit more. For what it is worth, we as Database Professionals love to be able to control our database environment. So this teeny tiny bit of new control ability is potentially a huge win, right?</p>
The post <a href="https://jasonbrimhall.info/2018/03/05/profiler-for-extended-events-quick-settings/">Profiler for Extended Events: Quick Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/"><img loading="lazy" class="alignleft wp-image-3910" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile.png" alt="" width="160" height="159" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile.png 225w, https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile-50x50.png 50w" sizes="(max-width: 160px) 85vw, 160px" /></a>Not long ago, I wrote a rather long article about a new-ish feature within SQL Server Management Studio (SSMS) that impacted Extended Events. You can read that book &#8211; <a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">here</a>! The XEvents Profiler feature is one of those things that you may or may not use. If you consider using the feature, I do believe it is important that you research it a bit and try to learn the pros and cons first.</p>
<p>With that there is a little more about the feature that the aforementioned <a href="http://bit.ly/2BkPBGC">book</a> did not cover. In fact, this information has pretty much gone ignored and mostly stays hidden under the covers.</p>
<h2>Settings</h2>
<p>As of SSMS 17.4 we have been given the ability to control XEvents Profiler just a tiny bit more. For what it is worth, we as Database Professionals love to be able to control our database environment. So this teeny tiny bit of new control ability is potentially a huge win, right?</p>
<p>If you are the controlling type, or maybe just the curious type, you will be pleased to know that under &#8220;Options&#8221; from the Tools menu in SSMS, Microsoft has tucked some new control options to help you configure XEvents Profiler &#8211; to a degree. If you open options, you will see this new node.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4340" src="http://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options-1024x683.jpg" alt="" width="560" height="374" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options-1024x683.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options-300x200.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options-768x512.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options-50x33.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/03/xe_profiler_options.jpg 1075w" sizes="(max-width: 560px) 85vw, 560px" /></a>If you expand the &#8220;XEvent Profiler&#8221; node (circled in red), you will discover the &#8220;options&#8221; node. If you click on this &#8220;options&#8221; node and do a quick comparison (in SSMS 17.4 and SSMS 17.5) you will also find that you don&#8217;t need t expand the &#8220;XEvent Profiler&#8221; node at all because the options are listed in the right hand pane for both nodes and they are exactly the same. So, choose one or the other and you will end up at the same place.</p>
<p>The options that you currently have are:</p>
<ul>
<li>Stop Session on Viewer Closed</li>
<li>Toolbar commands stop and restart</li>
</ul>
<p>You can either set these options to True or False. I recommend you play with them a bit to discover which you really prefer. That said, I do prefer to have the &#8220;Stop Session on Viewer Closed&#8221; set to true. There is &#8220;profiler&#8221; in the name of the feature afterall. And if you have read the &#8220;<a href="http://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">book</a>&#8221; I wrote about this feature, you would know that the filtering offered by the default sessions of this feature basically turn on the fire hose effect and can have a negative impact on your server. Are you sure you want a profiler style fire hose running on your production server?</p>
<h2>Conclusion</h2>
<p>There surely will continue to be more development around this idea of an XE style profiler. More development generally means that the product will mature and get better over time. This article shows how there is more being added to the feature to try and give you better control over the tool. We love control so the addition of these options is actually a good thing. Is it enough to sway me away from using the already established, more mature, and high performing tools that have been there for several generations? Nope! I will continue to use TSQL and the GUI tools available for XE that predated the XEvent Profiler.</p>
<p>Some say this is a way of bridging the gap. In my opinion, that gap was already bridged with the GUI that has been available for several years. Some say that maybe this tool needs to integrate a way to shred XML faster. To that, I say there are methods already available for that such as Powershell, the live data viewer, the Target Data viewer, or even my tools I have provided in the <a href="http://bit.ly/XE60Days">60 day series</a>.</p>
<p>I would challenge those that are still unfamiliar with the XE GUI (out for nearly 6 years now) to go and read some of my articles or articles by Jonathan Kehayias about the power that is in XE as well as some of the power in the GUI.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4337" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/03/05/profiler-for-extended-events-quick-settings/">Profiler for Extended Events: Quick Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/03/05/profiler-for-extended-events-quick-settings/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server User Already Exists &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/01/24/sql-server-user-already-exists-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-user-already-exists-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/01/24/sql-server-user-already-exists-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 24 Jan 2018 14:32:42 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4324</guid>

					<description><![CDATA[<p>One of my all-time favorite things in SQL Server is security. No matter what, it always seems that there is a new way to abuse permissions. When people abuse their access level or abuse the way permissions should be set in a SQL Server environment, we get the pleasure of both fixing it and then trying to educate them on why what they did was wrong and how to do it the right way.</p>
The post <a href="https://jasonbrimhall.info/2018/01/24/sql-server-user-already-exists-back-to-basics/">SQL Server User Already Exists – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png"><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="" width="208" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 208px) 85vw, 208px" /></a></p>
<p>One of my all-time favorite things in SQL Server is security. No matter what, it always seems that there is a new way to abuse permissions. When people abuse their access level or abuse the way permissions should be set in a SQL Server environment, we get the pleasure of both fixing it and then trying to educate them on why what they did was wrong and how to do it the right way.</p>
<p>In similar fashion, I previously wrote about some fundamental misconceptions about permissions <a href="http://jasonbrimhall.info/2017/03/02/sql-server-permissions-database-roles/">here</a> and <a href="http://bit.ly/2mMcYp2">here</a>. I have to bring those specific articles up because this latest experience involves the basics discussed in those articles along with a different twist.</p>
<p>I do hope that there is something you will be able to learn from this basics article. If you are curious, there are <a href="http://jasonbrimhall.info/tag/back-to-basics/">more basics articles on my blog &#8211; here</a>.</p>
<h2>Gimme Gimme Gimme&#8230;</h2>
<p>It is not uncommon to need to create a login and grant that login access to a database (or associate that login to a database user. In fact, that is probably a fairly routine process. It is so routine, that I have a demo script for it right here.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [master]
GO
IF EXISTS	(SELECT 1/0 FROM sys.databases WHERE name = 'GimmeSA')
BEGIN
DROP DATABASE GimmeSA;
END

CREATE DATABASE [GimmeSA];

IF NOT EXISTS (SELECT 1/0 FROM sys.server_principals WHERE name = 'IMustHaveSA')
BEGIN
SELECT 'IMustHaveSA Does NOT Exist - Create the login'
CREATE LOGIN [IMustHaveSA] WITH PASSWORD=N'weakpassword', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF;
END


USE [GimmeSA]
GO
CREATE USER [IMustHaveSA] FOR LOGIN [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_accessadmin] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_backupoperator] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_datareader] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_datawriter] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_ddladmin] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_owner] ADD MEMBER [IMustHaveSA]
GO
USE [GimmeSA]
GO
ALTER ROLE [db_securityadmin] ADD MEMBER [IMustHaveSA]
GO</pre><p>I even went as far as to include some of the very routine mistakes I see happening on a frequent basis (as referenced by a <a href="http://bit.ly/2lZGEM2">prior post here</a>).</p>
<p>To this point, we only have a mild abuse of how to set permissions for a principal. Now it is time for that twist I mentioned. This user account needs to be created on a secondary server that is participating in either a mirror or an Availability Group. Most people will take that user account that was just created on the first server and then use the same script to add the account to the secondary server. Let&#8217;s see how that might look.</p>
<p>For this example, I will not go to the extent of creating the mirror or AG. Rather, I will pretend I am just moving the database to a new server. So I have taken a backup and then I will restore the database to the new server.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [master]
RESTORE DATABASE [GimmeSA] FROM  DISK = N'C:\Database\GimmeSA.bak' 
WITH  FILE = 1
,  MOVE N'GimmeSA' TO N'D:\SQL16\Data\GimmeSA.mdf'
,  MOVE N'GimmeSA_log' TO N'D:\SQL16\Log\GimmeSA_log.ldf',  NOUNLOAD,  STATS = 5, replace

GO</pre><p>Next, let&#8217;s go ahead and recreate the login we created on the previous server.</p><pre class="urvanov-syntax-highlighter-plain-tag">IF NOT EXISTS (SELECT 1/0 FROM sys.server_principals WHERE name = 'IMustHaveSA')
BEGIN
SELECT 'IMustHaveSA Does NOT Exist - Create the login'
CREATE LOGIN [IMustHaveSA] WITH PASSWORD=N'weakpassword', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF;
END</pre><p>You see here that I am only going to create the login if it does not exist already. Running the script produces the following for me.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist.png"><img loading="lazy" class="aligncenter size-large wp-image-4331" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist-1024x441.png" alt="" width="560" height="241" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist-1024x441.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist-300x129.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist-768x330.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist-50x22.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_doesnotexist.png 1490w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Now, let&#8217;s deviate a bit and grant permissions for the login just like so many administrators will do.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser.png"><img loading="lazy" class="aligncenter size-large wp-image-4332" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser-1024x840.png" alt="" width="560" height="459" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser-1024x840.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser-300x246.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser-768x630.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser-50x41.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/login_notmappedtouser.png 1163w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>It seems pretty apparent that my login that I just created does not have access to the GimmeSA database, right? Let&#8217;s go ahead and add permissions to the GimmeSA database and see what happens.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan.png"><img loading="lazy" class="aligncenter size-large wp-image-4333" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan-1024x843.png" alt="" width="560" height="461" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan-1024x843.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan-300x247.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan-768x632.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan-50x41.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/permissions_error_orphan.png 1167w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Well, that did not work according to plan right? Enter twist the second.</p>
<p>What I am seeing more and more of, is people at this point will just grant that login (that was just created) sysadmin rights. You can pick up your jaw now. Indeed! People are just granting the user SA permissions and calling it good. This practice will certainly work &#8211; or appear to work. The fact is, the problem is not fixed. This practice has only camouflaged the problem and it will come back at some future date. That date may be when somebody like me comes along and starts working on stripping non-essential sysadmins from the system.</p>
<p>There are two legitimate fixes for this particular problem (and no granting sysadmin is definitely not one of them). First you can run an orphan fix with a <a href="http://blogs.lessthandot.com/index.php/datamgmt/dbprogramming/fixing-orphaned-database-users/" class="broken_link">script such as this one by Ted Krueger.</a> That will map the user that already exists in the database to the login principal (thus the reason for the error we saw). Or, you can prep your environment better by using the SID syntax with the create login as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE LOGIN TestLogin WITH PASSWORD = 'SuperSecret52&amp;&amp;'
, SID = 0x241C11948AEEB749B0D22646DB1A19F2;</pre><p>The trick here is to go and lookup the SID for the login on the old server first and then use that sid to create the login on the new server. This will preserve the user to login mappings and prevent the orphan user issue we just saw. It will also prevent the band-aid need of adding the login to the sysadmin server role.</p>
<h2>The Wrap</h2>
<p>In this article I have introduced you to some basics in regards to creating and synchronizing principals across different servers. Sometimes we try to shortcut the basics and apply band-aids that make absolutely no sense from either a practical point of view or a security point of view. Adhering to better practices will ease your administration burden along with improving your overall security presence.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4324" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/01/24/sql-server-user-already-exists-back-to-basics/">SQL Server User Already Exists – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/01/24/sql-server-user-already-exists-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Database Corruption and IO Errors</title>
		<link>https://jasonbrimhall.info/2018/01/18/database-corruption-and-io-errors/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-corruption-and-io-errors</link>
					<comments>https://jasonbrimhall.info/2018/01/18/database-corruption-and-io-errors/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 18 Jan 2018 14:49:58 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[CheckDB]]></category>
		<category><![CDATA[Corruption]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4234</guid>

					<description><![CDATA[<p>A quick way to have your day turned upside down and rip your gut out with nerves and anxiety is to come in one day to find that users are panicked, applications are not working and the HelpDesk team is curled up in the fetal position in the corner. Why? The sky is falling and everybody thinks the database has blown up. You appear to have a corrupt database and nasty IO errors.</p>
The post <a href="https://jasonbrimhall.info/2018/01/18/database-corruption-and-io-errors/">Database Corruption and IO Errors</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>A quick way to have your day turned upside down and rip your gut out with nerves and <a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/stop_corruptdb_shad.png"><img loading="lazy" class=" wp-image-4240 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/stop_corruptdb_shad.png" alt="" width="241" height="132" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/stop_corruptdb_shad.png 640w, https://jasonbrimhall.info/wp-content/uploads/2018/01/stop_corruptdb_shad-300x164.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/stop_corruptdb_shad-50x27.png 50w" sizes="(max-width: 241px) 85vw, 241px" /></a>anxiety is to come in one day to find that users are panicked, applications are not working and the HelpDesk team is curled up in the fetal position in the corner. Why? The sky is falling and everybody thinks the database has blown up.</p>
<p>Calmly, you settle in and check the server and eventually find your way to the error logs to see the following:</p>
<blockquote><p><span style="color: #ff0000;"><span style="text-decoration: underline;"><strong>Msg 823</strong></span>, Level 24, State 2, Line 1</span></p>
<p><span style="color: #ff0000;"><span style="text-decoration: underline;"><strong>The operating system returned error 1(Incorrect function.)</strong></span> to SQL Server during a read at offset 0x0000104c05e000 in file &#8216;E:\Database\myproddb.mdf&#8217;. Additional messages in the SQL Server error log and system event log may provide more detail. This is a severe system-level error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.</span></p></blockquote>
<p>Suddenly you understand and feel the collective fear and paranoia. What do you do now that the world has seemingly come to an end for your database?</p>
<h3>Corruption</h3>
<p>What exactly does this error message mean? Well, <a href="https://support.microsoft.com/en-us/help/2015755/how-to-troubleshoot-a-msg-823-error-in-sql-server">typically, an 823 error is a very strong indicator that there is some sort of problem with the storage system, hardware or driver that is in the path of the I/O request</a>.</p>
<p>Great! That fear is getting a little heavier knowing what the error represents. This doesn&#8217;t bode well for the database. Let&#8217;s go ahead and crack out the list of what we can do or check when a problem like this hits:</p>
<ol>
<li>Check msdb.dbo.suspect_pages</li>
<li>Run a consistency check for all databases on the same volume</li>
<li>Check Logs (SQL, Windows, Storage system) to see if there may be additional info (via different errors/warnings) in close proximity to the 823 error.</li>
<li>Check your drivers</li>
<li>Restore the database</li>
</ol>
<p>This is where your experience, training, and preparedness come in handy. An experienced data professional will be prepared with database backups (including log backups). So you are not concerned here because all of your backups are reporting successful. As you prep to pull the backups (for the past couple of days just in case) you notice that there are no available backups in your repository. Looking closer at your backup jobs you discover that the backups completed in mere seconds where they normally take hours for this database.</p>
<p>Now that your heart is racing, forehead is beading up with sweat, gut is sinking and the fear is very palpable &#8211; what do you do? Time to step through the rest of the steps and pull out your lucky charms, right?</p>
<p>Querying against suspect_pages, you find the table to be completely empty. You know that checkdb runs regularly but maybe it didn&#8217;t run last night. That is easy enough to check with a <a href="http://jasonbrimhall.info/2013/01/17/last-time-checkdb-was-run/">little query from here</a>. Since a consistency check does not seem to have run (as confirmed by the <a href="http://jasonbrimhall.info/2013/01/17/last-time-checkdb-was-run/">script</a>) and is the second item on the checklist, let&#8217;s go ahead and run it now.</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">Msg 0, Level 11, State 0, Line 0</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">A severe error occurred on the current command.  The results, if any, should be discarded.</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">Msg 0, Level 20, State 0, Line 0</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">A severe error occurred on the current command.  The results, if any, should be discarded.</p>
</blockquote>
<p>Crud. Blood pressure and nerves are getting a little more frazzled now. Maybe we can cycle through the database and find which table is causing the problem. Let&#8217;s try a checktable of every table in the database. Before doing the checktable, one more check against suspect_pages still shows no rows to be found.</p>
<p>Running the checktable, every table is coming up clean except one. That one table produces the same sort of error as the checkdb and just so happens to be the largest and most critical table to the database. Blood pressure is closing in on critical now. We have a corruption issue that is severe enough that checktable cannot complete, we know we have 823 errors and some sort of IO issue and do not have a backup.</p>
<p>Wait&#8230;backup. Let&#8217;s try to force a backup and see what happens. We can tell the backup to continue after error so let&#8217;s see what happens. Maybe that will allow you to move the database to a different server or different spindles to try and just recover the data.</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">Msg 3202, Level 16, State 2, Line 1</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">Write on &#8220;E:\SQLBackups\myproddb.bak&#8221; failed: <span style="text-decoration: underline;">1(Incorrect function.)</span></p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">Msg 3013, Level 16, State 1, Line 1</p>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt; color: red;">BACKUP DATABASE is terminating abnormally.</p>
</blockquote>
<p>The situation just does not want to get any better at this point. Time for drastic measures &#8211; shut down the SQL Server services and try to xcopy the data and log files to a different server and try to re-attach from there. Anything is worth a shot, right?</p>
<blockquote>
<p style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"><span style="color: #ff0000;">Error 1: Incorrect Function</span></p>
</blockquote>
<p>Glad to know it is not just SQL Server throwing the errors &#8211; sorta. The corruption is ever present and there is nothing more that can be done, right? All hope is lost. Time to fill out the resume and move on to something else, right? Give it one more shot. A spark of insanity hits and you wonder if a mere query against the clustered index will work, if not then maybe something against any of the indexes to try and spare any data at all.</p>
<p>You rub your luck horseshoe and query the table (yes the table that checktable aborts because of corruption). Lo and behold you get results from this very simple query. How is that possible. On a whim, you drop all the Non-Clustered Indexes and try a fresh backup.</p>
<p>Hallelujah! The backup completes without error. Time to take this backup and restore the database to a completely different server. Then on the new server run a consistency check to determine if it is all clear. To your liking, there is absolutely no corruption at this point so the non-clustered indexes can be recreated (easy to do because you have a script with the index definitions handy).</p>
<h3>Wrap</h3>
<p>This journey from fire and brimstone and the world ending to the epiphany and then the sweet euphoric feelings of success is not a normal resolution for these types of errors. This sort of thing happened for a client that called trying to get around the 823 errors. We had absolutely no indication whatsoever of where the corruption was beyond knowing we had failing disks at the time. We got lucky in that the non-clustered indexes in this case ended up being stored on the bad sectors and dropping those indexes allowed us to recover the database and make it usable.</p>
<p>When everything is breaking, the unconventional thought (especially without having a checkdb complete to tell you which index or which pages are corrupt) of dropping indexes may just save your bacon. It saved my clients bacon!</p>
<p>As a follow-up item, it is important to regularly check the dbccLastKnownGood for each database. That can be done by following the <a href="http://bit.ly/WKK7IF">script in this article</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4234" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/01/18/database-corruption-and-io-errors/">Database Corruption and IO Errors</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/01/18/database-corruption-and-io-errors/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server Configurations &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/01/11/sql-server-configurations-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-configurations-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/01/11/sql-server-configurations-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 11 Jan 2018 14:11:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4196</guid>

					<description><![CDATA[<p>One thing that SQL Server does very well is come pre-configured in a lot of ways. These pre-configured settings would be called defaults. Having default settings is not a bad thing nor is it necessarily a good thing.</p>
The post <a href="https://jasonbrimhall.info/2018/01/11/sql-server-configurations-back-to-basics/">SQL Server Configurations – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/hdog_assemblyreq.png"><img loading="lazy" class="alignright wp-image-4197 " src="http://jasonbrimhall.info/wp-content/uploads/2018/01/hdog_assemblyreq.png" alt="" width="256" height="325" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/hdog_assemblyreq.png 543w, https://jasonbrimhall.info/wp-content/uploads/2018/01/hdog_assemblyreq-236x300.png 236w, https://jasonbrimhall.info/wp-content/uploads/2018/01/hdog_assemblyreq-39x50.png 39w" sizes="(max-width: 256px) 85vw, 256px" /></a></p>
<p>One thing that SQL Server does very well is come pre-configured in a lot of ways. These pre-configured settings would be called defaults. Having default settings is not a bad thing nor is it necessarily a good thing.</p>
<p>For me, the defaults lie somewhere in the middle ground and they are kind of just there. You see, having defaults can be good for a horde of people. On the other hand, the default settings can be far from optimal for your specific conditions.</p>
<p>The real key with default settings is to understand what they are and how to get to them. This article is going to go through some of the basics around one group of these defaults. That group of settings will be accessible via the sp_configure system stored procedure. You may already know some of these basics, and that is ok.</p>
<p>I do hope that there is something you will be able to learn from this basics article. If you are curious, there are <a href="http://jasonbrimhall.info/tag/back-to-basics/">more basics articles on my blog &#8211; here</a>.</p>
<h2>Some Assembly Required&#8230;</h2>
<p><img loading="lazy" class="alignright wp-image-4198" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/setitforgetit.jpg" alt="" width="191" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/setitforgetit.jpg 500w, https://jasonbrimhall.info/wp-content/uploads/2018/01/setitforgetit-300x291.jpg 300w" sizes="(max-width: 191px) 85vw, 191px" /></p>
<p>Three dreaded words we all love to despise but have learned to deal with over the past several years &#8211; some assembly required. More and more we find ourselves needing to assemble our own furniture, bookcases, barbecue grills, and bathroom sinks. We do occasionally want some form of set and forget it.</p>
<p>The problem with set it and forget it type of settings (or defaults) is as I mentioned &#8211; they don&#8217;t always work for every environment. We do occasionally need to manually adjust settings for what is optimal for that <a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/db_burning.jpg"><img loading="lazy" class=" wp-image-4199 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/db_burning.jpg" alt="" width="145" height="181" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/db_burning.jpg 200w, https://jasonbrimhall.info/wp-content/uploads/2018/01/db_burning-40x50.jpg 40w" sizes="(max-width: 145px) 85vw, 145px" /></a>database, server, and/or environment.</p>
<p>When we fail to reconfigure the defaults, we could end up with a constant firefight that we just don&#8217;t ever seem to be able to win.</p>
<p>So how do we find some of these settings that can help us customize our environment for the better (or worse)? Let&#8217;s start taking a crack at this cool procedure called sp_configure! Ok, so maybe I oversold that a bit &#8211; but there is some coolness to it.</p>
<p>Looking at <a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-configure-transact-sql">msdn about sp_configure</a> I can see that it is a procedure to display or change global configuration settings for the current server.</p>
<p>If I run sp_configure without any parameters, I will get a complete result set of the configurable options via this procedure. Let&#8217;s look at how easy that is:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4202" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms-912x1024.jpg" alt="" width="560" height="629" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms-912x1024.jpg 912w, https://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms-267x300.jpg 267w, https://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms-768x862.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms-45x50.jpg 45w, https://jasonbrimhall.info/wp-content/uploads/2018/01/spconfigure_noparms.jpg 986w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Ok, so that was exceptionally easy. I can see that the procedure returns the configurable settings, the max value for the setting, configured value, and the running value for each setting. That is basic information, right? If I want a little more detailed information, guess what? I can query a catalog view to learn even more about the configurations &#8211; sys.configurations.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
	FROM sys.configurations c
	ORDER BY c.name;</pre><p>That query will also show me (in addition to what I already know from sp_configure) a description for each setting, if the setting is a dynamic setting and whether or not the setting is an advanced configuration (and thus requires &#8220;show advanced options&#8221; to be enabled). Pro-tip: The procedure just queries the catalog view anyway. Here is a snippet from the proc text.</p><pre class="urvanov-syntax-highlighter-plain-tag">-- If no option name is given, the procedure will just print out all the
	--  options and their values.
	if @configname is NULL
	begin
		select name,
			convert(int, minimum) as minimum,
			convert(int, maximum) as maximum,
			convert(int, isnull(value, value_in_use)) as config_value,
			convert(int, value_in_use) as run_value
		from  sys.configurations
		where (is_advanced = 0 or @show_advance = 1)
		order by lower(name)

		return (0)
	end</pre><p>Seeing that we have some configurations that are advanced and there is this option called &#8220;show advanced options&#8221;, let&#8217;s play a little bit with how to enable or disable that setting.</p><pre class="urvanov-syntax-highlighter-plain-tag">sp_configure 'show advanced options',1</pre><p>With the result (on my system) being:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4203" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1-1024x209.jpg" alt="" width="560" height="114" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1-1024x209.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1-300x61.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1-768x157.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1-50x10.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/showadvanced_1.jpg 1557w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>We can see there that the configuration had no effect because I already had the setting enabled. Nonetheless, the attempt to change still succeeded. Let&#8217;s try it a different way.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts.jpg"><img loading="lazy" class="aligncenter size-large wp-image-4204" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts-1024x547.jpg" alt="" width="560" height="299" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts-1024x547.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts-300x160.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts-768x410.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts-50x27.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_shortcuts.jpg 1635w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I ran a whole bunch of variations there for giggles. Notice how I continue to try different words or length of words until it finally errors? All of them have the same net effect (except the attempt that failed) they will change the configuration &#8220;show advanced options&#8221;. This is because all that is required (as portrayed in the failure message) is that the term provided is enough to make it unique. The uniqueness requirement (shortcut) is illustrated by this code block from sp_configure.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique.png"><img loading="lazy" class="aligncenter size-large wp-image-4205" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique-1024x698.png" alt="" width="560" height="382" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique-1024x698.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique-300x204.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique-768x523.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique-50x34.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/config_unique.png 1384w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>See the use of the wildcards and the &#8220;like&#8221; term? This is allowing us to shortcut the configuration name &#8211; as long as we use a unique term. If I select a term that is not unique, then the proc will output every configuration option that matches the term I used. From the example I used, I would get this output as duplicates to the term I used.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/duplicates.jpg"><img loading="lazy" class="aligncenter wp-image-4206" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/duplicates.jpg" alt="" width="315" height="176" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/duplicates.jpg 525w, https://jasonbrimhall.info/wp-content/uploads/2018/01/duplicates-300x167.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/duplicates-50x28.jpg 50w" sizes="(max-width: 315px) 85vw, 315px" /></a></p>
<p>Ah, I can see the option I need! I can now just copy and paste that option (for the sake of simplicity) into my query and just proceed along my merry way. This is a great shortcut if you can&#8217;t remember the exact full config name or if you happen to be really bad at spelling.</p>
<h2>The Wrap</h2>
<p>In this article I have introduced you to some basics in regards to default server settings and how to quickly see or change those settings. Not every environment is able to rely on set-it and forget-it type of defaults. Adopting the mentality that &#8220;some assembly is required&#8221; with your environments is a good approach. It will help keep you on top of your configurations at the bare minimum. This article will help serve a decent foundation for some near future articles. Stay tuned!</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4196" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/01/11/sql-server-configurations-back-to-basics/">SQL Server Configurations – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/01/11/sql-server-configurations-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Common Tempdb Trace Flags &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/01/05/common-tempdb-trace-flags-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=common-tempdb-trace-flags-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2018/01/05/common-tempdb-trace-flags-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 06 Jan 2018 03:14:14 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4182</guid>

					<description><![CDATA[<p>In this article I introduce you to some basics in regards to default behaviors and settings in tempdb along with some best practices. It is advisable to investigate from time to time some of these recommendations and confirm what we are really being told so we can avoid confusion and mis-interpretation.</p>
The post <a href="https://jasonbrimhall.info/2018/01/05/common-tempdb-trace-flags-back-to-basics/">Common Tempdb Trace Flags – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/day12.png"><img loading="lazy" class="alignright wp-image-4183 " src="http://jasonbrimhall.info/wp-content/uploads/2018/01/day12.png" alt="" width="150" height="245" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/day12.png 201w, https://jasonbrimhall.info/wp-content/uploads/2018/01/day12-184x300.png 184w, https://jasonbrimhall.info/wp-content/uploads/2018/01/day12-31x50.png 31w" sizes="(max-width: 150px) 85vw, 150px" /></a></p>
<p>Once in a while I come across something that sounds fun or interesting and decide to dive a little deeper into it. That happened to me recently and caused me to preempt my scheduled post and work on writing up something entirely different. Why? Because this seemed like fun and useful.</p>
<p>So what is it I am yammering on about that was fun?</p>
<p>I think we can probably concede that there are some best practices flying around in regards to the configuration of tempdb. One of those best practices is in regards to two trace flags within SQL Server. These trace flags are 1117 and 1118. <a href="https://www.brentozar.com/archive/2014/06/trace-flags-1117-1118-tempdb-configuration/">Here is a little bit of background on the trace flags and what they do</a>.</p>
<p>A caveat I have now for the use of trace flags is that I err on the same side as Kendra (author of the article just mentioned). I don&#8217;t generally like to enable trace flags unless it is <strong>very</strong> warranted for a <strong>very</strong> specific condition. As Kendra mentions, TF 1117 will impact more than just the tempdb data files. So use that one with caution.</p>
<h2>Ancient Artifacts</h2>
<p>With the release of SQL Server 2016, these trace flags were rumored to be a thing of the past and hence completely unnecessary. That is partially true. The trace flag is unneeded and SQL 2016 does have some different behaviors, but does that mean you have to do nothing to get the benefits of these Trace Flags as implemented in 2016?</p>
<p>As it turns out, these trace flags no longer do what they did in previous editions. SQL Server now pretty much has it baked into the product. Buuuuut, do you have to do anything slightly different to make it work? This was something I came across <a href="http://blog.waynesheffield.com/wayne/archive/2017/09/registry-sql-server-startup-parameters/">while reading this post</a> and wanted to double check everything. After all, I was also under the belief that it was automatically enabled. So let&#8217;s create a script that checks these things for me.</p><pre class="urvanov-syntax-highlighter-plain-tag">/*
http://blog.waynesheffield.com/wayne/archive/2017/09/registry-sql-server-startup-parameters/
https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-file-and-filegroup-options
https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-set-options

*/
USE tempdb;
GO

DECLARE @ServerMajorVersion DECIMAL(4, 2)
	, @TSQL VARCHAR(2048);

IF ( SELECT OBJECT_ID('tempdb..#dbsettings')) IS NOT NULL
	BEGIN
		DROP TABLE #dbsettings;
	END;
IF ( SELECT OBJECT_ID('tempdb..#tfstatus')) IS NOT NULL
	BEGIN
		DROP TABLE #tfstatus;
	END;
CREATE TABLE #tfstatus
	(
		TraceFlag INT
	, Status TINYINT
	, Global TINYINT
	, Session TINYINT
	);
CREATE TABLE #dbsettings
	(
		DBName VARCHAR(128)
	, DataFileName VARCHAR(128)
	, physical_name VARCHAR(1024)
	, FileGroupName VARCHAR(256)
	, is_mixed_page_allocation_on TINYINT
	, is_autogrow_all_files TINYINT
	, is_persistent_log_buffer TINYINT
	);

SELECT	@ServerMajorVersion = CONVERT(
								DECIMAL(4, 2)
								, PARSENAME(dt.fqn, 4) + '.'
								+ PARSENAME(dt.fqn, 3))
FROM	( SELECT	CONVERT(VARCHAR(20), SERVERPROPERTY('ProductVersion'))) dt(fqn);

SELECT	@ServerMajorVersion;

INSERT INTO #tfstatus ( TraceFlag
						, Status
						, Global
						, Session )
	EXECUTE ( 'DBCC TRACESTATUS' );

IF @ServerMajorVersion &lt; 13.00
	BEGIN

		SET @TSQL = 'SELECT	d.name AS DBName
			, df.name AS DataFileName
			, df.physical_name
			, fg.name as FileGroupName
			, NULL AS is_mixed_page_allocation_on
			, NULL AS is_autogrow_all_files
			, NULL AS is_persistent_log_buffer
		FROM	sys.databases d
				INNER JOIN sys.master_files mf
					ON d.database_id = mf.database_id
				INNER JOIN sys.database_files df
					ON mf.file_id = df.file_id
					AND mf.name = df.name COLLATE Latin1_General_CI_AI
				LEFT OUTER JOIN sys.filegroups fg
					ON df.data_space_id = fg.data_space_id;';

		INSERT INTO #dbsettings ( DBName
								, DataFileName
								, physical_name
								, FileGroupName
								, is_mixed_page_allocation_on
								, is_autogrow_all_files
								, is_persistent_log_buffer )
		EXECUTE ( @TSQL );

		SELECT	db.DBName
			, db.DataFileName
			, db.physical_name
			, CASE WHEN db.is_mixed_page_allocation_on IS NULL
						AND oa.TraceFlag IS NULL THEN
						'Mixed Page Alloc Not Enabled'
				END AS Feature
			, CASE WHEN db.is_mixed_page_allocation_on IS NULL
						AND oa.TraceFlag IS NULL THEN
						'DBCC TRACEON (1118, -1);'
				END AS EnableStatement
		FROM	#dbsettings db
				OUTER APPLY ( SELECT	TraceFlag
								FROM	#tfstatus tf
								WHERE tf.TraceFlag = 1118 ) oa
		WHERE is_mixed_page_allocation_on IS NULL
			AND db.FileGroupName IS NOT NULL
		UNION
		SELECT	db.DBName
			, db.DataFileName
			, db.physical_name
			, CASE WHEN db.is_autogrow_all_files IS NULL
						AND oa.TraceFlag IS NULL THEN
						'Even Data File Growth Not Enabled'
				END AS Feature
			, CASE WHEN db.is_autogrow_all_files IS NULL
						AND oa.TraceFlag IS NULL THEN
						'DBCC TRACEON (1117, -1);'
				END AS EnableStatement
		FROM	#dbsettings db
				OUTER APPLY ( SELECT	TraceFlag
								FROM	#tfstatus tf
								WHERE tf.TraceFlag = 1117 ) oa
		WHERE db.is_autogrow_all_files IS NULL
			AND db.FileGroupName IS NOT NULL;

		SELECT	d.DBName
			, d.DataFileName
			, d.physical_name
			, d.is_mixed_page_allocation_on
			, d.is_autogrow_all_files
			, d.is_persistent_log_buffer
		FROM	#dbsettings d;
	END;

IF @ServerMajorVersion &gt;= 13.00
	BEGIN
		SET @TSQL = 'SELECT	d.name AS DBName
			, df.name AS DataFileName
			, df.physical_name
			, fg.name as FileGroupName
			, d.is_mixed_page_allocation_on
			, fg.is_autogrow_all_files
			, mf.is_persistent_log_buffer
		FROM	sys.databases d
				INNER JOIN sys.master_files mf
					ON d.database_id = mf.database_id
				INNER JOIN sys.database_files df
					ON mf.file_id = df.file_id
					AND mf.name = df.name COLLATE Latin1_General_CI_AI
				LEFT OUTER JOIN sys.filegroups fg
					ON df.data_space_id = fg.data_space_id;';

		INSERT INTO #dbsettings ( DBName
								, DataFileName
								, physical_name
								, FileGroupName
								, is_mixed_page_allocation_on
								, is_autogrow_all_files
								, is_persistent_log_buffer )
		EXECUTE ( @TSQL );
		
		--just to check for giggles
		--SELECT	*
		--FROM	#tfstatus;

		SELECT	db.DBName
			, db.DataFileName
			, db.physical_name
			, CASE WHEN db.is_mixed_page_allocation_on = 1 THEN
						'Mixed Page Alloc Is Enabled'
				END AS Feature
			, CASE WHEN db.is_mixed_page_allocation_on = 1 THEN
						'ALTER DATABASE [' + db.DBName
						+ '] SET MIXED_PAGE_ALLOCATIONS OFF;'
				END AS EnableStatement
		FROM	#dbsettings db
				OUTER APPLY ( SELECT	TraceFlag
								FROM	#tfstatus tf
								WHERE tf.TraceFlag = 1118 ) oa
		WHERE is_mixed_page_allocation_on &lt;&gt; 0
			AND db.FileGroupName IS NOT NULL
		UNION
		SELECT	db.DBName
			, db.DataFileName
			, db.physical_name
			, CASE WHEN db.is_autogrow_all_files IS NULL
						AND oa.TraceFlag IS NULL THEN
						'Even Data File Growth Not Enabled'
				END AS Feature
			, CASE WHEN db.is_autogrow_all_files = 0 THEN
						'ALTER DATABASE [' + db.DBName
						+ '] MODIFY FILEGROUP [' + FileGroupName
						+ '] AUTOGROW_ALL_FILES;'
				END AS EnableStatement
		FROM	#dbsettings db
				OUTER APPLY ( SELECT	TraceFlag
								FROM	#tfstatus tf
								WHERE tf.TraceFlag = 1117 ) oa
		WHERE db.is_autogrow_all_files &lt;&gt; 1
			AND db.FileGroupName IS NOT NULL;

		SELECT	d.DBName
			, d.DataFileName
			, d.physical_name
			, d.FileGroupName
			, d.is_mixed_page_allocation_on
			, d.is_autogrow_all_files
			, d.is_persistent_log_buffer
		FROM	#dbsettings d;

		IF EXISTS ( SELECT		*
					FROM	#tfstatus
					WHERE TraceFlag IN ( 1117, 1118 ))
			BEGIN
				SELECT	'One or Both Trace Flags (1117 &amp; 1118) is/are enabled and has NO EFFECT. Please Disable' AS Warning
					, 'DBCC TRACEOFF (1117, 1118, -1);' AS DisableStatement;
			END;

	END;</pre><p>Holy cannoli batman &#8211; that is more than a simple script, right? Well, it may be a bit of overkill. I wanted it to work for version before and after and including SQL Server 2016 (when these sweeping changes went into effect). You see, I am checking for versions where the TF was required to make the change and also for versions after the change where the TF has no effect. In 2016 and later, these settings are database scoped and the TF is unnecessary.</p>
<p>The database scoped settings can actually be queried in 2016 more specifically with the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT	d.name AS DBName
			, df.name AS DataFileName
			, df.physical_name
			, fg.name as FileGroupName
			, d.is_mixed_page_allocation_on
			, fg.is_autogrow_all_files
			, mf.is_persistent_log_buffer
		FROM	sys.databases d
				INNER JOIN sys.master_files mf
					ON d.database_id = mf.database_id
				INNER JOIN sys.database_files df
					ON mf.file_id = df.file_id
					AND mf.name = df.name COLLATE Latin1_General_CI_AI
				LEFT OUTER JOIN sys.filegroups fg
					ON df.data_space_id = fg.data_space_id;</pre><p>In this query, I am able to determine if mixed_page_allocations and if is_autogrow_all_files are enabled. These settings can be retrieved from sys.databases and sys.filegroups respectively. If I run this query on a server where the defaults were accepted during the install, I would see something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results.jpg"><img loading="lazy" class="size-large wp-image-4188 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results-1024x108.jpg" alt="" width="560" height="59" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results-1024x108.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results-300x32.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results-768x81.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results-50x5.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/tempdb_tf_results.jpg 1379w" sizes="(max-width: 560px) 85vw, 560px" /></a>You can see here, the default settings on my install show something different than the reported behavior. While autogrow all files is enabled, mixed_page_allocations is disabled. This matches what we expect to see by enabling the Trace Flags 1117 and 1118 &#8211; for the tempdb database at least. If I look at a user database, I will find that mixed pages is disabled by default still but that autogrow_all_files is also disabled.</p>
<p>In this case, you may or may not want a user database to have all data files grow at the same time. That is a great change to have implemented in SQL Server with SQL 2016. Should you choose to enable it, you can do so on a database by database basis.</p>
<p>As for the trace flags? My query checks to see if maybe you enabled them on your instance or if you don&#8217;t have them enabled for the older versions of SQL Server. Then the script generates the appropriate action scripts and allows you to determine if you want to run the generated script or not. And since we are changing trace flags (potentially) I recommend that you also look at this article of mine that discusses how to <a href="http://bit.ly/ssgflagcapture">audit the changing of trace flags</a>. And since that is an XEvent based article, <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">I recommend freshening up on XEvents with this series too</a>!</p>
<h2>The Wrap</h2>
<p>In this article I have introduced you to some basics in regards to default behaviors and settings in tempdb along with some best practices. It is advisable to investigate from time to time some of these recommendations and confirm what we are really being told so we can avoid confusion and mis-interpretation.</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4182" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/01/05/common-tempdb-trace-flags-back-to-basics/">Common Tempdb Trace Flags – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/01/05/common-tempdb-trace-flags-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Changing Default Logs Directory &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=changing-default-logs-directory</link>
					<comments>https://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 05 Jan 2018 01:25:12 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSG Syndication]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jasonbrimhall.info/?p=4168</guid>

					<description><![CDATA[<p>In this article I will explore altering the default logs directory location. Some may say this is no big deal and you can just use the default location used during install. Fair enough, there may not be massive need to change that location</p>
The post <a href="https://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/">Changing Default Logs Directory – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/day11.png"><img loading="lazy" class="alignright wp-image-4169 " src="http://jasonbrimhall.info/wp-content/uploads/2018/01/day11.png" alt="" width="151" height="222" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/day11.png 218w, https://jasonbrimhall.info/wp-content/uploads/2018/01/day11-204x300.png 204w, https://jasonbrimhall.info/wp-content/uploads/2018/01/day11-34x50.png 34w" sizes="(max-width: 151px) 85vw, 151px" /></a></p>
<p>Every now and then I find a topic that seems to fit perfectly into the mold of the theme of &#8220;Back to Basics&#8221;. A couple of years ago, there was a challenge to write a series of posts about basic concepts. Some of <a href="http://jasonbrimhall.info/tag/back-to-basics/">my articles in that series can be found here</a>.</p>
<p>Today, my topic to discuss is in regards to altering the default logs directory location. Some may say this is no big deal and you can just use the default location used during install. Fair enough, there may not be massive need to change that location.</p>
<p>Maybe, just maybe, there is an overarching need to change this default. Maybe you have multiple versions of SQL Server in the enterprise and just want a consistent folder to access across all servers so you don&#8217;t have to think too much. Or possibly, you want to copy the logs from multiple servers to a common location on a central server and don&#8217;t want to have to code for a different directory on each server.</p>
<p>The list of reasons can go on and I am certain I would not be able to list all of the really good reasons to change this particular default. Suffice it to say, there are some really good requirements out there (and probably some really bad ones too) that mandate the changing of the default logs directory to a new standardized location.</p>
<h2>Changes</h2>
<p>The logs that I am referring to are not the transaction logs for the databases &#8211; oh no no no! Rather, I am referring to the error logs, the mini dumps, and the many other logs that may fall into the traditional &#8220;logs&#8221; folder during the SQL Server install. Let&#8217;s take a peek at a default log directory after the install is complete.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs.jpg"><img loading="lazy" class="size-large wp-image-4171 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs-1024x612.jpg" alt="" width="560" height="335" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs-1024x612.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs-300x179.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs-768x459.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs-50x30.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/freshinstall_logs.jpg 1485w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I picked a demo server that has a crap load of stuff available (and yeah not so fresh after install) but where the installation placed the logs by default. You can see I have traces, default XE files, some SQL logs, and some dump files. There is plenty going on with this server. A very fresh install would have similar files but not quite as many.</p>
<p>If I want to change the Log directory, it is a pretty easy change but it does require a service restart.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir.png"><img loading="lazy" class="size-large wp-image-4172 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir-1024x837.png" alt="" width="560" height="458" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir-1024x837.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir-300x245.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir-768x628.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir-50x41.png 50w, https://jasonbrimhall.info/wp-content/uploads/2018/01/change_logdir.png 1043w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In SQL Server Configuration Manager, navigate to services then to &#8220;SQL Server Service&#8221;. Right click that service and select properties. From properties, you will need to select the &#8220;Startup Parameters&#8221; tab. Select the parameter with the &#8220;-e&#8221; and errorlog in the path. Then you can modify the path to something more appropriate for your needs and then simply click the update button. After doing that, click the ok button and bounce the SQL Service.</p>
<p>After you successfully bounce the service, you can confirm that the error logs have been migrated to the correct folder with a simple check. Note that this change impacts the errorlogs, the default Extended Events logging directory, the default trace directory, the dumps directory and many other things.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir.png"><img loading="lazy" class="size-full wp-image-4173 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir.png" alt="" width="977" height="344" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir.png 977w, https://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir-300x106.png 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir-768x270.png 768w, https://jasonbrimhall.info/wp-content/uploads/2018/01/new_logdir-50x18.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>See how easy that was? Did that move everything over for us? As it turns out, it did not. The old directory will continue to have the SQL Agent logs. We can see this with a check from the Agent log properties like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/default_agentlogdir.jpg"><img loading="lazy" class="size-full wp-image-4174 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/default_agentlogdir.jpg" alt="" width="706" height="634" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/default_agentlogdir.jpg 706w, https://jasonbrimhall.info/wp-content/uploads/2018/01/default_agentlogdir-300x269.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/default_agentlogdir-50x45.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>To change this, I can execute a simple stored procedure in the msdb database and then bounce the sql agent service.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
EXECUTE dbo.sp_set_sqlagent_properties 
	@errorlog_file=N'D:\Logging\SQLAGENT.OUT'
GO</pre><p>With the agent logs now writing to the directory verified after agent service restart as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2018/01/changed_agentlogdir.jpg"><img loading="lazy" class="size-full wp-image-4175 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2018/01/changed_agentlogdir.jpg" alt="" width="605" height="213" srcset="https://jasonbrimhall.info/wp-content/uploads/2018/01/changed_agentlogdir.jpg 605w, https://jasonbrimhall.info/wp-content/uploads/2018/01/changed_agentlogdir-300x106.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2018/01/changed_agentlogdir-50x18.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>At this point, all that will be left in the previous folder will be the files that were written prior to the folder changes and the service restarts.</p>
<h2>The Wrap</h2>
<p>In this article I have introduced you to an easy method to move the logs for SQL Server and the SQL Server Agent to a custom directory that better suits your enterprise needs. This concept is a basic building block for some upcoming articles &#8211; stay tuned!</p>
<p>This has been another post in the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=4168" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/">Changing Default Logs Directory – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2018/01/04/changing-default-logs-directory/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>An Identity Crisis: Is it Profiler or is it Extended Events?</title>
		<link>https://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=an-identity-crisis-is-it-profiler-or-is-it-extended-events</link>
					<comments>https://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 22 Dec 2017 16:40:37 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3908</guid>

					<description><![CDATA[<p>Despite it being new, it seems there are a handful of "facts" already published about it that may or may not be accurate. Due to that, I want to play a little game of fact or fiction with it in this article.</p>
The post <a href="https://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">An Identity Crisis: Is it Profiler or is it Extended Events?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I have been working on this article for far longer than one might think is necessary for <a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile.png"><img loading="lazy" class="wp-image-3910 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile.png" alt="" width="160" height="159" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile.png 225w, https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2017/12/database_fingerprint_profile-50x50.png 50w" sizes="(max-width: 160px) 85vw, 160px" /></a>something of this nature. Truth be told, I was reluctant because there are so many people that quickly jumped on the wagon to write about this feature as soon as it was released. With some coercing, here the article is finally!</p>
<p>What is this newfangled feature? Well, that is kind of the problem. The name has already changed in the second release &#8211; be it ever so slightly. The feature is XE Profiler or XEvents Profiler and in theory it is supposed to give us something new in management studio.</p>
<h2>Fact or Fiction</h2>
<p>This Extended Events Profiler is a brand spanking new feature (ok, so the bouncing baby is a few months old now and no longer a newborn). Despite it being new, it seems there are a handful of &#8220;facts&#8221; already published about it that may or may not be accurate. Due to that, I want to play a little game of fact or fiction with it in this article.</p>
<p><strong>Here is the short list from which we will work:</strong></p>
<ol>
<li>Sessions (XE Profiler Sessions) are Customizable</li>
<li>The default standard session displays all Extended Events</li>
<li>It works with instances of SQL 2012 or greater only</li>
<li>XE Profiler Adds ability to quickly start/stop sessions</li>
<li>XE Profiler provides a new live view of the Event Session</li>
<li>XE Profiler provides a GUI for Extended Events</li>
<li>Templates were not available in XE until the release of XE Profiler</li>
<li>Similarly, XE Profiler also brought the Profiler templates with it as part of the feature release</li>
<li>A DBA can now do something that was not previously possible to do (quickly start a session)</li>
</ol>
<p>That is a rather wealthy list of &#8220;facts&#8221; to be checked for validity if you ask me. Let&#8217;s go ahead and start diving into each of these. I will not be following the provided list order. Rather, I will be looking at items that seem appropriate to validate in my own special order. Rest assured tho, we will get through the list.</p>
<h3>GUI</h3>
<p>I don&#8217;t know how this is still a misconception about Extended Events, but it is certainly still out there. Suddenly XE Profiler comes along and people suddenly think that this tool has provided the GUI that everybody has been clamoring about since Extended Events was released in 2008 (yes almost 10 yrs ago).</p>
<p>I am not going to waste much time on this because it is a complete and total piece of fiction. The GUI has been readily and easily available since SQL Server 2012. In addition to that, there was a GUI that could have been installed for the older versions that was created by Jonathan Kehayias.</p>
<p>From SSMS 2014, here is a sample screenshot of the GUI wizard followed by a standard GUI screen.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3912" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard-1024x632.jpg" alt="" width="560" height="346" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard-1024x632.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard-300x185.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard-768x474.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard-50x31.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_wizard.jpg 1527w" sizes="(max-width: 560px) 85vw, 560px" /></a><img loading="lazy" class="aligncenter size-large wp-image-3911" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_gui_properties-1024x396.jpg" alt="" width="560" height="217" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_gui_properties-1024x396.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_gui_properties-300x116.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_gui_properties-768x297.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_gui_properties-50x19.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>As you can see, there is clearly a GUI prior to the release of SSMS 17.3.</p>
<p>Result: <strong>Fiction</strong></p>
<h3>Templates</h3>
<p>This is probably the next easiest notion to prove or disprove. I have heard from more than a single source that templates are brand new with SSMS 17.3 (which is when XE Profiler was released).</p>
<p>I don&#8217;t really need to go very far or work very hard to prove this notion as a complete work of fiction. I have SSMS 2014, 2016, 17.0, 17.3, and 17.4 readily available to me. I am going to start with SSMS 2014.</p>
<p>If I  once again open the GUI for XEvents in SSMS 2014, I can easily see the available templates in that version.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3913" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates-1024x541.jpg" alt="" width="560" height="296" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates-1024x541.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates-300x159.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates-768x406.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates-50x26.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates.jpg 1699w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>It looks pretty obvious there that templates were introduced well before SSMS 17.3.</p>
<p>I can also see all of the templates available by browsing out to the file system.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3914" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os-1024x510.jpg" alt="" width="560" height="279" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os-1024x510.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os-300x150.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os-768x383.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os-50x25.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates_os.jpg 1342w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And for good measure, here is one from a 2012 instance.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2012_os.jpg"><img loading="lazy" class="aligncenter size-full wp-image-3915" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2012_os.jpg" alt="" width="373" height="217" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2012_os.jpg 373w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2012_os-300x175.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2012_os-50x29.jpg 50w" sizes="(max-width: 373px) 85vw, 373px" /></a></p>
<p>The same templates (minus possible changes within the template definitions) are available in SSMS 2012, 2014 and 2016. We will see those same templates available in SSMS 17 and above as well &#8211; in addition to a few that have been added.</p>
<p>I want to also add here that these are just the default templates. Just like in Profiler, you can create and save your own templates for future use.</p>
<p>Result: <strong>Fiction</strong></p>
<h3>Profiler Templates</h3>
<p>We just saw how there are templates available prior to the release of SSMS 17.3. We can also see that the profiler templates are not available in those prior versions of SSMS. So does that also mean that the profiler templates were only released as a part of SSMS 17.3? We best be careful with that slippery slope of assumption. Let&#8217;s take a closer look at SSMS 17.0.</p>
<p>And just so we can confirm that this is indeed a version of SSMS that pre-dates 17.3&#8230;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/ssms_17rc3.jpg"><img loading="lazy" class="aligncenter wp-image-3916 " src="http://jasonbrimhall.info/wp-content/uploads/2017/12/ssms_17rc3.jpg" alt="" width="402" height="418" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms_17rc3.jpg 492w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms_17rc3-289x300.jpg 289w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms_17rc3-48x50.jpg 48w" sizes="(max-width: 402px) 85vw, 402px" /></a></p>
<p>As you can see there, this is RC3 of SSMS 17.0 so it is definitely a version that precedes 17.3</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3917" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe-1024x635.jpg" alt="" width="560" height="347" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe-1024x635.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe-300x186.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe-768x476.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe-50x31.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/profiler_templates_in_xe.jpg 1466w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And similarly from a peek inside the folder on disk:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os.jpg"><img loading="lazy" class="aligncenter wp-image-3918" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os-1024x657.jpg" alt="" width="509" height="327" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os-1024x657.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os-300x192.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os-768x493.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os-50x32.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_templates2017_os.jpg 1090w" sizes="(max-width: 509px) 85vw, 509px" /></a></p>
<p>Seems to me we have ample evidence that the profiler templates were made available to the XE GUI well in advance of SSMS 17.3</p>
<p>Result: <strong>Fiction</strong></p>
<h3>Event Session Live View</h3>
<p>One of the most widely used feature of profiler is the ability to watch the data as it streams through the session. According to many, this ability is missing in Extended Events and the XE Profiler feature has brought this ability to the forefront with XE now.</p>
<p>Let&#8217;s start by taking a look at an XE Session in SSMS 2014 connected to a 2014 database instance to check the validity of this concern.</p>
<p>All I need to do is browse the nodes in SSMS down to the session I want to view. Right click the session and then select the option to &#8220;Watch Live Data&#8221;.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/watch_livestream.jpg"><img loading="lazy" class="aligncenter wp-image-3919" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/watch_livestream.jpg" alt="" width="263" height="459" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/watch_livestream.jpg 491w, https://jasonbrimhall.info/wp-content/uploads/2017/12/watch_livestream-172x300.jpg 172w, https://jasonbrimhall.info/wp-content/uploads/2017/12/watch_livestream-29x50.jpg 29w" sizes="(max-width: 263px) 85vw, 263px" /></a></p>
<p>After clicking watch live data, the event session live stream will appear on the right and start streaming the data to your SSMS workspace as shown in the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data.jpg"><img loading="lazy" class="aligncenter wp-image-3920" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data-1024x640.jpg" alt="" width="510" height="319" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data-1024x640.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data-300x187.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data-768x480.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data-50x31.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/livestream_data.jpg 1204w" sizes="(max-width: 510px) 85vw, 510px" /></a></p>
<p>For this session demo, I selected a session that should be readily available to everybody &#8211; the system_health default session. That session comes installed and running for you already.</p>
<p>Don&#8217;t like the layout of the screen? Well, you can customize the view to your liking and it can be customized differently for each and every different running session on your server.</p>
<p>As it turns out, the ability to watch livestream data has been available to you for Extended Events since 2012 when the GUI was made available. If you are curious about learning more about the GUI and customizing the view, you can read various articles I have written in my <a href="http://bit.ly/XE60Days">60 day series you can find here</a>.</p>
<p>Result: <strong>Fiction</strong></p>
<p>That brings us to the halfway point. To recap we are now sitting at a score of Fact 0 and Fiction 4. Let&#8217;s see if we can turn the tide in these last 5.</p>
<h3>Quick Start a Session</h3>
<p>To be quite frank here, this has been a long time argument against using Extended Events. It just isn&#8217;t possible to start a session quickly and easily. I have two methods that I have shown in my training sessions concerning that concern. Let&#8217;s take a look at the first. I will demonstrate this from SSMS 2014.</p>
<p>The first thing that needs to be done is browse the SSMS tree until a session is found that you want to start. Here is an ancient cheat code &#8211; I leave many sessions on the server in the stopped state until I need to use them. Pro-tip: create your XE sessions on all of your servers and leave them stopped until you think you need to use it.</p>
<p>For this example, I have selected my AG_LeaseTimeout sessions which is in the stopped state (denoted by the little red &#8220;stop&#8221; icon next to the session name).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/easystartsession.png"><img loading="lazy" class="aligncenter wp-image-3921" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/easystartsession.png" alt="" width="432" height="521" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/easystartsession.png 517w, https://jasonbrimhall.info/wp-content/uploads/2017/12/easystartsession-249x300.png 249w, https://jasonbrimhall.info/wp-content/uploads/2017/12/easystartsession-41x50.png 41w" sizes="(max-width: 432px) 85vw, 432px" /></a></p>
<p>Then right click the session name and select &#8220;Start Session&#8221; from the context menu. To help clarify, I have circled the session name in <strong><span style="color: #339966;">green</span></strong> and the menu item in <strong><span style="color: #0000ff;">blue</span></strong>. This an extremely easy method to start a session. Once started, and if you really feel you must watch data stream onto the screen, then you can also follow the steps shown for watching the live stream data in the previous section.</p>
<p>The second method to quick start a session is only a touch more difficult. The steps are just the same as shown in the &#8220;template&#8221; section. You select a template that matches your desires and give the session a name. Here are some broad strokes shown in SSMS 17.0 (same steps apply for SSMS 2014 minus the ability to select a profiler template):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/new_session_ssms17.jpg"><img loading="lazy" class="aligncenter size-full wp-image-3922" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/new_session_ssms17.jpg" alt="" width="480" height="378" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/new_session_ssms17.jpg 480w, https://jasonbrimhall.info/wp-content/uploads/2017/12/new_session_ssms17-300x236.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/new_session_ssms17-50x39.jpg 50w" sizes="(max-width: 480px) 85vw, 480px" /></a></p>
<p>Right click the &#8220;Session&#8221; node and selection &#8220;New Session&#8221; from the context menu.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3923" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17-1024x752.jpg" alt="" width="560" height="411" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17-1024x752.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17-300x220.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17-768x564.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17-50x37.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_standardtemplate_ssms17.jpg 1463w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Select the &#8220;Standard&#8221; template from the dropdown box. This is a profiler equivalent (and also happens to be one of the two default sessions in &#8220;XE Profiler&#8221; so makes sense for a good comparison. Note that the window has a warning that the Session name cannot be empty, so let&#8217;s give the session a name.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3926" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar-1024x754.jpg" alt="" width="560" height="412" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar-1024x754.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar-300x221.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar-768x565.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar-50x37.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_addname_ssms17_ar.jpg 1462w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>With that warning cleared, we can now move on to the next configuration. Notice the two red arrows in the preceding image. Enabling these two options will start the session immediately and also give you that profiler warm and fuzzy by allowing you to immediately start watching the session without needing to lift another finger.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3927" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17-1024x751.jpg" alt="" width="560" height="411" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17-1024x751.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17-300x220.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17-768x563.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17-50x37.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_startwatch_ssms17.jpg 1465w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From here, click the OK button ( I know I normally teach people that they should script it, but in this case we are going for quick and easy). After clicking &#8220;ok&#8221;, be prepared for something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17.jpg"><img loading="lazy" class="aligncenter size-full wp-image-3928" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17.jpg" alt="" width="860" height="798" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17.jpg 860w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17-300x278.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17-768x713.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_floodserver_ssms17-50x46.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>After just a few seconds on a busy server, one should expect thousands of events to fire in a very profiler type manner. I want to reiterate here, that this was the same session template that feeds one of the two available sessions in XE Profiler.</p>
<p>Once you have determined that you have enough data, you can easily stop the session by right clicking the session name and then selecting the &#8220;Stop Session&#8221; menu item.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_stopsession_ssms17.jpg"><img loading="lazy" class="aligncenter wp-image-3929" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_stopsession_ssms17.jpg" alt="" width="247" height="288" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_stopsession_ssms17.jpg 432w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_stopsession_ssms17-258x300.jpg 258w, https://jasonbrimhall.info/wp-content/uploads/2017/12/newsession_stopsession_ssms17-43x50.jpg 43w" sizes="(max-width: 247px) 85vw, 247px" /></a></p>
<p>And that is all. It is very easy to start a session in two different manners without XE Profiler. One of the options even allows you to create the exact same session as XE profiler but without that feature even being made available on the version of SSMS being used. So if you really want that profiler type of session, you can use a template to quickly create it even if your SSMS version pre-dates 17.3 and even if you don&#8217;t have the profiler templates by default (remember you can simply add the profiler templates should you choose).</p>
<p>In the end, I have to call this one a piece of fiction as well. The XE Profiler does not add any new ability to quickly start a session that wasn&#8217;t already a viable option. That said, the XE Profiler does add a third alternative to start a session &#8211; so long as it is one of the two default sessions.</p>
<p>Result: <strong>Fiction</strong></p>
<h3>SQL 2012 Required</h3>
<p>This is one of those areas that I wish were fiction. However, this has actually been a consistent theme ever since the GUI was released for XE. The GUI components only work on 2012 instances and later. Let&#8217;s take a look at a connection to a 2014 Server and a 2008R2 Server in the same SSMS window from SSMS 17.0.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/no_xetools_2008.png"><img loading="lazy" class="aligncenter wp-image-3930" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/no_xetools_2008.png" alt="" width="280" height="611" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xetools_2008.png 423w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xetools_2008-138x300.png 138w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xetools_2008-23x50.png 23w" sizes="(max-width: 280px) 85vw, 280px" /></a></p>
<p>We can see here that the standard Extended Events GUI is just not available for the 2008R2 instance. The 2014 instance is denoted with a Green box and arrow to help distinguish between that and the red marks for the 2008R2 instance.</p>
<p>Now, let&#8217;s take a look at it with SSMS 17.3. With a similar setup and similar notation, we see the following in SSMS 17.3 when connected to both a 2014 instance and a 2008R2 instance.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008.png"><img loading="lazy" class="aligncenter size-large wp-image-3933" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008-1024x834.png" alt="" width="560" height="456" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008-1024x834.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008-300x244.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008-768x626.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008-50x41.png 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/no_xeprofiler_2008.png 1235w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Once again, I will admit this is something I really wish were not the case. It would definitely be helpful if the XE GUI were to be made available to SQL Server Instances that are 2008 and 2008R2. Especially given that the tool is an &#8220;SSMS feature&#8221;. That said, it really behooves everybody to get their SQL Servers updated to current technologies (2008 is nearly 10 years old afterall).</p>
<p>Result: <strong>Fact</strong></p>
<h3>The default &#8220;Standard&#8221; session displays all Extended Events</h3>
<p>So far, we have been easing ourselves into this XE Profiler very gently. It is time to finally get into the deeper end and actually look at some very specific XE Profiler things. When I first heard this one, I was admittedly flabbergasted. One session displays <strong>all</strong> extended events? Really? Let&#8217;s actually establish some baselines about the default sessions for XE Profiler first.</p>
<ol>
<li>There are only two default sessions for XE Profiler</li>
<li>The session names are &#8220;Standard&#8221; and &#8220;TSQL&#8221;</li>
<li>The default sessions are based on templates (discussed previously)</li>
<li>The template for the &#8220;Standard&#8221; session is the xe_Profiler_Standard xml template file</li>
<li>The template for the &#8220;TSQL&#8221; session is xe_Profiler_TSQL</li>
</ol>
<p>If I peruse the template file located in the directory on disk (C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Templates\sql\xevent) for the standard session, I will be able to see that it contains the following events:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;event package="sqlserver" name="attention"&gt;
&lt;event package="sqlserver" name="sql_batch_starting"&gt;
&lt;event package="sqlserver" name="sql_batch_completed"&gt;
&lt;event package="sqlserver" name="rpc_completed"&gt;
&lt;event package="sqlserver" name="existing_connection"&gt;
&lt;event package="sqlserver" name="logout"&gt;
&lt;event package="sqlserver" name="login"&gt;</pre><p>Now, that is not the entire template file. I shorted it to only include the events and none of the other details like session configuration or the actions attached to each event. As you can see, there is a grand total of seven events in this particular session.</p>
<p>If I run the following statement against a SQL Server 2014 instance, I will get a few more events than just seven.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT SERVERPROPERTY('ProductMajorVersion') AS SvrVersion,COUNT(*) AS EventCount
	FROM sys.dm_xe_objects xo
	WHERE xo.object_type = 'event';</pre><p>And the results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3935" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt-1024x245.jpg" alt="" width="560" height="134" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt-1024x245.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt-300x72.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt-768x184.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt-50x12.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt.jpg 1285w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And just for the sake of clarity, the results on a 2017 instance:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt17.jpg"><img loading="lazy" class="aligncenter size-full wp-image-3936" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt17.jpg" alt="" width="628" height="421" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt17.jpg 628w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt17-300x201.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/eventcnt17-50x34.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Obviously the math does not add up. There are multiple things wrong with the notion that a session from XE Profiler will contain all events. First, there is no sense at all in adding every event to a single event session. The second problem is that the session is supposed to mimic a profiler default template session. If it is supposed to mimic a profiler style session, you can only use 180 events max anyway. Profiler only had 180 events and XE is obviously way beyond that with so much more feature support than Profiler could even muster back in its glory days.</p>
<p>In case, you were wondering, here is how you access the XE Profiler. It is not under the Extended Events Node, it is a brand new node.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_node.png"><img loading="lazy" class="aligncenter wp-image-3937" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_node.png" alt="" width="210" height="254" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_node.png 511w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_node-248x300.png 248w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_node-41x50.png 41w" sizes="(max-width: 210px) 85vw, 210px" /></a></p>
<p>As you can see, there really are only the two options for XE Profiler and if you recall, both of those options are derived from the templates that were made available in the traditional XE GUI and are very easy to create a quick session via the same templates as these two options.</p>
<p>Whether using the XE Profiler or the previous method to create these sessions, there is just no way that these sessions could contain every event in Extended Events. It&#8217;s just a bunch of hot air with no foundation to the claim.</p>
<p>Result: <strong>Fiction</strong></p>
<h3>XE Profiler adds ability to start/stop session</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_menu.png"><img loading="lazy" class="wp-image-3938 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_menu.png" alt="" width="269" height="192" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_menu.png 543w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_menu-300x214.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xe_profiler_menu-50x36.png 50w" sizes="(max-width: 269px) 85vw, 269px" /></a>Let&#8217;s start back with the last image from the previous section and then go from there. We need to access what is available to us via the XE Profiler node so we can test this theory. I will start by right clicking one of the sesisons (right clicking on the &#8220;XE Profiler object itself will not yield anything very promising fwiw).</p>
<p>As you can see here, we are given some pretty basic options to either &#8220;Stop Session&#8221; or to &#8220;Launch Session&#8221;. It also <a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/xeprofilernosessions.png"><img loading="lazy" class="wp-image-3939 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/xeprofilernosessions.png" alt="" width="218" height="285" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/xeprofilernosessions.png 414w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xeprofilernosessions-230x300.png 230w, https://jasonbrimhall.info/wp-content/uploads/2017/12/xeprofilernosessions-38x50.png 38w" sizes="(max-width: 218px) 85vw, 218px" /></a>seems very obvious what they want you to do here because the option is <strong>bolded</strong> &#8211; &#8220;Launch Session&#8221;.</p>
<p>This menu is the same regardless of the session state. What I mean by that is even if you do not have the session created, this menu is the same as if you have the session created and running. None of the options dim and all are clickable on this menu. This holds true for SSMS 17.4 as well. Let&#8217;s take a look at a server where none of these &#8220;profiler&#8221; sessions are running.</p>
<p>&nbsp;</p>
<p>I want to make it abundantly clear. This is the way it appears after a completely fresh install of SSMS 17.3. None of these sessions have ever run on this particular instance of SQL Server 2017 and this is even a completely fresh install of SQL Server 2017. That said, I have done nothing yet to break it &#8211; buahaha.</p>
<p>Knowing that no sessions have ever been &#8220;launched&#8221; for XE Profiler, it is clear that it is time to go ahead and &#8220;launch&#8221; a session. In this new feature &#8220;launch&#8221; is the new equivalent of &#8220;start&#8221;. Once you launch a session you will get the same net effect as what we saw earlier when I created a session from the profiler template and checked the box to watch live data and the box to start the session. When I click launch, I will see something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard.png"><img loading="lazy" class="aligncenter size-large wp-image-3940" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard-1024x469.png" alt="" width="560" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard-1024x469.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard-300x138.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard-768x352.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard-50x23.png 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksessionstandard.png 1706w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>A new XE session was created under the Extended Events node and it is now called &#8220;QuickSessionStandard&#8221;. Once again, this is created from that profiler template I have mentioned a few times.</p>
<p>And then after a bit, I may want to try and stop the session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu.png"><img loading="lazy" class="aligncenter size-large wp-image-3941" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu-1024x616.png" alt="" width="560" height="337" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu-1024x616.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu-300x181.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu-768x462.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stopmenu.png 1489w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>You can see here that I was able to capture some quick data into the live stream view (which was a feature that was already there prior to 17.3). And after clicking the &#8220;stop session&#8221; menu item, I will see the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stop.png"><img loading="lazy" class="aligncenter wp-image-3942" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stop.png" alt="" width="224" height="316" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stop.png 402w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stop-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2017/12/quicksession_stop-35x50.png 35w" sizes="(max-width: 224px) 85vw, 224px" /></a></p>
<p>Note that the &#8220;QuickSessionStandard&#8221; event session now has a &#8220;Stop&#8221; icon instead of a &#8220;play&#8221; icon. So yay &#8211; I was able to start and stop a session quickly from XE Profiler. In addition, XE profiler launched a live stream view just like we saw earlier when creating the same session from the template in the XE GUI. Now for a pro-tip &#8211; start and stop an XE Session from the old GUI &#8211; &#8220;right click any event session and select start/stop from the context menu.&#8221;</p>
<p>Yes it is that easy. In addition, only the available option for that session will be enabled (e.g. you cannot stop a session that is already stopped &#8211; or not running). In fact you can even start/stop from TSQL. If you try to stop a session that is not running in TSQL, you will get a warning message that it is already stopped. Far more intuitive than XE Profiler. You will get no indication that the session is unable to be stopped if it is already stopped. Let&#8217;s take a look at the old way.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/old_quickstart.png"><img loading="lazy" class="aligncenter wp-image-3943" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/old_quickstart.png" alt="" width="231" height="315" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/old_quickstart.png 460w, https://jasonbrimhall.info/wp-content/uploads/2017/12/old_quickstart-220x300.png 220w, https://jasonbrimhall.info/wp-content/uploads/2017/12/old_quickstart-37x50.png 37w" sizes="(max-width: 231px) 85vw, 231px" /></a></p>
<p>And after the session is started, I can also quickly stop it.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/oldquickstop.png"><img loading="lazy" class="aligncenter wp-image-3944" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/oldquickstop.png" alt="" width="295" height="273" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/oldquickstop.png 587w, https://jasonbrimhall.info/wp-content/uploads/2017/12/oldquickstop-300x278.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/oldquickstop-50x46.png 50w" sizes="(max-width: 295px) 85vw, 295px" /></a></p>
<p>You can also see from each of those images, that I have the option to watch live data for the session. Another easy access feature from the old XE GUI.</p>
<p>While XE Profiler has added an additional means to be able to start/stop sessions quickly, the fact of the matter is that it is not a new feature brought to the table by XE Profiler. All it did was add a different way of doing it. I will also add that this new method can actually be somewhat confusing as well. You can only determine (visually) if the session is running or stopped by expanding the &#8220;Extended Events&#8221; node. Stopping a session from the XE Profiler node does not close the livestream viewer so you could easily presume it is still running. The XE Profiler node gives you no insight into the actual state of the session.</p>
<p>And for giggles, this is how easy it is to start or stop a session via TSQL.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION QuickSessionStandard on SERVER
STATE = START;
GO

ALTER EVENT SESSION QuickSessionStandard on SERVER
STATE = STOP;
GO</pre><p>If I run the statement to stop the session when it is already stopped, I will get the following:</p>
<blockquote><p><span style="color: #ff0000;">Msg 25704, Level 16, State 1, Line 9</span><br />
<span style="color: #ff0000;">The event session has already been stopped.</span></p></blockquote>
<p>I have previously covered this specific topic (start/stop sessions) in my <a href="http://bit.ly/XE60Days">60 Day series which can be found here</a>.</p>
<p>Result: <strong>Fiction</strong></p>
<h3>Customizable XE Profiler Sessions</h3>
<p>Let&#8217;s take a gander at the previous section where I showed the context menu available in XE Profiler and not the extent of that menu. The profiler iteself does not offer any sort of customization. You have only two default sessions. You cannot change either session within that particular feature.</p>
<p>Since I cannot customize anything for these sessions via the XE Profiler, let&#8217;s use the XE GUI that is tried and true. I will effectively perform the following via the XE Session Properties window:</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION [QuickSessionStandard] ON SERVER 
DROP EVENT sqlserver.attention, DROP EVENT sqlserver.logout
GO</pre><p>And after I am done, that session will look like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [QuickSessionStandard] ON SERVER 
ADD EVENT sqlserver.existing_connection(SET collect_options_text=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_id)),
ADD EVENT sqlserver.login(SET collect_options_text=(1)
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_id)),
ADD EVENT sqlserver.rpc_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
    WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_completed(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
    WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
ADD EVENT sqlserver.sql_batch_starting(
    ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
    WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))))
WITH (MAX_MEMORY=8192 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO</pre><p>And visually, from the GUI, it will look like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession.jpg"><img loading="lazy" class="aligncenter size-large wp-image-3945" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession-1024x749.jpg" alt="" width="560" height="410" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession-1024x749.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession-300x219.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession-768x561.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession-50x37.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/altered_quicksession.jpg 1465w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>You can see that the aforementioned events are definitely gone from this session. From here, I can absolutely start that session from the XE GUI and it will run just fine. I can hit &#8220;watch live data&#8221; from the context menu and it will open up the previous view of the live data that was used (so the exact same configuration of that window because the XE GUI has always done that). If I double check my session after it is started, I will be able to confirm that the altered session is indeed still tact just the same as I customized it.</p>
<p>Let&#8217;s go ahead and stop that and then &#8220;launch&#8221; it from the XE Profiler now. After the &#8220;launch&#8221; I will re-script the session to verify that it is either the same or altered from what I had configured. In this case, since the session was already in place, I will find that the XE Profiler did not alter my session in any way and merely started the session. That is a win for XE Profiler in that it was able to determine that the session did indeed exist. However, I have to use the XE GUI and not XE Profiler in order to get a decent config on those default sessions.</p>
<p>Result: <strong>Fiction</strong></p>
<h2>Bonus time</h2>
<h3>XE Profiler only has SQL Profiler Events</h3>
<p>This is actually an interesting statement. While the XE Profiler relies on templates based on SQL Profiler and the events in those templates are events that are available in SQL Profiler, they are not exclusive to SQL Profiler. These events can be used in Extended Events and have been a part of the XE Engine since inception. So, I would call this one fiction as well. I think an obvious litmus test for that is that the events are actually running through an XE Session so they must obviously be XE events as well.</p>
<p>Result: <strong>Fiction</strong></p>
<p>Up to this point I have not addressed any changes in the Extended Events Profiler that were made for SSMS 17.4. Here is where it seems we compound a bit of confusion for the masses. Not only do we have this Extended Events tool that we have decided to call &#8220;Profiler&#8221; which has already had many people asking me about it because the name confused them (is it profiler or is it XE??), but it seems that the identity crisis for this feature is exacerbated slightly with a sudden name change.</p>
<p>Using yet another very clean install of SSMS on a different instance of SQL Server to ensure that none of the XE Profiler components had been used or any of the default sessions created and launched, I have the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler.png"><img loading="lazy" class="aligncenter size-large wp-image-3946" src="http://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler-1024x692.png" alt="" width="560" height="378" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler-1024x692.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler-300x203.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler-768x519.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler-50x34.png 50w, https://jasonbrimhall.info/wp-content/uploads/2017/12/ssms174_xe_profiler.png 1200w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Yes, the name change is very innocuous but it can lead to some confusion for various parties involved. If a set of step by step instructions says to do something and the learner cannot find that explicit node, they will become confused.</p>
<p>For anybody that has been working with XE for some time, they will know that XE is synonymous with XEvent and will quickly figure it out.</p>
<h2>Conclusion</h2>
<p>So, in wrapping up this very long article, I want to recap the score of the Fact v. Fiction items. The final tally is <strong>Fact 1 and Fiction 9</strong> (9 original list items plus 1 bonus entry). This means that there is a whole lot of stuff going on around out there about this new feature that is just not accurate. While some may be able to derive some small use from the XE Profiler, it really does not add anything that you could not already do with either TSQL or the old XE GUI.</p>
<p>Some say this is a way of bridging the gap. In my opinion, that gap was already bridged with the GUI that has been available for several years. Some say that maybe this tool needs to integrate a way to shred XML faster. To that, I say there are methods already available for that such as Powershell, the live data viewer, the Target Data viewer, or even my tools I have provided in the <a href="http://bit.ly/XE60Days">60 day series</a>.</p>
<p>I would challenge those that are still unfamiliar with the XE GUI (out for nearly 6 years now) to go and read some of my articles or articles by Jonathan Kehayias about the power that is in XE as well as some of the power in the GUI.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3908" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/">An Identity Crisis: Is it Profiler or is it Extended Events?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/12/22/an-identity-crisis-is-it-profiler-or-is-it-extended-events/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server Haunt 2017</title>
		<link>https://jasonbrimhall.info/2017/11/01/sql-server-haunt-2017/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-haunt-2017</link>
					<comments>https://jasonbrimhall.info/2017/11/01/sql-server-haunt-2017/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 01 Nov 2017 06:53:48 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3875</guid>

					<description><![CDATA[<p>The undead of Halloween are now upon us. Among the hordes of data zombies roaming the streets in lab-coats and fishnet stockings, few of us are still scrambling to remove the hexes we have looming over our data.</p>
The post <a href="https://jasonbrimhall.info/2017/11/01/sql-server-haunt-2017/">SQL Server Haunt 2017</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Halloween is a great time of year. It is unfortunate that it is just one day of the year. That said, I do like to think of the <img loading="lazy" class="wp-image-2529 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-173x300.png" alt="phantasmrip" width="151" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-173x300.png 173w, https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-28x50.png 28w, https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip.png 376w" sizes="(max-width: 151px) 85vw, 151px" />month of October as Halloween Month. I have several posts over the years that geek out over the cross-over between Halloween and SQL Server.</p>
<p>The undead of Halloween are now upon us. Among the hordes of data zombies roaming the streets in lab-coats and fishnet stockings, few of us are still scrambling to remove the hexes we have looming over our data.</p>
<p>As chance would have it, these hexidecimals, err hexes, have a more profound effect on us than we first thought. Many may have yet to even recognize the impact of the hexes placed along with the monsters that now lurk in the data after having been summoned via those hexes.</p>
<h3>DB and Fun Related</h3>
<p>Seeing as I am a really big fan of this holiday I have a few Halloween posts over the years. If you are interested in the previous Halloween posts, here is a list of a few of them:</p>
<h3><a style="font-size: 12px;" href="http://jasonbrimhall.info/?s=halloween">All Halloween posts</a></h3>
<p>That list is my Halloween treat this year. Now for a bit of a trick with a very strong warning. Because of this warning, I am not posting any code showing how to perform the trick.</p>
<h2>Warning</h2>
<p><span style="color: #ff0000;"><em><strong>The contents of this post are for the intent of HUMOR!</strong></em></span></p>
<h3>Freddy Kreuger</h3>
<p><img loading="lazy" class="wp-image-3314 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-300x300.png" alt="mangled" width="157" height="157" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled.png 600w" sizes="(max-width: 157px) 85vw, 157px" /></p>
<p>I can hear you clamoring from half a world away right now &#8211; &#8220;There is nothing called &#8216;Freddy Kreuger&#8217; in SQL Server. What in the world are you talking about?&#8221;</p>
<p>You would be very accurate in your exclamation there. But this is not necessarily a strict exercise in feature names within SQL Server. I want you to think a little further outside the norms for a while.</p>
<p>Do you currently or have you ever needed to shred XML? XML shredding via TSQL <em>can </em>be a monstrously bloody killer to your database performance. As it turns out, Mr. Kreuger was also a monstrously bloody shredder.</p>
<h3>Jason Voorheese</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/10/voorheese.png"><img loading="lazy" class="wp-image-3877 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/10/voorheese.png" alt="" width="155" height="205" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/10/voorheese.png 462w, https://jasonbrimhall.info/wp-content/uploads/2017/10/voorheese-228x300.png 228w, https://jasonbrimhall.info/wp-content/uploads/2017/10/voorheese-38x50.png 38w" sizes="(max-width: 155px) 85vw, 155px" /></a>Yet another beast that is not truly in SQL Server, or is it? A not so new but new feature in SQL Server is called JSON. This feature does actually perform better than XML in some regards. That said, we do have a very common problem between the two of these features &#8211; <strong>blobs</strong>.</p>
<p>If you are not familiar with what that means -here you go. A blob is an overly large item being stored in the database. If you wish, you could correlate that to the other well known Halloween beast &#8211; &#8220;The Blob&#8221;.</p>
<p>Over time, this blob acts like sludge and just slows down your database queries. In addition, like the creature, the blob in your database tends to continue to grow in size and is seemingly never able to be put in check.</p>
<h3>Skeletons</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/10/sitting_skeleton.png"><img loading="lazy" class="wp-image-3878 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2017/10/sitting_skeleton.png" alt="" width="138" height="221" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/10/sitting_skeleton.png 451w, https://jasonbrimhall.info/wp-content/uploads/2017/10/sitting_skeleton-188x300.png 188w, https://jasonbrimhall.info/wp-content/uploads/2017/10/sitting_skeleton-31x50.png 31w" sizes="(max-width: 138px) 85vw, 138px" /></a>When I find skeletons, I have to be honest, I don&#8217;t find them terribly frightening. When talking about skeletons in your database, I am even less frightened.</p>
<p>Then again, when I run into the situation as described recently, in this <a href="http://bit.ly/2zTcpNi">post</a>, I may get a bit of a startle and get just a wee bit concerned.</p>
<p>Overall though, I am rarely startled or frightened by any skeletons in the database. These are really just the supporting structures of a nice secure database and are called &#8220;schemas&#8221;. See, not really all that frightening here if we think about it just a bit.</p>
<p>This next one however, might be a little harder and should be nearly enough to cause some heart pain.</p>
<h3>Warlocks</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/10/manwich.png"><img loading="lazy" class="wp-image-3879 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/10/manwich.png" alt="" width="150" height="227" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/10/manwich.png 364w, https://jasonbrimhall.info/wp-content/uploads/2017/10/manwich-199x300.png 199w, https://jasonbrimhall.info/wp-content/uploads/2017/10/manwich-33x50.png 33w" sizes="(max-width: 150px) 85vw, 150px" /></a>Surely there are no wizarding type of people in the database, right? Warlocks? I know for absolute certainty that there is no such feature or anything remotely close to a warlock, witch or wizard within the database. That is unless my database is about mystical creatures and people.</p>
<p>Alas, I urge you again to expand the box of perception a little bit and become just a tiny bit imaginative. This one, truth be told, does require a fair amount of explanation and imagination though.</p>
<p>The problem comes in part from some magical data issues that can occur due to this particular feature. In addition, this also comes from the wonderful grammatical errors from various blog posts and forums out there mis-spelling &#8220;which&#8221; as &#8220;witch&#8221;. Since &#8220;manwich&#8221; is really close to &#8220;man-witch&#8221;, I am calling it a warlock.</p>
<p>Now, since I am calling it a warlock, that leads us to the next strong hint about the feature. &#8220;Lock&#8221; in this case is the key. Now which magical, imaginative feature might there be that is related to &#8220;lock&#8221;? That would be the &#8220;nolock&#8221; directive and all of the data quality issues that it presents. Here is a really really good recap (by Aaron Bertrand) on this feature along with reference to it being &#8220;magic&#8221; &#8211; <a href="https://blogs.sentryone.com/aaronbertrand/bad-habits-nolock-everywhere/">at this site</a>.</p>
<h3>Pirates</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/10/skull_crossbones.png"><img loading="lazy" class="wp-image-3882 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2017/10/skull_crossbones.png" alt="" width="101" height="108" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/10/skull_crossbones.png 333w, https://jasonbrimhall.info/wp-content/uploads/2017/10/skull_crossbones-281x300.png 281w, https://jasonbrimhall.info/wp-content/uploads/2017/10/skull_crossbones-47x50.png 47w" sizes="(max-width: 101px) 85vw, 101px" /></a>This is probably the easiest of the day by far. For all the data loving geeks out there, SQL Server has this pirate flavored way for you to get your drool on. This feature is called &#8220;R&#8221;. Yup &#8211; just like what a pirate says matey.</p>
<p>R is a tool to be used by data scientists or data geeks in general to try and throw together many different flavors of statistical analysis about your data.</p>
<h3><strong>Split Brain</strong></h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2017/11/splitbrain.png"><img loading="lazy" class="wp-image-3883 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/11/splitbrain.png" alt="" width="235" height="152" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/11/splitbrain.png 442w, https://jasonbrimhall.info/wp-content/uploads/2017/11/splitbrain-300x194.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/11/splitbrain-50x32.png 50w" sizes="(max-width: 235px) 85vw, 235px" /></a>Finally, (at least for this Halloween) we have this condition that is real within SQL Server. While treatable with long hours and heavy medication, it is something to be feared.</p>
<p>This condition is something rare but it is very real. The split brain syndrome is pretty much a multiple identity personality disorder in your database. If you have multiple nodes in a cluster, mirror or availability group, it is possible for more than one of those nodes to believe it is the master node and then for different transactions to become hardened in each of those nodes.</p>
<p>When this happens, you will not be able to use bleach to clean up the mess. Instead, you will be required to spend a grundle of time with your database cuddling it and nursing it back to data consistency and good mental health.</p>
<p>Last but not least, <span style="color: #ff9900;"><strong>HAPPY HALLOWEEN!</strong></span></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3875" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/11/01/sql-server-haunt-2017/">SQL Server Haunt 2017</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/11/01/sql-server-haunt-2017/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Endpoint Owners &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2017/06/05/what-agent-job-is-running-back-to-basics-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-agent-job-is-running-back-to-basics-2</link>
					<comments>https://jasonbrimhall.info/2017/06/05/what-agent-job-is-running-back-to-basics-2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Jun 2017 12:52:36 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3824</guid>

					<description><![CDATA[<p>"What the heck is an endpoint?" Well, that is a good question. An endpoint in the simplest form is a connection or point of entry into SQL server.</p>
The post <a href="https://jasonbrimhall.info/2017/06/05/what-agent-job-is-running-back-to-basics-2/">Endpoint Owners – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>While the challenge may have been for the year 2016 and I haven&#8217;t contributed in several months, it is still a worthwhile effort. In that vain, I am adding this article to that series.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Endpoints</h2>
<p>You may have heard the term endpoints thrown around in technical discussion and wondered &#8220;what the heck is an endpoint?&#8221; Well, that is a good question. An endpoint in the simplest form is a connection or point of entry into SQL server.</p>
<p>Another way of thinking about an endpoint is to look at the ends of a line. Generally speaking, there is a stop point at each end of the line. At this stopping point, the line may connect to something else and therefore be a point of entry into that &#8220;something else&#8221;.</p>
<p>When we deal with SQL Server there is a handful of default endpoints and then a handful of other types of endpoints. To figure out what the default endpoints are, it is pretty easy. The following query will expose the default endpoints.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
SELECT e.name, e.protocol_desc, e.type_desc
	FROM sys.endpoints e
	WHERE e.endpoint_id &lt; 65536;</pre><p>Executing that query will produce results similar to the following:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3825" src="http://jasonbrimhall.info/wp-content/uploads/2017/06/defendpoints.jpg" alt="" width="932" height="268" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/06/defendpoints.jpg 932w, https://jasonbrimhall.info/wp-content/uploads/2017/06/defendpoints-300x86.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/06/defendpoints-768x221.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/06/defendpoints-50x14.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<p>Some of those might look pretty straight forward and then you get to that VIA endpoint. Don&#8217;t worry about that endpoint. The VIA endpoint is on the deprecation list. All of these default endpoints will be owned by sa and don&#8217;t require you to do anything with them per se other than to understand they exist. You may have noticed that I filtered my results by looking only at endpoints with an id of less than 65536. Any endpoint id lower than this number is a default endpoint. All others are user defined endpoints.</p>
<h3>Endpoint Owners</h3>
<p>So far so good. This is pretty straight forward to this point. If you have implemented anything like mirroring, Availability Groups, or Service Broker, then you may be interested to know that you have also created additional endpoints in the Instance. When you create an endpoint, did you know that you become the owner of that endpoint by default? It is very similar to when you restore a database or create a database &#8211; the default owner of that database will be the person that restored/created it.</p>
<p>Do you know who owns your endpoints? Did you create all of the endpoints? Do you know if you have any additional endpoints beyond the default endpoints? If you cannot answer yes to all of these questions, then you will probably want to figure out what the endpoints are and who owns those endpoints. Let&#8217;s try that with a slight modification to the previous query.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
SELECT ISNULL(e.name, 'Unused PayloadType') AS EndpointName
		, e.endpoint_id
		, sp.name AS EndpointOwner
		, CASE	WHEN e.protocol IS NULL
						AND oa.typeid = 1 THEN 1
				WHEN e.protocol IS NULL
						AND oa.typeid = 3 THEN 2
				WHEN e.protocol IS NULL
						AND oa.typeid = 4 THEN 2
				ELSE e.protocol
			END AS protocolid
		, CASE WHEN e.protocol IS NULL
						AND oa.typeid = 1 THEN  'HTTP'
			WHEN e.protocol IS NULL
						AND oa.typeid = 3 THEN 'TCP'
			WHEN e.protocol IS NULL
						AND oa.typeid = 4 THEN 'TCP'
			ELSE e.protocol_desc
			END AS protocol_desc
		, oa.typeid
		, oa.PayloadType
		, e.state
		, e.state_desc
		, e.is_admin_endpoint
	FROM sys.endpoints e
		INNER JOIN sys.server_principals sp
			ON e.principal_id = sp.principal_id
		RIGHT OUTER JOIN ( VALUES ( 1, 'SOAP'), ( 2, 'TSQL'),
				( 3, 'SERVICE_BROKER'), ( 4, 'DATABASE_MIRRORING') ) AS oa ( typeid, PayloadType )
			ON oa.typeid = e.type;</pre><p>This will yield results similar to the following:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3826" src="http://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints-1024x190.jpg" alt="" width="560" height="104" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints-1024x190.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints-300x56.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints-768x142.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints-50x9.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2017/06/advendpoints.jpg 1457w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>I took the script a step further than necessary. I wanted to illustrate potential endpoint types that may not be in use. This script covers both in use endpoint types and those not used. In my results you may note that I have a DATABASE_MIRRORING endpoint. As reality would actually have it, it is an Availability Group endpoint but those are presented as DATABASE_MIRRORING endpoints.</p>
<p>Note that my mirroring endpoint (aka Hadr_endpoint) is owned by &#8220;YourDomain\DBAdmin&#8221;. What if the owner of that particular endpoint was no longer present in the organization and I wanted to change it to something more sustainable? Well, I could do the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
ALTER AUTHORIZATION ON ENDPOINT::Hadr_endpoint TO sa;</pre><p>In this case, the default endpoints are owned by sa and it does make enough sense to assign the owner to be sa for the mirroring endpoint. Take notice that the name of the endpoint is required in order to reassign the owner. The name of the endpoint follows the :: in the script. So, whatever your endpoint name happens to be, just place &#8220;Hadr_endpoint&#8221; that follows the :: in my script.</p>
<h3>Recap</h3>
<p>Endpoints are a fundamental piece of the puzzle with SQL Server.  Getting to know your endpoints and the owners of those endpoints is an essential component of knowing your environment. Who knows, it may come to pass that the owner of an endpoint may no longer exist in your environment or possibly lose permissions along the way. Knowing who owns the endpoint may just save three or four grey hairs when that day comes.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3824" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/06/05/what-agent-job-is-running-back-to-basics-2/">Endpoint Owners – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/06/05/what-agent-job-is-running-back-to-basics-2/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>SSRS Subscription Schedules &#8211; Enhanced</title>
		<link>https://jasonbrimhall.info/2017/05/25/last-restore-of-a-database-back-to-basics-2-2-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=last-restore-of-a-database-back-to-basics-2-2-2</link>
					<comments>https://jasonbrimhall.info/2017/05/25/last-restore-of-a-database-back-to-basics-2-2-2/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 25 May 2017 13:05:45 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[Shared Schedule]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3818</guid>

					<description><![CDATA[<p>With the ability to create content delivery schedules, or to subscribe to report content delivery, it becomes very important to also know when the various reports are scheduled to be delivered.</p>
The post <a href="https://jasonbrimhall.info/2017/05/25/last-restore-of-a-database-back-to-basics-2-2-2/">SSRS Subscription Schedules – Enhanced</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Reporting Services</h2>
<h3><img loading="lazy" class="wp-image-3804 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png" alt="" width="155" height="155" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png 1000w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-50x50.png 50w" sizes="(max-width: 155px) 85vw, 155px" /></h3>
<p>&nbsp;</p>
<p>Over the past couple of articles I have illustrated some of the fun that can be had when dealing with the scheduling capabilities of Reporting Services (SSRS). The first article covered how to create more <a href="http://bit.ly/2qMuhat">advanced schedules</a> (from the SSRS point of view). In another I article, I showed how to <a href="http://bit.ly/2rcPAmG">retrieve scheduling information</a> from the ReportServer database. In that last article, I also promised a follow-up article for more in-depth scheduling details.</p>
<p>SSRS provides the capability to review the scheduled reports (subscriptions) in a far moare detailed fashion than shown in that <a href="http://bit.ly/2rcPAmG">previous article</a>. That ability is held within the ReportServer database. This article will dive into the source of this scheduling information within the ReportServer database.</p>
<p>This dive will be a bit more detailed than the first time I dove into SSRS scheduling &#8211; <a href="http://bit.ly/UwcgTY">here</a>. That particular dive was missing an important set of data.</p>
<h3>Deeper Dive</h3>
<p>My first dive into building a report of the report schedules was pretty comprehensive and I used it quite frequently. Many others also used it regularly for their environments as well. So the first attempt wasn&#8217;t bad by any stretch. The main problem (at least for now) is that the script does not account for any of the custom schedules that can be built. I have to be honest in that I hadn&#8217;t really considered that feasibility. Times and experience change that perspective. When that perspective changes, it is time to dive back in and add coverage for the shortcoming in the script.</p>
<p>When I dove back in to fetch the custom scheduling information, <img loading="lazy" class="wp-image-3821 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/3dreport.png" alt="" width="180" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/3dreport.png 229w, https://jasonbrimhall.info/wp-content/uploads/2017/05/3dreport-50x48.png 50w" sizes="(max-width: 180px) 85vw, 180px" />I realized there was a discrepancy even in the old report in that I was not gathering Job information pertinent to the schedule. Recall that SSRS subscriptions are performed via the SQL Agent. With that in mind, it is reasonable that the Agent job information is pertinent and germane to the report subscription and probably should be included in a report. Couple that with the methods on creating custom schedules for the SSRS reports, and we have a resounding need to ensure that data is trapped properly.</p>
<p>Due to this epiphany, I have now a more complete script to include both the data from SQL Agent as well as the data from the ReportServer database in regards to subscriptions and schedules of reports.</p>
<h3>Script</h3>
<p>In pulling the data together from the two sources, I opted to return two result sets. Not just two disparate result sets, but rather two result sets that each pertained to both the agent job information as well as the ReportServer scheduling data. For instance, I took all of the subscriptions in the ReportServer and joined that data to the job system to glean information from there into one result set. And I did the reverse as well. You will see when looking at the query and data. One of the reasons for doing it this way was to make this easier to assimilate into an SSRS style report.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* union the ssrs schedule query with the sql agent schedule query to get all 
report schedules
*/

IF OBJECT_ID('tempdb..#morepower') IS NOT NULL DROP TABLE #morepower;
IF OBJECT_ID('tempdb..#ReportJobScheds') IS NOT NULL DROP TABLE #ReportJobScheds;
IF OBJECT_ID('tempdb..#SSRSScheds') IS NOT NULL DROP TABLE #SSRSScheds;

--DROP TABLE #morepower;
--DROP TABLE #ReportJobScheds;
--DROP TABLE #SSRSScheds;

DECLARE @ReportName VARCHAR(100)
SET @ReportName = NULL;

CREATE TABLE #morepower (MonthDate BIGINT,N BIGINT,PowerN BIGINT PRIMARY KEY CLUSTERED
							,NameofMonth VARCHAR(25),WkDay VARCHAR(25))
;

WITH powers(powerN, n) AS (
	SELECT POWER(2,number), number 
		FROM master.dbo.spt_values 
		WHERE type = 'P' AND number &lt; 31)

INSERT INTO #morepower ( MonthDate ,N,PowerN ,NameofMonth ,WkDay)
	SELECT ROW_NUMBER() OVER (ORDER BY N) AS MonthDate,N,PowerN
			,CASE WHEN N BETWEEN 0 AND 11 
				THEN DateName(month,DATEADD(month,N+1,0)-1)
				ELSE NULL
				END AS NameofMonth
			,CASE WHEN N BETWEEN 0 AND 6
				THEN DATENAME(weekday,DATEADD(DAY,n+1,0)-2)
				ELSE NULL
				END AS WkDay
		FROM powers

SELECT DISTINCT 
		ReportScheduleID = s.ScheduleID
		,Ca.Path as ReportManagerPath,Ca.Name as ReportName
		,U.UserName as SubscriptionCreator
		,PrimaryScheduleSource = 'SSRS Catalog'
		,Su.Description as SubscriptionDescription
		,SSRSScheduleStartDate = S.StartDate
		,Su.LastRunTime
		,CASE 
				WHEN s.RecurrenceType = 1 THEN 'Once'
				WHEN s.RecurrenceType = 2 THEN 'Hourly'
				WHEN s.RecurrenceType = 3 THEN 'Daily'
				WHEN s.RecurrenceType = 4 THEN 'Weekly'
				WHEN s.RecurrenceType = 5 THEN 'Monthly' 
				WHEN s.RecurrenceType = 6 THEN 'Week of Month' 
			END AS RecurrenceType
		, [Sched Enabled] = CASE su.InactiveFlags
								WHEN 0 THEN 'Yes'
								ELSE 'No'
							END
		,s.EventType
		,ISNULL(REPLACE(REPLACE(STUFF(
					(Select ', ['+CONVERT(VARCHAR(20),MonthDate)+']' AS [text()] 
						FROM #morepower m1 
						WHERE m1.powerN &lt; s.DaysofMonth+1 
							AND s.DaysofMonth &amp; m1.powerN &gt;0 
						ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
			   , 1, 2, ''),'[',''),']','')
			,'N/A') AS DaysofMonth
		,ISNULL(c1.NameOfMonth,'N/A') AS MonthString
		,ISNULL(c2.WkDays,'N/A') AS DaysofWeek
		,CASE MonthlyWeek
				WHEN 1 THEN 'First'
				WHEN 2 THEN 'Second'
				WHEN 3 THEN 'Third'
				WHEN 4 THEN 'Fourth'
				WHEN 5 THEN 'Last'
				ELSE 'N/A'
			END AS MonthlyWeek
		,ISNULL(CONVERT(VARCHAR(10),s.DaysInterval),'N/A') AS DaysInterval
		,ISNULL(CONVERT(VARCHAR(10),s.MinutesInterval),'N/A') AS MinutesInterval
		,ISNULL(CONVERT(VARCHAR(10),s.WeeksInterval),'N/A') AS WeeksInterval
	into #SSRSScheds
	FROM #morepower mp, dbo.Schedule s
		INNER JOIN ReportSchedule RS
			ON S.ScheduleID = RS.ScheduleID
		INNER JOIN Catalog Ca
			ON Ca.ItemID = RS.ReportID
		INNER JOIN Subscriptions Su
			ON Su.SubscriptionID = RS.SubscriptionID
		INNER JOIN Users U
			ON U.UserID = S.CreatedById
			OR U.UserID = Su.OwnerID
	CROSS APPLY (Select s.ScheduleID,REPLACE(REPLACE(STUFF(
							(SELECT ', ['+ NameofMonth + ']' AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s1
								WHERE m1.NameofMonth IS NOT NULL 
									AND m1.powerN &amp; s1.Month &gt;0 
									AND s1.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
							, 1, 2, ''),'[',''),']','') AS NameOfMonth)c1
	CROSS APPLY (SELECT s.ScheduleID,REPLACE(REPLACE(STUFF(
							(SELECT ', [' + WkDay + ']' AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s2
								WHERE m1.WkDay IS NOT NULL 
									AND DaysOfWeek &amp; m1.powerN &gt;0
									AND  s2.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
							, 1, 2, ''),'[',''),']','') AS WkDays) c2
	WHERE Ca.Name = ISNULL(@ReportName,Ca.Name);



SELECT [Job ID] = job.job_id
		, [Job Name] = job.name
		, [Job Enabled] = CASE job.enabled
							WHEN 1 THEN 'Yes'
							WHEN 0 THEN 'No'
							END
		, [JobSchedID] = sched.schedule_id
		, PrimaryScheduleSource = 'SQL Agent Job Catalog'
		, [RecurrenceType] = CASE sched.freq_type
								WHEN 1 THEN 'Once'
								WHEN 4 THEN 'Daily'
								WHEN 8 THEN 'Weekly'
								WHEN 16 THEN 'Monthly'
								WHEN 32 THEN 'Monthly relative'
								WHEN 64 THEN 'When SQLServer Agent starts'
								END
		, [Sched Enabled] = CASE sched.enabled
								WHEN 1 THEN 'Yes'
								WHEN 0 THEN 'No'
							END
		, EventType = 'SharedSchedule'
		, CASE sched.freq_type 
			WHEN 1 THEN ''
			WHEN 4 THEN convert(VARCHAR,sched.freq_interval) + ' days'
			WHEN 8 THEN c2.WkDays
			WHEN 16 THEN 'Day of Month'
			WHEN 32 THEN case sched.freq_interval
								WHEN 1 THEN 'Sunday'
								WHEN 2 THEN 'Monday'
								WHEN 3 THEN 'Tuesday'
								WHEN 4 THEN 'Wednesday'
								WHEN 5 THEN 'Thursday'
								WHEN 6 THEN 'Friday'
								WHEN 7 THEN 'Saturday'
								WHEN 8 THEN 'Day'
								WHEN 9 THEN 'Weekday'
								WHEN 10 THEN 'Weekend Day'
								END
			WHEN 64 THEN ''
			WHEN 128 THEN ''
			END as [Frequency Interval]
		, [Relative Interval] = CASE sched.freq_relative_interval
									WHEN 1 THEN 'First'
									WHEN 2 THEN 'Second'
									WHEN 4 THEN 'Third'
									WHEN 8 THEN 'Fourth'
									WHEN 16 THEN 'Last'
									ELSE NULL
								END
		, sched.freq_recurrence_factor
		, [Next Run Date] = convert(datetime,CASE next_run_date
								WHEN 0 THEN NULL
								ELSE SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
												1, 4) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
													5, 2) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
													7, 2)
							END + ' ' + CASE LEN(next_run_time)
								WHEN 1
								THEN CAST('00:00:0' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(next_run_time, 3),
														1) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(next_run_time, 4),
														2) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(next_run_time, 5), 1)
										+ ':' + LEFT(RIGHT(next_run_time, 4), 2)
										+ ':' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(next_run_time, 6), 2) + ':'
										+ LEFT(RIGHT(next_run_time, 4), 2) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
							END)
		, [Max Duration] = CASE LEN(run_duration)
								WHEN 1
								THEN CAST('00:00:0' + CAST(run_duration AS CHAR) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + CAST(run_duration AS CHAR) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(run_duration, 3),
														1) + ':'
										+ RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(run_duration, 4), 2)
										+ ':' + RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(run_duration, 5), 1)
										+ ':' + LEFT(RIGHT(run_duration, 4), 2)
										+ ':' + RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(run_duration, 6), 2) + ':'
										+ LEFT(RIGHT(run_duration, 4), 2) + ':'
										+ RIGHT(run_duration, 2) AS CHAR(8))
							END
		, [Subday Frequency] = CASE ( sched.freq_subday_interval )
									WHEN 0 THEN 'Once'
									ELSE CAST('Every '
											+ RIGHT(sched.freq_subday_interval,
													2) + ' '
											+ CASE ( sched.freq_subday_type )
												WHEN 1 THEN 'Once'
												WHEN 4 THEN 'Minutes'
												WHEN 8 THEN 'Hours'
												END AS CHAR(16))
								END
		, [Sched End Date] = sched.active_end_date
		, [Sched End Time] = sched.active_end_time
		, [AgentScheduleStartDate] = convert(datetime,CASE sched.active_start_date
								WHEN 0 THEN NULL
								ELSE SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
												1, 4) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
													5, 2) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
													7, 2)
							END + ' ' + CASE LEN(sched.active_start_time)
								WHEN 1
								THEN CAST('00:00:0' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(sched.active_start_time, 3),
														1) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(sched.active_start_time, 4),
														2) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(sched.active_start_time, 5), 1)
										+ ':' + LEFT(RIGHT(sched.active_start_time, 4), 2)
										+ ':' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(sched.active_start_time, 6), 2) + ':'
										+ LEFT(RIGHT(sched.active_start_time, 4), 2) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
							END)
		, LastRunTime = Q1.LastRun
		, ca.ReportScheduleID
	into #ReportJobScheds
	FROM msdb.dbo.sysjobs job
		CROSS APPLY ( SELECT js.job_id, SUBSTRING(js.command, CHARINDEX('@EventData=', js.command) + 12, 36) as ReportScheduleID
							FROM msdb.dbo.sysjobsteps js
							WHERE js.command LIKE '%AddEvent @EventType=%'
					) ca
		CROSS APPLY ( SELECT CASE	WHEN TRY_CONVERT(UNIQUEIDENTIFIER, j.name) IS NULL
									THEN j.name
									ELSE NULL
								END AS jobname
							FROM msdb.dbo.sysjobs j
							WHERE j.job_id = job.job_id
					) caj
		LEFT JOIN ( SELECT job_schd.job_id
							, sys_schd.enabled
							, sys_schd.schedule_id
							, sys_schd.freq_type
							, sys_schd.freq_interval
							, sys_schd.freq_relative_interval
							, sys_schd.freq_recurrence_factor
							, sys_schd.freq_subday_type
							, sys_schd.freq_subday_interval
							, next_run_date = CASE	WHEN job_schd.next_run_date = 0
													THEN sys_schd.active_start_date
													ELSE job_schd.next_run_date
												END
							, next_run_time = CASE	WHEN job_schd.next_run_date = 0
													THEN sys_schd.active_start_time
													ELSE job_schd.next_run_time
												END
							, active_end_date = NULLIF(sys_schd.active_end_date,
														'99991231')
							, active_end_time = NULLIF(sys_schd.active_end_time,
														'235959')
							, sys_schd.active_start_date
							, sys_schd.active_start_time
						FROM msdb.dbo.sysjobschedules job_schd
							LEFT JOIN msdb.dbo.sysschedules sys_schd
								ON job_schd.schedule_id = sys_schd.schedule_id
					) sched
			ON job.job_id = sched.job_id
		LEFT OUTER JOIN ( SELECT job_id
									, MAX(job_his.run_duration) AS run_duration
									,MAX(CAST(
STUFF(STUFF(CAST(job_his.run_date as varchar),7,0,'-'),5,0,'-') + ' ' + 
STUFF(STUFF(REPLACE(STR(job_his.run_time,6,0),' ','0'),5,0,':'),3,0,':') as datetime)) AS [LastRun]
								FROM msdb.dbo.sysjobhistory job_his
								GROUP BY job_id
						) Q1
			ON job.job_id = Q1.job_id
		CROSS APPLY (SELECT sched.schedule_id,REPLACE(REPLACE(STUFF(
						(SELECT ', [' + WkDay + ']' AS [text()] 
							FROM #morepower m1 ,msdb.dbo.sysschedules s2
							WHERE m1.WkDay IS NOT NULL 
								AND freq_interval &amp; m1.powerN &gt;0
								AND  s2.schedule_id = sched.schedule_id
							ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
						, 1, 2, ''),'[',''),']','') AS WkDays) c2
	WHERE job.job_id = ca.job_id
		AND caj.jobname IS NOT NULL;


SELECT sub.ReportScheduleID
	 , rjs.[Job Name]
	 , sub.ReportManagerPath
	 , sub.ReportName
	 , sub.SubscriptionCreator
	 , rjs.PrimaryScheduleSource
	 , sub.SubscriptionDescription
	 , sub.SSRSScheduleStartDate
	 , sub.LastRunTime
	 , sub.RecurrenceType
	 , sub.[Sched Enabled]
	 , sub.EventType
	 , sub.DaysofMonth
	 , sub.MonthString
	 , sub.DaysofWeek
	 , sub.MonthlyWeek
	 , sub.DaysInterval
	 , sub.MinutesInterval
	 , sub.WeeksInterval
	FROM #ReportJobScheds rjs
		INNER JOIN (SELECT DISTINCT 
		ReportScheduleID = s.ScheduleID
		,Ca.Path as ReportManagerPath
		,Ca.Name as ReportName
		,U.UserName as SubscriptionCreator
		--,PrimaryScheduleSource = 'SSRS Catalog'
		,Su.Description as SubscriptionDescription
		,SSRSScheduleStartDate = S.StartDate
		,Su.LastRunTime
		,CASE 
				WHEN s.RecurrenceType = 1 THEN 'Once'
				WHEN s.RecurrenceType = 2 THEN 'Hourly'
				WHEN s.RecurrenceType = 3 THEN 'Daily'
				WHEN s.RecurrenceType = 4 THEN 'Weekly'
				WHEN s.RecurrenceType = 5 THEN 'Monthly' 
				WHEN s.RecurrenceType = 6 THEN 'Week of Month' 
			END AS RecurrenceType
		, [Sched Enabled] = CASE su.InactiveFlags
								WHEN 0 THEN 'Yes'
								ELSE 'No'
							END
		,s.EventType
		,ISNULL(REPLACE(REPLACE(STUFF(
					(Select ', ['+CONVERT(VARCHAR(20),MonthDate)+']' AS [text()] 
						FROM #morepower m1 
						WHERE m1.powerN &lt; s.DaysofMonth+1 
							AND s.DaysofMonth &amp; m1.powerN &gt;0 
						ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
			   , 1, 2, ''),'[',''),']','')
			,'N/A') AS DaysofMonth
		,ISNULL(c1.NameOfMonth,'N/A') AS MonthString
		,ISNULL(c2.WkDays,'N/A') AS DaysofWeek
		,CASE MonthlyWeek
				WHEN 1 THEN 'First'
				WHEN 2 THEN 'Second'
				WHEN 3 THEN 'Third'
				WHEN 4 THEN 'Fourth'
				WHEN 5 THEN 'Last'
				ELSE 'N/A'
			END AS MonthlyWeek
		,ISNULL(CONVERT(VARCHAR(10),s.DaysInterval),'N/A') AS DaysInterval
		,ISNULL(CONVERT(VARCHAR(10),s.MinutesInterval),'N/A') AS MinutesInterval
		,ISNULL(CONVERT(VARCHAR(10),s.WeeksInterval),'N/A') AS WeeksInterval
	FROM #morepower mp, dbo.Schedule s
		INNER JOIN ReportSchedule RS
			ON S.ScheduleID = RS.ScheduleID
		INNER JOIN Catalog Ca
			ON Ca.ItemID = RS.ReportID
		INNER JOIN Subscriptions Su
			ON Su.SubscriptionID = RS.SubscriptionID
		INNER JOIN Users U
			ON U.UserID = S.CreatedById
			OR U.UserID = Su.OwnerID
		CROSS APPLY (Select s.ScheduleID,REPLACE(REPLACE(STUFF(
								(SELECT ', ['+ NameofMonth + ']' AS [text()] 
									FROM #morepower m1 ,dbo.Schedule s1
									WHERE m1.NameofMonth IS NOT NULL 
										AND m1.powerN &amp; s1.Month &gt;0 
										AND s1.ScheduleID = s.ScheduleID
									ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
								, 1, 2, ''),'[',''),']','') AS NameOfMonth)c1
		CROSS APPLY (SELECT s.ScheduleID,REPLACE(REPLACE(STUFF(
								(SELECT ', [' + WkDay + ']' AS [text()] 
									FROM #morepower m1 ,dbo.Schedule s2
									WHERE m1.WkDay IS NOT NULL 
										AND DaysOfWeek &amp; m1.powerN &gt;0
										AND  s2.ScheduleID = s.ScheduleID
									ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
								, 1, 2, ''),'[',''),']','') AS WkDays) c2
	WHERE Ca.Name = ISNULL(@ReportName,Ca.Name)) sub
	ON sub.ReportScheduleID = rjs.ReportScheduleID
UNION ALL
SELECT ss.ReportScheduleID
	 , [Job Name] = CONVERT(VARCHAR(64),ss.ReportScheduleID)
	 , ss.ReportManagerPath
	 , ss.ReportName
	 , ss.SubscriptionCreator
	 , ss.PrimaryScheduleSource
	 , ss.SubscriptionDescription
	 , ss.SSRSScheduleStartDate
	 , ss.LastRunTime
	 , ss.RecurrenceType
	 , ss.[Sched Enabled]
	 , ss.EventType
	 , ss.DaysofMonth
	 , ss.MonthString
	 , ss.DaysofWeek
	 , ss.MonthlyWeek
	 , ss.DaysInterval
	 , ss.MinutesInterval
	 , ss.WeeksInterval
	From #SSRSScheds ss;

SELECT sub.[Job ID]
	 , sub.[Job Name]
	 , sub.[Job Enabled]
	 , sub.JobSchedID
	 , rjs.PrimaryScheduleSource
	 , sub.RecurrenceType
	 , sub.[Sched Enabled]
	 , sub.EventType
	 , sub.[Frequency Interval]
	 , sub.[Relative Interval]
	 , sub.freq_recurrence_factor
	 , sub.[Next Run Date]
	 , sub.[Max Duration]
	 , sub.[Subday Frequency]
	 , sub.[Sched End Date]
	 , sub.[Sched End Time]
	 , sub.AgentScheduleStartDate
	 , sub.LastRunTime
	 , rjs.ReportScheduleID
	 , InStepScheduleID = sub.ReportScheduleID -- sometimes the scheduleid in the step is different from the actual scheduleid
	FROM #SSRSScheds rjs
		LEFT OUTER JOIN (SELECT [Job ID] = job.job_id
		, [Job Name] = caj.jobname
		, [Job Enabled] = CASE job.enabled
							WHEN 1 THEN 'Yes'
							WHEN 0 THEN 'No'
							END
		, [JobSchedID] = sched.schedule_id
		, PrimaryScheduleSource = 'SQL Agent Job Catalog'
		, [RecurrenceType] = CASE sched.freq_type
								WHEN 1 THEN 'Once'
								WHEN 4 THEN 'Daily'
								WHEN 8 THEN 'Weekly'
								WHEN 16 THEN 'Monthly'
								WHEN 32 THEN 'Monthly relative'
								WHEN 64 THEN 'When SQLServer Agent starts'
								END
		, [Sched Enabled] = CASE sched.enabled
								WHEN 1 THEN 'Yes'
								WHEN 0 THEN 'No'
							END
		, EventType = 'SharedSchedule'
		, CASE sched.freq_type 
			WHEN 1 THEN ''
			WHEN 4 THEN convert(VARCHAR,sched.freq_interval) + ' days'
			WHEN 8 THEN c2.WkDays
			WHEN 16 THEN 'Day of Month'
			WHEN 32 THEN case sched.freq_interval
								WHEN 1 THEN 'Sunday'
								WHEN 2 THEN 'Monday'
								WHEN 3 THEN 'Tuesday'
								WHEN 4 THEN 'Wednesday'
								WHEN 5 THEN 'Thursday'
								WHEN 6 THEN 'Friday'
								WHEN 7 THEN 'Saturday'
								WHEN 8 THEN 'Day'
								WHEN 9 THEN 'Weekday'
								WHEN 10 THEN 'Weekend Day'
								END
			WHEN 64 THEN ''
			WHEN 128 THEN ''
			END as [Frequency Interval]
		, [Relative Interval] = CASE sched.freq_relative_interval
									WHEN 1 THEN 'First'
									WHEN 2 THEN 'Second'
									WHEN 4 THEN 'Third'
									WHEN 8 THEN 'Fourth'
									WHEN 16 THEN 'Last'
									ELSE NULL
								END
		, sched.freq_recurrence_factor
		, [Next Run Date] = convert(datetime,CASE next_run_date
								WHEN 0 THEN NULL
								ELSE SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
												1, 4) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
													5, 2) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), next_run_date),
													7, 2)
							END + ' ' + CASE LEN(next_run_time)
								WHEN 1
								THEN CAST('00:00:0' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(next_run_time, 3),
														1) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(next_run_time, 4),
														2) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(next_run_time, 5), 1)
										+ ':' + LEFT(RIGHT(next_run_time, 4), 2)
										+ ':' + RIGHT(next_run_time, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(next_run_time, 6), 2) + ':'
										+ LEFT(RIGHT(next_run_time, 4), 2) + ':'
										+ RIGHT(next_run_time, 2) AS CHAR(8))
							END)
		, [Max Duration] = CASE LEN(run_duration)
								WHEN 1
								THEN CAST('00:00:0' + CAST(run_duration AS CHAR) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + CAST(run_duration AS CHAR) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(run_duration, 3),
														1) + ':'
										+ RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(run_duration, 4), 2)
										+ ':' + RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(run_duration, 5), 1)
										+ ':' + LEFT(RIGHT(run_duration, 4), 2)
										+ ':' + RIGHT(run_duration, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(run_duration, 6), 2) + ':'
										+ LEFT(RIGHT(run_duration, 4), 2) + ':'
										+ RIGHT(run_duration, 2) AS CHAR(8))
							END
		, [Subday Frequency] = CASE ( sched.freq_subday_interval )
									WHEN 0 THEN 'Once'
									ELSE CAST('Every '
											+ RIGHT(sched.freq_subday_interval,
													2) + ' '
											+ CASE ( sched.freq_subday_type )
												WHEN 1 THEN 'Once'
												WHEN 4 THEN 'Minutes'
												WHEN 8 THEN 'Hours'
												END AS CHAR(16))
								END
		, [Sched End Date] = sched.active_end_date
		, [Sched End Time] = sched.active_end_time
		, [AgentScheduleStartDate] = convert(datetime,CASE sched.active_start_date
								WHEN 0 THEN NULL
								ELSE SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
												1, 4) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
													5, 2) + '/'
										+ SUBSTRING(CONVERT(VARCHAR(15), sched.active_start_date),
													7, 2)
							END + ' ' + CASE LEN(sched.active_start_time)
								WHEN 1
								THEN CAST('00:00:0' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 2
								THEN CAST('00:00:' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 3
								THEN CAST('00:0' + LEFT(RIGHT(sched.active_start_time, 3),
														1) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 4
								THEN CAST('00:' + LEFT(RIGHT(sched.active_start_time, 4),
														2) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 5
								THEN CAST('0' + LEFT(RIGHT(sched.active_start_time, 5), 1)
										+ ':' + LEFT(RIGHT(sched.active_start_time, 4), 2)
										+ ':' + RIGHT(sched.active_start_time, 2) AS CHAR(8))
								WHEN 6
								THEN CAST(LEFT(RIGHT(sched.active_start_time, 6), 2) + ':'
										+ LEFT(RIGHT(sched.active_start_time, 4), 2) + ':'
										+ RIGHT(sched.active_start_time, 2) AS CHAR(8))
							END)
		, LastRunTime = Q1.LastRun
		, ca.ReportScheduleID
	FROM msdb.dbo.sysjobs job
		CROSS APPLY ( SELECT js.job_id, SUBSTRING(js.command, CHARINDEX('@EventData=', js.command) + 12, 36) as ReportScheduleID
							FROM msdb.dbo.sysjobsteps js
							WHERE js.command LIKE '%AddEvent @EventType=%'
					) ca
		CROSS APPLY ( SELECT CASE	WHEN TRY_CONVERT(UNIQUEIDENTIFIER, j.name) IS NULL
									THEN NULL
									ELSE j.name
								END AS jobname
							FROM msdb.dbo.sysjobs j
							WHERE j.job_id = job.job_id
					) caj
		LEFT JOIN ( SELECT job_schd.job_id
							, sys_schd.enabled
							, sys_schd.schedule_id
							, sys_schd.freq_type
							, sys_schd.freq_interval
							, sys_schd.freq_relative_interval
							, sys_schd.freq_recurrence_factor
							, sys_schd.freq_subday_type
							, sys_schd.freq_subday_interval
							, next_run_date = CASE	WHEN job_schd.next_run_date = 0
													THEN sys_schd.active_start_date
													ELSE job_schd.next_run_date
												END
							, next_run_time = CASE	WHEN job_schd.next_run_date = 0
													THEN sys_schd.active_start_time
													ELSE job_schd.next_run_time
												END
							, active_end_date = NULLIF(sys_schd.active_end_date,
														'99991231')
							, active_end_time = NULLIF(sys_schd.active_end_time,
														'235959')
							, sys_schd.active_start_date
							, sys_schd.active_start_time
						FROM msdb.dbo.sysjobschedules job_schd
							LEFT JOIN msdb.dbo.sysschedules sys_schd
								ON job_schd.schedule_id = sys_schd.schedule_id
					) sched
			ON job.job_id = sched.job_id
		LEFT OUTER JOIN ( SELECT job_id
								, MAX(job_his.run_duration) AS run_duration
								,MAX(CAST(
								STUFF(STUFF(CAST(job_his.run_date AS VARCHAR),7,0,'-'),5,0,'-') + ' ' + 
								STUFF(STUFF(REPLACE(STR(job_his.run_time,6,0),' ','0'),5,0,':'),3,0,':') AS DATETIME)) AS [LastRun]
							FROM msdb.dbo.sysjobhistory job_his
							GROUP BY job_id
						) Q1
			ON job.job_id = Q1.job_id
		CROSS APPLY (SELECT sched.schedule_id,REPLACE(REPLACE(STUFF(
						(SELECT ', [' + WkDay + ']' AS [text()] 
							FROM #morepower m1 ,msdb.dbo.sysschedules s2
							WHERE m1.WkDay IS NOT NULL 
								AND freq_interval &amp; m1.powerN &gt;0
								AND  s2.schedule_id = sched.schedule_id
							ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
						, 1, 2, ''),'[',''),']','') AS WkDays) c2
	WHERE job.job_id = ca.job_id
		) sub
	ON sub.[Job Name] = rjs.ReportScheduleID
UNION ALL
	SELECT rjs.[Job ID]
			, rjs.[Job Name]
			, rjs.[Job Enabled]
			, rjs.JobSchedID
			, rjs.PrimaryScheduleSource
			, rjs.RecurrenceType
			, rjs.[Sched Enabled]
			, rjs.EventType
			, rjs.[Frequency Interval]
			, rjs.[Relative Interval]
			, rjs.freq_recurrence_factor
			, rjs.[Next Run Date]
			, rjs.[Max Duration]
			, rjs.[Subday Frequency]
			, rjs.[Sched End Date]
			, rjs.[Sched End Time]
			, rjs.AgentScheduleStartDate
			, rjs.LastRunTime
			, rjs.ReportScheduleID
			, InStepScheduleID = rjs.ReportScheduleID
		FROM #ReportJobScheds rjs;</pre><p>As you can see, it is not a short script. By fair measure, it is also considerably more complex than the XML version that was <a href="http://bit.ly/2rcPAmG">recently posted</a> (and mentioned earlier in this article). That said, it is many times more flexible and complete than the XML version as well. I do continue to use the bit math for figuring the schedules as I did in the <a href="http://bit.ly/UwcgTY">first version of the script</a>. When done this way, I can handle the custom schedules as well as get extensive details about the schedule from both the msdb and ReportServer databases.</p>
<h3>Recap</h3>
<p>SSRS provides built-in mechanisms to help report on the scheduled reports that have been deployed. This version of the report will help you retrieve the data from both a job perspective and from the report scheduler perspective. Through this series of articles, you should be confident in being able to now create custom schedules as well as accurately report on any reports that have specific subscriptions/schedules.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3818" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/05/25/last-restore-of-a-database-back-to-basics-2-2-2/">SSRS Subscription Schedules – Enhanced</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/05/25/last-restore-of-a-database-back-to-basics-2-2-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SSRS Subscription Schedules</title>
		<link>https://jasonbrimhall.info/2017/05/23/last-restore-of-a-database-back-to-basics-2-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=last-restore-of-a-database-back-to-basics-2-2</link>
					<comments>https://jasonbrimhall.info/2017/05/23/last-restore-of-a-database-back-to-basics-2-2/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 23 May 2017 13:05:48 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[Shared Schedule]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3812</guid>

					<description><![CDATA[<p>With the ability to create content delivery schedules, or to subscribe to report content delivery, this imposes a requirement to also know when the various reports are scheduled to be delivered.</p>
The post <a href="https://jasonbrimhall.info/2017/05/23/last-restore-of-a-database-back-to-basics-2-2/">SSRS Subscription Schedules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Reporting Services</h2>
<h3><img loading="lazy" class="wp-image-3804 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png" alt="" width="155" height="155" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png 1000w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-50x50.png 50w" sizes="(max-width: 155px) 85vw, 155px" /></h3>
<p>Reporting Services (SSRS) is a tool that permits you to create and deliver feature rich reports. The reports can be delivered in various formats and can even be scheduled to be delivered at various times. I even recently wrote about creating more advanced custom schedules.</p>
<p>With the ability to create content delivery schedules, or to subscribe to report content delivery, this imposes a requirement to also know when the various reports are scheduled to be delivered.</p>
<p>SSRS provides the means to be able to review the scheduled reports (subscriptions). That means is held within the ReportServer database. This article will help to uncover one of the sources of this scheduling information within the ReportServer database.</p>
<h3>Review Schedules</h3>
<p>When looking into the database for SSRS, I can see there are different means to be able to review the report schedules. This article is going to cover just one of those methods. And if I am going to be entirely up front about this method, I don&#8217;t like it and I recommend that it not be use.</p>
<p>I can hear the moans now. &#8220;If you don&#8217;t like it, then why show it to us?&#8221; Well, that is a very good question and there is a very good reason for this decision. A lesson I learned a long time ago is sometimes you need to learn the hard way, or less desirable way, to do various things. One of my favorite Calculus teachers from years ago drilled this into my head over and over again. Why? Well, there are three good reasons that come to mind: a) it makes the more desirable method seem much easier, b) it helps you to appreciate the more desirable method all that much more, and c) because if all else fails, you will have another method to fall back to just in case.</p>
<h3>Less Disérables</h3>
<p>The least desirable method (at least of the methods I will share) is to parse XML from a field stored in the ReportServer database. If I look into the Schedule table within the RepotServer database, I will find this column called MatchData. Up front, this field is not very intuitively named. I would not think this field actually represented the schedule, but it actually does.</p>
<p>Before we start diving into parsing XML, we need an example of what this XML may look like. The following will provide that very example that we need.</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;ScheduleDefinition xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
  &lt;StartDateTime xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/03/01/ReportServer"&gt;2017-03-27T02:00:00.000-06:00&lt;/StartDateTime&gt;
  &lt;MonthlyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/03/01/ReportServer"&gt;
    &lt;Days&gt;1&lt;/Days&gt;
    &lt;MonthsOfYear&gt;
      &lt;January&gt;true&lt;/January&gt;
      &lt;February&gt;true&lt;/February&gt;
      &lt;March&gt;true&lt;/March&gt;
      &lt;April&gt;true&lt;/April&gt;
      &lt;May&gt;true&lt;/May&gt;
      &lt;June&gt;true&lt;/June&gt;
      &lt;July&gt;true&lt;/July&gt;
      &lt;August&gt;true&lt;/August&gt;
      &lt;September&gt;true&lt;/September&gt;
      &lt;October&gt;true&lt;/October&gt;
      &lt;November&gt;true&lt;/November&gt;
      &lt;December&gt;true&lt;/December&gt;
    &lt;/MonthsOfYear&gt;
  &lt;/MonthlyRecurrence&gt;
	&lt;MinuteRecurrence xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/03/01/ReportServer"&gt;
		&lt;MinutesInterval&gt;75&lt;/MinutesInterval&gt;
	&lt;/MinuteRecurrence&gt;
	&lt;WeeklyRecurrence xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/03/01/ReportServer"&gt;
		&lt;WeeksInterval&gt;1&lt;/WeeksInterval&gt;
		&lt;DaysOfWeek&gt;
			&lt;Sunday&gt;true&lt;/Sunday&gt;
			&lt;Tuesday&gt;true&lt;/Tuesday&gt;
			&lt;Thursday&gt;true&lt;/Thursday&gt;
			&lt;Friday&gt;true&lt;/Friday&gt;
		&lt;/DaysOfWeek&gt;
	&lt;/WeeklyRecurrence&gt;
&lt;/ScheduleDefinition&gt;</pre><p>Are your gears grinding yet? The XML is not terribly difficult to follow. I am sure you have realized the problem from this format at this point. If I query this to make it human readable in a tabular format (you know DBA format), I will end up with a really wide table that is pretty ugly to look at (unless I get super creative to combine fields etc).</p>
<p>Let&#8217;s take a look at the query to parse something like the preceding XML example.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/reporting/2010/03/01/ReportServer' AS rs)
, getxml AS (
	SELECT SUB.SubscriptionID
			, ReportName = CAT.[Name]
			, ExtensionSettings = CAST(SUB.ExtensionSettings AS XML)
			, ReportSchedule = CAST(SUB.MatchData AS XML)
		FROM dbo.Subscriptions AS SUB
			INNER JOIN dbo.Users AS USR
				ON SUB.OwnerID = USR.UserID
			INNER JOIN dbo.[Catalog] AS CAT
				ON SUB.Report_OID = CAT.ItemID
			INNER JOIN dbo.ReportSchedule AS RS
				ON SUB.Report_OID = RS.ReportID
					AND SUB.SubscriptionID = RS.SubscriptionID
			INNER JOIN dbo.Schedule AS SCH
				ON RS.ScheduleID = SCH.ScheduleID 
  --WHERE CONVERT(CHAR(8), SUB.LastRunTime, 112  ) &gt; '20170101' 
)
SELECT SubscriptionID
		, ReportName
		, [StartHour] = SUBSTRING(( c.nd.value('(rs:StartDateTime/text())[1]',
												'VARCHAR(500)') ), 12, 2)
		, [StartMin] = SUBSTRING(( c.nd.value('(rs:StartDateTime/text())[1]',
												'VARCHAR(500)') ), 15, 2)
		, [Days] = c.nd.value('(rs:MonthlyRecurrence/rs:Days/text())[1]', 'INT')
		, [January] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:January/text())[1]',
									'BIT')
		, [February] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:February/text())[1]',
									'BIT')
		, [March] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:March/text())[1]',
								'BIT')
		, [April] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:April/text())[1]',
								'BIT')
		, [May] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:May/text())[1]',
								'BIT')
		, [June] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:June/text())[1]',
								'BIT')
		, [July] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:July/text())[1]',
								'BIT')
		, [August] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:August/text())[1]',
								'BIT')
		, [September] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:September/text())[1]',
									'BIT')
		, [October] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:October/text())[1]',
									'BIT')
		, [November] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:November/text())[1]',
									'BIT')
		, [December] = c.nd.value('(rs:MonthlyRecurrence/rs:MonthsOfYear/rs:December/text())[1]',
									'BIT')
		, [Sunday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Sunday/text())[1]',
								'BIT')
		, [Monday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Monday/text())[1]',
								'BIT')
		, [Tuesday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Tuesday/text())[1]',
									'BIT')
		, [Wednesday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Wednesday/text())[1]',
									'BIT')
		, [Thursday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Thursday/text())[1]',
									'BIT')
		, [Friday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Friday/text())[1]',
								'BIT')
		, [Saturday] = c.nd.value('(rs:WeeklyRecurrence/rs:DaysOfWeek/rs:Saturday/text())[1]',
									'BIT')
		, [WeeksInterval] = c.nd.value('(rs:WeeklyRecurrence/rs:WeeksInterval/text())[1]',
										'INT')
		, [MinuteRecurrence] = c.nd.value('(rs:MinuteRecurrence/rs:MinutesInterval/text())[1]',
											'INT')
	FROM getxml
		CROSS APPLY ReportSchedule.nodes('//ScheduleDefinition') c ( nd )
	ORDER BY SubscriptionID
		, ReportName;</pre><p>And there we have that ugly query to produce a really wide ugly result set. The query is not difficult to write. It&#8217;s just extremely repetitive. In similar fashion, the results are very repetitive. This makes, in my eyes, this particular method less desirable.</p>
<p>I haven&#8217;t even gotten to the part about the shortcoming in scheduling reports through SSRS that I wrote about recently &#8211; <a href="http://bit.ly/2qMuhat">here</a>. In that article I discussed a workaround to overcome the SSRS scheduling options. If you employ methods such as I discussed there, then this query will never fully cover the scheduling related to your reports. Because of that, I will be discussing the better solution in the next article.</p>
<h3>Recap</h3>
<p>SSRS provides built-in mechanisms to help report on the scheduled reports that have been deployed. While parsing the XML is less desirable than what I will be sharing in the near future, it is better than doing nothing at all. I recommend you start looking into the various report schedules you may already have in your environment. Also, stay tuned for the next article that will better show these schedules.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3812" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/05/23/last-restore-of-a-database-back-to-basics-2-2/">SSRS Subscription Schedules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/05/23/last-restore-of-a-database-back-to-basics-2-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SSRS Custom Shared Schedule</title>
		<link>https://jasonbrimhall.info/2017/05/22/ssrs-custom-shared-schedule/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssrs-custom-shared-schedule</link>
					<comments>https://jasonbrimhall.info/2017/05/22/ssrs-custom-shared-schedule/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 22 May 2017 13:05:29 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[Shared Schedule]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3803</guid>

					<description><![CDATA[<p>Reporting Services is a pretty feature rich tool for delivering reports to various consumers. Unfortunately, the scheduling capability within SSRS is fairly weak.</p>
The post <a href="https://jasonbrimhall.info/2017/05/22/ssrs-custom-shared-schedule/">SSRS Custom Shared Schedule</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Reporting Services</h2>
<p>&nbsp;</p>
<h3><img loading="lazy" class="wp-image-3804 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png" alt="" width="155" height="155" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar.png 1000w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-768x768.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/calendar-50x50.png 50w" sizes="(max-width: 155px) 85vw, 155px" /></h3>
<p>Reporting Services is a pretty feature rich tool for delivering reports to various consumers. There is plenty of power within Reporting Services (SSRS) giving one the ability to perform visualizations, render reports in various formats and even schedule reports to be delivered in different formats or on different schedules.</p>
<p>Unfortunately, the scheduling capability within SSRS is fairly weak. While it is true that one can accomplish a varied array of different schedules, the scheduling of SSRS is far below the power of SQL Agent (for instance).</p>
<p>I will explore the deficiency of the scheduling tool within SSRS in a very specific case. You may even be familiar with this deficiency already. Many organizations have the need to produce end of month reports that need to run on the last day of the month. If you are familiar with the scheduling tool within SSRS, you already know that this is not possible (at least through SSRS 2014). This article will help step you through how to schedule a report subscription to run on the last day of the month.</p>
<h3>Schedule Options</h3>
<p>Before diving into the custom schedules, let&#8217;s take a closer look at the options available for scheduling through SSRS.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3806" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/ssrs_monthly_options.jpg" alt="" width="912" height="510" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/ssrs_monthly_options.jpg 912w, https://jasonbrimhall.info/wp-content/uploads/2017/05/ssrs_monthly_options-300x168.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/ssrs_monthly_options-768x429.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/ssrs_monthly_options-50x28.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<p>While the tool does provide various options, the granularity certainly is not diverse enough to cover many legitimate scheduling needs &#8211; especially the &#8220;last day of month&#8221; requirement for many month end type of reports.</p>
<p>As you may be aware, SSRS subscriptions are actually run through the SQL Agent despite being set through SSRS. If I take a look at some of the scheduling options in SQL Agent, I can see the following.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3807" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options.jpg" alt="" width="840" height="731" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options.jpg 840w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options-300x261.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options-768x668.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options-50x44.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<p>Note here that there are various built-in options to schedule on a monthly basis, including the &#8220;last&#8221; option. If I wanted to look even closer at the available options I would see the following.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3808" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options_2.jpg" alt="" width="841" height="740" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options_2.jpg 841w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options_2-300x264.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options_2-768x676.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/agent_monthly_options_2-50x44.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></p>
<p>As you can see here, I can schedule for multiple different types of &#8220;last&#8221; options relative to the month. One of these options happens to be the last day. This helps to illustrate just how much more powerful and versatile the scheduling within SQL Agent is than what we get with the SSRS scheduler. All of this despite the fact that SSRS subscriptions are actually executed by the SQL Agent. Doesn&#8217;t that seem a bit odd?</p>
<h3>Custom Schedule</h3>
<p>Now that we better understand the limitations of the SSRS scheduler and given that SSRS subscriptions are executed through the SQL Agent, let&#8217;s move on to bigger, better and much more useful means of scheduling the SSRS reports.</p>
<p>The very first thing that you should do is to create a share schedule. This should be a shared schedule that is created as a run-once schedule. Let the schedule run that one time and then proceed on to the following steps. If you need help in creating a shared schedule, here is an <a href="https://technet.microsoft.com/en-us/library/bb326287%28v=sql.105%29.aspx?f=255&amp;MSPPError=-2147217396">msdn article</a>. When you create the shared schedule, I recommend using a descriptive name that you can remember. This name will be useful in the next step. For the purposes of this article, my schedule is named &#8220;EndOfMonth&#8221;.</p>
<p>Once the schedule is created, the next thing to do is to query the ReportServer database. Make sure you know the name of your database. Some people have changed the ReportServer database name from the default. This is an important piece of information to remember. The query against the ReportServer database will be predominantly just to get the schedule id of the newly created schedule.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sch.scheduleid
		, sub.Description
		, sch.Name
	FROM subscriptions sub
		LEFT JOIN reportschedule rs
			ON sub.subscriptionid = rs.subscriptionid
		LEFT JOIN schedule sch
			ON sch.scheduleid = rs.scheduleid
	WHERE sch.Name = 'EndofMonth'
	ORDER BY sub.modifieddate DESC;</pre><p>When I run that query, I receive the following results.</p>
<p><img loading="lazy" class="aligncenter wp-image-3809 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/sharedsched_id.jpg" alt="" width="672" height="111" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/sharedsched_id.jpg 672w, https://jasonbrimhall.info/wp-content/uploads/2017/05/sharedsched_id-300x50.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/sharedsched_id-50x8.jpg 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
<p>I now want to take that scheduleid and then use it to determine what SQL Agent job is actually related to that schedule so I can fetch some info from the job. I could skip this entirely and go to the subsequent step but this helps to understand what needs to be done in that subsequent step. So, from here let&#8217;s query the msdb database in SQL Server to fetch some info from the job system.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT j.name
		, j.job_id
		, js.step_name
		, js.command
		, sp.name AS JobOwner
	FROM msdb.dbo.sysjobs j
		INNER JOIN msdb.dbo.sysjobsteps js
			ON j.job_id = js.job_id
		INNER JOIN sys.server_principals sp
			ON j.owner_sid = sp.sid
	WHERE js.command LIKE '%219542cc-c1e8-4b42-889f-682d7276a07a%'
		AND j.description like 'This job is owned by a report server process. %';</pre><p>The scheduleid is used within a command within a jobstep. By passing the scheduleid into this query and then comparing against the existing job steps, I am able to retrieve the job that is related to the SSRS shared schedule (subscription). When I run the preceding query, I receive results illustrated in the following image.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3810" src="http://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo-1024x189.png" alt="" width="560" height="103" srcset="https://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo-1024x189.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo-300x55.png 300w, https://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo-768x142.png 768w, https://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo-50x9.png 50w, https://jasonbrimhall.info/wp-content/uploads/2017/05/jobsystem_subscriptioninfo.png 1204w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Take note of the items I highlighted in red. Within the job name, step name and command text for the step, I can find the scheduleid for that shared schedule that I created. Yes, I could easily have changed the query I used to compare to the job name and that would have worked just fine in this case. By querying the command, I can confirm that the schedule is actually being used. The most important piece of information in this result is the entire command text for the job. I will need to take this command text and use it to populate a brand new SQL Agent job. This is how I will get my custom schedule for the SSRS subscription.</p><pre class="urvanov-syntax-highlighter-plain-tag">exec [ReportServer2012].dbo.AddEvent @EventType='SharedSchedule', @EventData='219542cc-c1e8-4b42-889f-682d7276a07a'</pre><p>From here, I just need to create a SQL Agent job that uses the options for a monthly schedule indicating last day from the two drop down menus illustrated previously in this article. Then all that is left is a sigh of relief and a boom bada bing.</p>
<h3>Recap</h3>
<p>SSRS does not have the built-in capability for some of the more complex and often times regularly required report schedules to meet various business requirements. By following the steps outlined in this article, you can circumvent that short-coming and achieve the needed business requirements while looking like a hero to those that need the more advanced report schedules.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3803" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/05/22/ssrs-custom-shared-schedule/">SSRS Custom Shared Schedule</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/05/22/ssrs-custom-shared-schedule/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Parse Dynamics AX Context Info</title>
		<link>https://jasonbrimhall.info/2017/01/30/parse-dynamics-ax-context-info/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=parse-dynamics-ax-context-info</link>
					<comments>https://jasonbrimhall.info/2017/01/30/parse-dynamics-ax-context-info/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 30 Jan 2017 20:02:23 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Restore]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3761</guid>

					<description><![CDATA[<p>In this article I will only be discussing the AX product and an easy tweak to make troubleshooting that product much easier from the perspective of the database administrator. This tweak is to enable the context info from within the administration console.</p>
The post <a href="https://jasonbrimhall.info/2017/01/30/parse-dynamics-ax-context-info/">Parse Dynamics AX Context Info</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Dynamics AX and SQL Server</h2>
<p>More and more I am seeing clients requiring assistance with the Microsoft Dynamics Suite. Each of the products in the suite comes with a different set of performance issues and gotchas. In this article I will only be discussing the AX product and an easy tweak to make troubleshooting that product much easier from the perspective of the database administrator. This tweak is to enable the context info from within the administration console.</p>
<h1>Enable Context Info</h1>
<p>Some may call this a critical setting that must be activated on every transaction heavy Dynamics AX AOS server. One of the most common reasons is that DAX user sessions frequently block one another. Occasionally the blocking may be uncomfortably long.</p>
<p>In  order to enable this setting on each DAX AOS server, the following steps should be followed:</p>
<ul>
<li>Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\DynamicsServer\6.01\Original (installed configuration). The last key, Original (installed configuration), is the key name for the current server configuration. If your system uses a different configuration than the original installed configuration, navigate to the currently active configuration.</li>
<li>Create a string registry value called ‘connectioncontext’ and set the value to 1.</li>
<li>Restart the AOS.</li>
</ul>
<p>The steps to implement this change is not terribly difficult. The risk is very low as well. There is very minimal cost for sending this additional info. That said, even on an extremely busy system for one client, we have yet to see a negative impact with this setting enabled.</p>
<h2>Easy Troubleshooting for the DBA</h2>
<p>Now that the context info is enabled within the application, this is where the pains of troubleshooting AX performance issues within the database becomes somewhat easier for the database administrator. Just enabling the setting doesn&#8217;t bring you to the promised land though. You still need to do a bit of work.</p>
<p>Once the setting is enabled, what actually happens is the AX application starts to send an extra chunk of data along with each connection to the database server. This chunk of data is the context info. The context info that AX decides to send along is not straight-forward to read however. The AX context info is sent to SQL Server as a varbinary.</p>
<p>What does it mean to be in varbinary format for you as the database administrator? This means that you still have a bit of work to do. Do you need to perform that extra work every time you look at the data? Well, the short answer is &#8220;it depends&#8221;! If you are smart about your tool-set (e.g. set of administration scripts) then you will save this extra work there. If you do not yet have a tool-set and rewrite your queries every time &#8211; you obviously fall at the far opposite end of the spectrum and will have much more work to do.</p>
<p>Whichever end of the spectrum you fall within, here is script to integrate into your scripts to help make your AX DBA work just a tad bit easier.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT SUBSTRING(REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))), ' ',
							','),
					CHARINDEX(',',
								REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))),
										' ', ',')) + 1,
					CHARINDEX(',',
								REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))),
										' ', ','),
								CHARINDEX(',',
											REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))),
													' ', ',')) + 1)
					- ( CHARINDEX(',',
									REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))),
											' ', ',')) )
					- CASE	WHEN CAST(s.context_info AS VARCHAR(256)) = ''
							THEN 0
							ELSE 1
						END) AS DAXSessionID
		, SUBSTRING(REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))), ' ',
							','), 1,
					CHARINDEX(',',
								REPLACE(LTRIM(CAST(s.context_info AS VARCHAR(256))),
										' ', ','))
					- CASE	WHEN CAST(s.context_info AS VARCHAR(256)) = ''
							THEN 0
							ELSE 1
						END) AS DAXUser
		, s.context_info
	FROM sys.dm_exec_sessions s
	WHERE ISNULL(CAST(s.context_info AS VARCHAR(256)),'') &lt;&gt; '';</pre><p></p>
<h2>So What does it DO?</h2>
<p>So what value does this query actually bring you? I have talked about it making life easier by enabling the context info from within AX, but I didn&#8217;t dive into any details on what it will provide.</p>
<p>Looking at the query I just provided, one can surmise that the context info will provide two significant pieces of information. The first bit is the Session ID. This is not the spid within SQL Server. Rather this is the session id that is a different value within AX. The second piece of information that is highly valuable is the User that is tied to that AX Session. The AX application will show as the service account for the application on all spids within SQL Server. The spid and spid user are fairly useless when trying to figure out who is causing what level of pain since all users in SQL Server for AX will appear to be the same user. The SQL spid will be useless for the DAX admins because the spid will not match the DAX session id. Both of these factors will lead to an extra amount of frustration between the DBA and DAX Admin if in the middle of a performance slowdown.</p>
<p>Being able to extract the DAX User and Session ID from the context info will significantly reduce troubleshooting time when in the trenches trying to figure out who is running what from within the application. This reduces the chances of taking a guess and gives good solid evidence that can be taken back to the business users and try to improve their processes and the overall performance of the system.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3761" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2017/01/30/parse-dynamics-ax-context-info/">Parse Dynamics AX Context Info</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2017/01/30/parse-dynamics-ax-context-info/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>User Contains Invalid Characters &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=user-contains-invalid-characters-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 24 Dec 2016 00:57:57 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Restore]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3756</guid>

					<description><![CDATA[<p>While creating database users, it is possible to encounter an invalid character error message. This article will help clarify the error message.</p>
The post <a href="https://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">User Contains Invalid Characters – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>I did not officially accept the challenge. Was an official acceptance required? I don&#8217;t know. I do know that I think it is a good challenge and that I intend to participate in the challenge. I hope I can meet the requirements and keep the posts to &#8220;basics&#8221;. Let&#8217;s hope this post holds up to the intent of the challenge.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Logins and Users</h2>
<p>It seems appropriate to re-introduce the concept of principals (aka Logins and Users). Rather than go into depth about principals here though, I will refer you to a recent article on the topic. The article in question was another &#8220;basics&#8221; article and can be found <a href="http://bit.ly/1PIG0i7">here</a>.</p>
<p><img loading="lazy" class=" wp-image-3757 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/invalid.png" alt="invalid" width="258" height="100" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/invalid.png 335w, https://jasonbrimhall.info/wp-content/uploads/2016/12/invalid-300x116.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/12/invalid-50x19.png 50w" sizes="(max-width: 258px) 85vw, 258px" />With that out of the way, it should be conceded that creating principals is a common practice and possibly a frequent requirement of the data professional. While creating those principals, there is a good chance that one will run into an absurd error ever now and then. Today, I want to discuss one absurd error. The fix for the error may seem just as absurd as the error, but would be really easy to implement.</p>
<h3>Invalid Characters</h3>
<p>Here is the error message that is quite possible to encounter while creating principals.</p>
<blockquote><p><span style="color: #ff0000;">Msg 15006, Level 16, State 1, Line 6</span><br />
<span style="color: #ff0000;">&#8216;SomeDOmain\jason&#8217; is not a valid name because it contains invalid characters.</span></p></blockquote>
<p>At first look, this error makes absolutely no sense. The error states there is an invalid character somewhere in the string &#8220;SomeDomain\jason&#8221;, yet every character in that string is supported and normal for the collation. This can be a head-scratcher for sure.</p>
<p>To better understand this error, let&#8217;s try to reproduce the error. First, we need to create a login.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE LOGIN [SomeDomain\jason] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
GO</pre><p>Here, I have used &#8220;SomeDomain&#8221; in lieu of my actual domain or local workstation name. This statement will complete successfully given the user exists within the domain or on the Windows workstation. Great so far!</p>
<p>The next step is to create a database user within the AdminDB (you can pick a database that exists in your environment) and map this user to the Login created in the previous step. This can be done with the following script:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdminDB
GO
CREATE USER [SomeDOmain\jason] FOR LOGIN [SomeD0main\jason]
GO</pre><p>Bam! Executing the script produces:</p>
<blockquote><p><span style="color: #ff0000;">Msg 15006, Level 16, State 1, Line 6</span><br />
<span style="color: #ff0000;">&#8216;SomeDOmain\jason&#8217; is not a valid name because it contains invalid characters.</span></p></blockquote>
<p>This is where a close inspection of the script is required. Due to a fabulous fat finger, a 0 (zero) instead of O (capital o) was typed in the second occurrence of &#8220;SomeDOmain&#8221;. This is easy enough to reproduce with a typo of any portion of the windows login that already exists in SQL as a login principal.</p>
<h3>The Fix</h3>
<p>The fix is insanely easy once you figure out that invalid character actually means you mis-typed the Login portion of the Create User statement. The fix is to type the login <em><span style="text-decoration: underline;">correctly</span></em>. Knowing is half the battle! Running into this error in the wild could cause you a few minutes trying to figure it out and prepping to throw something through the monitor.</p>
<h3>Recap</h3>
<p>In this article I have shown how a simple mistake can lead to a really obtuse error message that doesn&#8217;t seem to make much sense. A little care and attention to properly typing the login names will save you a bit of time and hair on the troubleshooting end of creating principals.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3756" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">User Contains Invalid Characters – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>What Agent Job is Running &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2016/12/23/what-agent-job-is-running-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-agent-job-is-running-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2016/12/23/what-agent-job-is-running-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 23 Dec 2016 07:49:47 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Restore]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3751</guid>

					<description><![CDATA[<p>It is quite common to be required to investigate performance issues on the server. With this, it is occasionally necessary to be able to interpret an obfuscated job name. Learn how to do that in this article.</p>
The post <a href="https://jasonbrimhall.info/2016/12/23/what-agent-job-is-running-back-to-basics/">What Agent Job is Running – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>I did not officially accept the challenge. Was an official acceptance required? I don&#8217;t know. I do know that I think it is a good challenge and that I intend to participate in the challenge. I hope I can meet the requirements and keep the posts to &#8220;basics&#8221;. Let&#8217;s hope this post holds up to the intent of the challenge.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Active Queries</h2>
<p>If you are like me, you have had the opportunity on more than one occasion to try and figure out what is currently active on your SQL Server. The reason to try and figure this is out is usually tied to some sort of performance issue that you have to dive in and troubleshoot.</p>
<p>When checking for current activity through sp_who2 or by querying the dmvs (sys.dm_exec_sessions, sys.dm_exec_requests, sys.dm_exec_connections), there is inevitably some sort of session that looks something like this:</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3753" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/active_job.jpg" alt="active_job" width="584" height="67" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/active_job.jpg 584w, https://jasonbrimhall.info/wp-content/uploads/2016/12/active_job-300x34.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/12/active_job-50x6.jpg 50w" sizes="(max-width: 584px) 85vw, 584px" /></p>
<p>This is not very helpful in this format. What I have seen most people do when they see this kind of result (and they care enough to know what is running) is to open up the &#8220;Job Activity Monitor&#8221; and then try to figure out manually what job is truly running. You can imagine the nightmare this becomes if there are more than a few jobs running.</p>
<h3>Currently Running Agent Jobs</h3>
<p>There is a significantly easier way to find the name and step of the agent job that is currently running when using your favorite dmv query to explore current activity. Let&#8217;s start with a simple query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT p.session_id,p.program_name
	FROM sys.dm_exec_sessions p
	WHERE p.program_name LIKE 'SQLAgent - TSQL JobStep (Job%';</pre><p>If you have jobs that are currently executing, then this query should return some results representative of the running jobs. Unfortunately, you only know that the source of the spid happens to be the SQLAgent. I am going to dirty up this simple query with quite a bit more query so it looks like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT p.session_id,p.program_name
	,j.name AS JobName, js.step_name, j.description, js.step_id
	, st.Query AS JobCommand
	, js.subsystem
	FROM sys.dm_exec_sessions p
		INNER JOIN msdb.dbo.sysjobs j
			ON j.job_id = CONVERT(UNIQUEIDENTIFIER, CONVERT(BINARY(16), SUBSTRING(p.program_name,
																CHARINDEX('(',
																p.program_name)
																+ 5,
																CHARINDEX(':',
																p.program_name)
																- CHARINDEX('(',
																p.program_name)
																- 6),1))
		INNER JOIN msdb.dbo.sysjobsteps js
			ON j.job_id = js.job_id
				CROSS APPLY (
					SELECT 
						REPLACE
						(
							REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
							REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
							REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
								CONVERT
								(
									NVARCHAR(MAX),
									N'--' + NCHAR(13) + NCHAR(10) + ist.command + NCHAR(13) + NCHAR(10) + N'--' COLLATE Latin1_General_Bin2
								),
								NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
								NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
								NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
							NCHAR(0),
							N''
						) AS [processing-instruction(query)]
						FROM msdb.dbo.sysjobsteps AS ist
							WHERE ist.job_id = j.job_id
								AND ist.step_id = SUBSTRING(p.program_name, CHARINDEX(')', p.program_name) - 2, 2)
					FOR XML
						PATH(''),
						TYPE
				) AS st(Query)
	WHERE p.program_name LIKE 'SQLAgent - TSQL JobStep (Job%'
		AND js.step_id = SUBSTRING(p.program_name, CHARINDEX(')', p.program_name) - 2, 2)
	;</pre><p>There is a good reason for how much I have complicated the simple version of the query. I can leave the query significantly less complicated if not for the fact that I wanted to also know the sql text in a well formatted manner. That accounts for the entire segment in the cross apply.</p>
<p>To retrieve the name of the job that is running, I actually only need this little piece of code right here:</p><pre class="urvanov-syntax-highlighter-plain-tag">INNER JOIN msdb.dbo.sysjobs j
			ON j.job_id = CONVERT(UNIQUEIDENTIFIER, CONVERT(BINARY(16), SUBSTRING(p.program_name,
																CHARINDEX('(',
																p.program_name)
																+ 5,
																CHARINDEX(':',
																p.program_name)
																- CHARINDEX('(',
																p.program_name)
																- 6),1))</pre><p>This takes the varbinary representation of the jobid string and converts to the human friendly form with the appropriate format of the string so we can compare it to the the actual job id and then finally get the job name. From there, I can then retrieve the job step to see exactly where in the process the job is presently executing.</p>
<p>Executing this query, I receive the following results for the job that I have executing right now.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3754" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob-1024x54.jpg" alt="decrypt_agentjob" width="560" height="30" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob-1024x54.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob-300x16.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob-768x40.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob-50x3.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/12/decrypt_agentjob.jpg 1842w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>If I take this code and then integrate it into my favorite query to check for running sessions while investigating issues on the server, I have become just that much more efficient as a DBA.</p>
<h3></h3>
<h3>Recap</h3>
<p>It is quite common to be required to investigate performance issues on the server. Even if not a performance issue, there are frequent needs that require us to know what queries are executing at various points in time throughout the day. A complication to this is the varbinary format of the job name that is represented as the program that is running during many of these spot checks.</p>
<p>The means to circumvent this complication is with a little extra code for your favorite script du jour used to investigate running sessions. I recommend adding a code segment, such as the code I have shown in this article, to help simplify your research tasks and help you look more like a rockstar. Of course, you could always resort to the other method touched on in this article &#8211; trial and guess through manual process of elimination via &#8220;Job Activity Monitor&#8221;.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3751" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/12/23/what-agent-job-is-running-back-to-basics/">What Agent Job is Running – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/12/23/what-agent-job-is-running-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Database Backups &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2016/12/21/database-backups-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-backups-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2016/12/21/database-backups-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 22 Dec 2016 03:13:01 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Restore]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3744</guid>

					<description><![CDATA[<p>In this article, we will explore database backups. More specifically, how do you truly know if you have a successful backup? Here's a hint: it has to deal with restores.</p>
The post <a href="https://jasonbrimhall.info/2016/12/21/database-backups-back-to-basics/">Database Backups – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>I did not officially accept the challenge. Was an official acceptance required? I don&#8217;t know. I do know that I think it is a good challenge and that I intend to participate in the challenge. I hope I can meet the requirements and keep the posts to &#8220;basics&#8221;. Let&#8217;s hope this post holds up to the intent of the challenge.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Database Backups</h2>
<p><img loading="lazy" class=" wp-image-3741 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup.png" alt="db_backup" width="162" height="161" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup-50x50.png 50w" sizes="(max-width: 162px) 85vw, 162px" />In my previous two articles, I touched on some data that is available to the data professional with regards to <a href="http://bit.ly/2h7Dpmr">backups </a>and database <a href="http://bit.ly/2i3GOCX">restores</a>. In the article discussing the restore history data, I alluded to another topic related to restores that could have been discussed.</p>
<p>Today, I will be diving into that alternate direction. This direction is related to database backups. More specifically, how do you truly know if you have a successful backup? Here&#8217;s a hint: it has to deal with restores.</p>
<p>If you haven&#8217;t heard it before, here it is in simple terms &#8220;you do not have a backup until you have restored the <em>backup</em>&#8220;. If you ponder that for a minute, it is quite logical and makes plenty of sense. The only way to confirm that you have a backup is to test the purpose of the backup and that is to recover the database back to the state represented by the backup.</p>
<h3>Testing Backups</h3>
<p>Creating a database backup is a pretty straight-forward task. This is easy enough to do through the GUI or from tsql script, or <img loading="lazy" class="wp-image-3736 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore.png" alt="db_restore" width="144" height="144" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore-50x50.png 50w" sizes="(max-width: 144px) 85vw, 144px" />even, *<strong><em>shudder</em></strong>*, from a maintenance plan. Creating the backup is the easy part. If you are not creating backups, I hope there is a good reason for it (and yes there are valid reasons for not creating a backup of certain databases).</p>
<p>This article will not explore the nuances of the ways to <a href="https://technet.microsoft.com/en-us/library/ms186865(v=sql.110).aspx">create a backup of a database</a>. Suffice it to say, there are multiple options and methods. This article will focus on the second part of creating a successful backup &#8211; testing the backup. In other words, restoring the backup that was created.</p>
<p>So how does one go about testing a backup? The simple answer as already stated is to perform a restore. This means through the use of the <a href="https://technet.microsoft.com/en-us/library/ms190372(v=sql.110).aspx">restore command</a>. But is it really that simple?</p>
<p>If I have the following backups available for my AdventureWorks2014 database, where should I test the validity of the backup?</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3746" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/avail_backups-1024x60.png" alt="avail_backups" width="560" height="33" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/avail_backups-1024x60.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/12/avail_backups-300x18.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/12/avail_backups-768x45.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/12/avail_backups-50x3.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Would it make much sense to take any of these backups and test the restore process on the same server as the source of the backup? To be honest, that is a question that may have an entirely different answer in each and every environment. That is a question that requires a little insight into the business needs, available resources and procedures and policies in place for the environment. For me, I typically like to create an automated restore process that will restore the previous night&#8217;s backup onto a test/stage/dev server that is not in production.</p>
<p>I have written previously on how I do this sort of automated restore. You can read all about it from the original article <a href="http://bit.ly/1eClb0k">here</a>. In that article I provide a script to assist with the restore of these backups. You are welcome to test it out and play around with it while setting up your backup validation environment. In using the script, the user assumes all risk.</p>
<p>I recommend an automated restore system to ensure the backups are tested on a routine basis. The benefits of doing this are more than just a few. That said here are a few of those benefits: 1. Confidence in backups, 2. Quick recovery in event of failure or disaster, 3. A usable environment for quick data comparison, 4. A passable environment for reporting, and the best benefit is that you can get a good nights sleep knowing your backups are reliable.</p>
<h3>Caveat</h3>
<p>With automated restores, there may be an occasional failure. Heck, you may run into a bit of a head-scratcher here or there trying to get them to work in the first place. It&#8217;s not technically easy the first time. With some practice, it gets much easier. This method is intended to be suitable for a cheap solution. There may be a pricier solution out there that can be bought. If that is in your budget &#8211; go with it. The main point is to do it.</p>
<p>After you get these restores working, I recommend using the scripts in <a href="http://bit.ly/2i3GOCX">this article</a> to check the restore history from time to time. Take it an extra mile and generate some reports from that data.</p>
<h3>Recap</h3>
<p>I have provided some information on how and why to restore a database. The primary reason being that you never know how good your backup is until you have restored it. Some say you do not have a backup until you have restored it. This is a solution and some opinions on how to do that efficiently.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3744" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/12/21/database-backups-back-to-basics/">Database Backups – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/12/21/database-backups-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Database Backup History &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-backup-history-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Dec 2016 13:24:27 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3740</guid>

					<description><![CDATA[<p>In this article I explore the basic of querying backup history data as a foundation to reporting on essentials such as storage and job management.</p>
The post <a href="https://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/">Database Backup History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>I did not officially accept the challenge. Was an official acceptance required? I don&#8217;t know. I do know that I think it is a good challenge and that I intend to participate in the challenge. I hope I can meet the requirements and keep the posts to &#8220;basics&#8221;. Let&#8217;s hope this post holds up to the intent of the challenge.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Database Backup History</h2>
<p><img loading="lazy" class=" wp-image-3741 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup.png" alt="db_backup" width="134" height="134" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_backup-50x50.png 50w" sizes="(max-width: 134px) 85vw, 134px" />As a data professional, there is little to no doubt that one of the most important tasks is to ensure the data is backed up regularly. We do this in preparation for several reasons. Whether it be to be able to recover in the event of a problem or to compare yesterdays data to how it looks today, the backup is done.</p>
<p>When doing a backup, how often do you report on the backup success? How frequently do you refer to the backup history to compare multiple runs or even generate reports for interested parties? The fact of the matter is that this history should be referenced on a routine basis to generate reports that should be read and not ignored.</p>
<h3>Backup Reporting</h3>
<p>Right about here you may be asking yourself why would somebody generate reports on the backups. After all, the job succeeds or fails and you respond appropriately to that, right? Does one really need to generate a report about the success of the backup job? Well, that is for you to decide. I would say it wouldn&#8217;t hurt to generate a report about the success rate of your backups. Management often likes to see reports concerning important processes. That said, that is not the reporting that I am referencing here.</p>
<p>The reporting I believe is useful in this case is indeed related to the historical information of your backups, but it is less about the success of the job and so forth. Of great benefit from the backup history data is the information on frequency of backup and also the size of the backup. These pieces of information can be somewhat useful when looking to forecast data growth. That is one example of a possible report when working with the backup history data that is stored.</p>
<p>Let&#8217;s take a look at a query that will help retrieve some of this backup history data.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SQLVer SQL_VARIANT
	, @DBName VARCHAR(128)
	, @NumDays SMALLINT
	, @SQL VARCHAR(1024)
	, @WhereClause VARCHAR(256);
 
SET @DBName = NULL;
SET @NumDays = 10000;
SET @SQLVer = CONVERT(INTEGER, PARSENAME(CONVERT(VARCHAR(20), SERVERPROPERTY('ProductVersion')),
											4));

SET @WhereClause = 'WHERE a.type IN (''D'',''I'')
		AND a.backup_start_date &gt; GETDATE()- ' + CAST(@NumDays AS VARCHAR) + '';
IF @DBName IS NOT NULL
	BEGIN
		SET @WhereClause = @WhereClause + '
		AND a.database_name = ''' + @DBName + '''';
	END;

SET @SQL = '
SELECT a.database_name,a.backup_start_date,a.backup_finish_date
		,datediff(second,a.backup_start_date,a.backup_finish_date)/60.0 as DurationMinute
		,b.physical_device_name AS BackupPath
		,a.position
		,a.type
		,a.backup_size/1024/1024 AS BackupSizeMB
		,' + CASE	WHEN @SQLVer &lt; 10 THEN '0'
					ELSE 'a.compressed_backup_size/1024/1024'
				END + ' AS CompressedBackMB
	FROM msdb.dbo.backupset a
		INNER JOIN msdb.dbo.backupmediafamily b
			ON a.media_set_id = b.media_set_id
	' + @WhereClause + '
	ORDER BY a.database_name,a.backup_start_date;';

--PRINT @SQL
EXECUTE (@SQL);</pre><p>Off the top, yes the script uses dynamic sql. I use dynamic sql because I use this script on multiple versions of SQL Server. One of the data points I gather in this script is the compressed backup size. That attribute is not available in SQL 2005. Due to that, and not wanting to maintain multiple scripts, I use the dynamic sql to account for that missing column.</p>
<p>I have also set the script to accept a database name parameter. If a name is provided, then only the backup history for that database is returned. If the parameter is left NULL, then the backup history for all databases will be returned. Additionally, I added a number of days parameter to limit the scope of the report to a specific range of days.</p>
<p>Among the data points returned in this script, you will note there is the duration of the backup, the date, and even the size of the backup. All of these attributes can help me to forecast future storage requirements both for the backup storage as well as for the data volume. Additionally, by knowing the duration of the backup and the trend of that duration, I can adjust maintenance schedules accordingly.</p>
<h3>Caveat</h3>
<p>In this particular script, I only retrieve the backup history for two backup types: FULL and DIFFERENTIAL. A small adjustment can be made to include other backup types if necessary. The line to change is:</p><pre class="urvanov-syntax-highlighter-plain-tag">SET @WhereClause = 'WHERE a.type IN (''D'',''I'')</pre><p>Other possible values for backups are:</p>
<ul style="list-style-type: circle;">
<li>D = Database</li>
<li>I = Differential database</li>
<li>L = Log</li>
<li>F = File or filegroup</li>
<li>G =Differential file</li>
<li>P = Partial</li>
<li>Q = Differential partial</li>
</ul>
<p>If you are interested in learning more about backup information, you can read this msdn article &#8211; <a href="https://technet.microsoft.com/en-us/library/ms186299(v=sql.110).aspx">here</a>.</p>
<h3>Recap</h3>
<p>I have provided a quick example of how to retrieve pertinent backup history information. This information can be used to assist in forecasting storage requirements as well as assist in the job scheduling as backup jobs begin to run longer and longer as the data gets larger and larger.</p>
<p>For a related article, <a href="http://bit.ly/2i3GOCX">check out this article on how to retrieve the restore history</a> from the msdb database.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3740" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/">Database Backup History – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/12/20/database-backup-history-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Last Restore of a Database &#8211; Back to Basics</title>
		<link>https://jasonbrimhall.info/2016/12/19/last-restore-of-a-database-back-to-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=last-restore-of-a-database-back-to-basics</link>
					<comments>https://jasonbrimhall.info/2016/12/19/last-restore-of-a-database-back-to-basics/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Dec 2016 04:58:33 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Restore]]></category>
		<category><![CDATA[Restore]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3734</guid>

					<description><![CDATA[<p>In this article I explore the basics around how to determine when a database was last restored.</p>
The post <a href="https://jasonbrimhall.info/2016/12/19/last-restore-of-a-database-back-to-basics/">Last Restore of a Database – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Remember When&#8230;</h2>
<p><img loading="lazy" class="wp-image-3547 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="163" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 163px) 85vw, 163px" />Back in late December of 2015, a challenge of sorts was issued by Tim Ford (<a href="http://twitter.com/sqlagentman">twitter</a>) to write a blog post each month on a SQL Server Basic. Some have hash-tagged this as #backtobasics. Here is the <a href="https://twitter.com/sqlagentman/status/681292115947589633">link to that challenge sent via tweet</a>.</p>
<p>I did not officially accept the challenge. Was an official acceptance required? I don&#8217;t know. I do know that I think it is a good challenge and that I intend to participate in the challenge. I hope I can meet the requirements and keep the posts to &#8220;basics&#8221;. Let&#8217;s hope this post holds up to the intent of the challenge.</p>
<p>With this being another installment in a monthly series, here is a link to review the other posts in the series &#8211; <a href="http://bit.ly/SQLBack2Basics">back to basics</a>. Reviewing that link, you can probably tell I am a bit behind in the monthly series.</p>
<h2>Database Restore</h2>
<p><img loading="lazy" class="wp-image-3736 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore.png" alt="db_restore" width="119" height="119" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restore-50x50.png 50w" sizes="(max-width: 119px) 85vw, 119px" />As a data professional, one should be somewhat cognitive of backups with regards to the data. From the point of the creation of the backup, we can go in one of two directions with this article. Due to the importance of each of the directions, I will devote a basics article to each.</p>
<p>The order of publication of these articles in no means denotes a level of priority to the topic. I feel each is equally important. The two directions I see both deal with the restore of that backup that was created. One direction is in regards to reporting and the other direction is the actual restore.</p>
<h3>Last Restore Date</h3>
<p>Something that I seem to be getting asked more and more frequently is how to determine when a database was last restored. Maybe it is just a hot topic and maybe it will be short lived, but it sure seems to be something that is on the tip of peoples minds of late. So, how does one determine the last time a database was restored? The answer is actually quite simple. Within the msdb database, there is a table (that maintains the history of database restores) called restorehistory.</p>
<p>The restorehistory table stores information that will help you better understand what kind of restore was performed, who did the restore, when it was done, and even some information about the backup that was used to perform the restore. You can read more about the specifics of this table from the msdn article &#8211; <a href="https://msdn.microsoft.com/en-us/library/ms187408.aspx">here</a>.</p>
<p>A quick means to query this table is via the following script:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT r.restore_date
		, r.destination_database_name
		, CASE r.restore_type
			WHEN 'D' THEN 'Database'
			WHEN 'F' THEN 'File'
			WHEN 'G' THEN 'FileGroup'
			WHEN 'I' THEN 'Differential'
			WHEN 'L' THEN 'Log'
			WHEN 'V' THEN 'VerifyOnly'
			END AS restore_type
		, r.replace
		, r.recovery
		, r.user_name
	FROM msdb.dbo.[restorehistory] r
	WHERE r.destination_database_name = 'TestDB'
	ORDER BY r.destination_database_name,r.restore_date DESC;</pre><p>Now, that is an extremely simple query looking at my TestDB database. The results of that query on my system are as follows:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3738" src="http://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example-1024x173.jpg" alt="db_restores_example" width="560" height="95" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example-1024x173.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example-300x51.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example-768x130.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example-50x8.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/12/db_restores_example.jpg 1603w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>As is shown in the preceding illustration, I have multiple restores and restore types of this particular database. This is a good start. Let&#8217;s take this query up a notch. Not all production environments will have databases that are restored on the same server. What do we do to report on databases that are restored on the production server vs. the databases that exist on the production server? That is where this next query comes in to play.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @DBName VARCHAR(128) = 'AdventureWorks2014' --NULL
	, @MostRecentRestore TINYINT = 1 --NULL --1
	, @RestoredDBsOnly TINYINT = NULL; --1

SELECT DatabaseName = [d].[name]
		, [d].[create_date]
		, [d].[compatibility_level]
		, [d].[collation_name]
		, r.restore_date
		, r.user_name AS RestoredBy
		, r.destination_database_name
		, r.restore_type
		, r.replace
		, r.recovery
		--, r.RowNum
	FROM master.sys.databases d
		LEFT OUTER JOIN ( SELECT r.restore_date
									, r.destination_database_name
									, CASE r.restore_type
										WHEN 'D' THEN 'Database'
										WHEN 'F' THEN 'File'
										WHEN 'G' THEN 'FileGroup'
										WHEN 'I' THEN 'Differential'
										WHEN 'L' THEN 'Log'
										WHEN 'V' THEN 'VerifyOnly'
										END AS restore_type
									, r.replace
									, r.recovery
									, r.user_name
									, RowNum = ROW_NUMBER() OVER ( PARTITION BY r.[destination_database_name] ORDER BY r.restore_date DESC )
								FROM msdb.dbo.[restorehistory] r
						) r
			ON d.name = r.[destination_database_name]
				AND r.RowNum = ISNULL(@MostRecentRestore, r.RowNum)
	WHERE 1 = 1
		AND ISNULL(r.RowNum, -1) = COALESCE(@RestoredDBsOnly, r.RowNum, -1)
		AND d.name = ISNULL(@DBName, d.name);</pre><p>In this latter query, I have added a few things to help for various reporting needs. You never know when the CIO or an auditor is going to come to you with a request to filter the data differently for restored databases. In this vein, I added parameters that will help filter the results down to a specific database, return all databases, or return all databases that have a restore history on the server. In this case, I decided to use the AdventureWorks2014 database as my example database. You will want to change the parameter as needed. If you pass a null value to the database name, then all databases can be returned in the result set &#8211; depending on the values used for the remaining parameters.</p>
<h3>Caveat</h3>
<p>This is all fine and well if the databases are restored onto the same server as the source database, right? What about the case where the database is restored to a different server? Well, the query still works for reporting the restored databases on the server where the database is restored. The complexity comes when trying to correlate back to the original production server. My recommendation here is good documentation and an administrative linked server that is not accessible via the application accounts or any user but the DBA group.</p>
<h3>Recap</h3>
<p>I have provided two quick examples of how to retrieve the restore history for your databases. I recommend that the restore history be checked on a routine basis. You never know when an over-permissioned user may decide to restore a database for you and then have all of the rest of the users coming to you to determine what happened. This will also be essential when we routinely test our database backups. Stay tuned for the next article where I will explore that aspect of database restores.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3734" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/12/19/last-restore-of-a-database-back-to-basics/">Last Restore of a Database – Back to Basics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/12/19/last-restore-of-a-database-back-to-basics/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Finding Deprecated Uses in SQL Server</title>
		<link>https://jasonbrimhall.info/2016/11/07/finding-deprecated-uses-in-sql-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=finding-deprecated-uses-in-sql-server</link>
					<comments>https://jasonbrimhall.info/2016/11/07/finding-deprecated-uses-in-sql-server/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 07 Nov 2016 20:47:16 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3719</guid>

					<description><![CDATA[<p>Do you know that your Server logs 300 million deprecation events a week? Do you know if code needs to be updated or how to find deprecated uses in SQL Server?</p>
The post <a href="https://jasonbrimhall.info/2016/11/07/finding-deprecated-uses-in-sql-server/">Finding Deprecated Uses in SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p><img loading="lazy" class="alignright wp-image-3547" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png" alt="sqlbasic_sarge" width="136" height="192" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge.png 549w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-213x300.png 213w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlbasic_sarge-35x50.png 35w" sizes="(max-width: 136px) 85vw, 136px" /></p>
<p>How well do you know your environment? You probably know all of the jobs that are running, the frequency that indexes need to be rebuilt, and even which users have which level of access to each object in the SQL Server instance. Do you know that your applications are accessing deprecated datatypes over 300 million times a week? What if your TSQL constructs are a bit archaic? Do you know that the code needs to be updated? Do you know how to find deprecated uses in SQL Server?</p>
<p>In this article, I will explore how to use Extended Events to track feature use and abuse. To be more precise, I will share how this tool can help you better understand all of the ways that your applications have been abusing your database by continuing to employ the use of deprecated features, syntax, or constructs in general. In case you are a bit behind in your exploration of XEvents, I have the perfect solution for you &#8211; my series on the topic that is continually growing. You can explore the full list of articles in the series by visiting the <a href="http://bit.ly/XE60Days">table of contents &#8211; here</a>.</p>
<h3>Audit Deprecated Uses</h3>
<p><img loading="lazy" class="wp-image-3721 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/11/redX.png" alt="redx" width="137" height="137" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/11/redX.png 250w, https://jasonbrimhall.info/wp-content/uploads/2016/11/redX-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/11/redX-50x50.png 50w" sizes="(max-width: 137px) 85vw, 137px" />I would dare say that most data professionals think there is some use of deprecated constructs, datatypes or features within their environment. I would double down on that and say that most do not know just how bad it really may be. To find just how bad it really is, we need to audit for the use and abuse of these deprecation events.</p>
<p>Right here would be a good time to point out that your mileage may vary. Some items that are deprecated are more painful than others. Some may be deprecated and may have been on the list for 10+ years at this point. The point is, know your environment and then use good judgement to determine which items in your results need the most attention to fix and update. Why? Well, things really may break especially if you are looking to upgrade to a new version of SQL Server. Just because an item is still available in your current edition, that does not ensure it will still be available in a future release of SQL Server.</p>
<p>Now for the juicy stuff. As I mentioned, finding when and where a deprecated feature or syntax is employed, there are a couple of neat little events within Extended Events that can help to track each time a deprecated feature is accessed or employed. How do we do that? Use the deprecation_announcement and deprecation_final_support events. To help create sessions to track these events, I have the following script to create an &#8220;audit&#8221; session to do exactly that.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AuditDeprecated' )
	DROP EVENT SESSION AuditDeprecated
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO


CREATE EVENT SESSION [AuditDeprecated] ON SERVER
ADD EVENT sqlserver.deprecation_announcement (
	ACTION ( sqlserver.database_id, sqlserver.database_name,
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname,
	sqlserver.context_info, sqlserver.client_connection_id )
	WHERE  [sqlserver].[database_name] = N'AdventureWorks2014' 
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
			AND [sqlserver].[client_app_name] NOT LIKE 'Red Gate Software Ltd SQL Prompt%'
		),
ADD EVENT sqlserver.deprecation_final_support (
	ACTION ( sqlserver.database_id, sqlserver.database_name,
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname,
	sqlserver.context_info, sqlserver.client_connection_id )
	WHERE  [sqlserver].[database_name] = N'AdventureWorks2014' 
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
			AND [sqlserver].[client_app_name] NOT LIKE 'Red Gate Software Ltd SQL Prompt%'
		)
ADD TARGET package0.event_file (  SET filename = N'C:\Database\XE\AuditDeprecated.xel'
									, max_rollover_files = ( 25 ) )
WITH (  MAX_MEMORY = 4096 KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 30 SECONDS
		, MAX_EVENT_SIZE = 0 KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO

ALTER EVENT SESSION AuditDeprecated ON SERVER
STATE = START;</pre><p>&nbsp;</p>
<p>And just in case you are using 2008 or 2008R2, use this version instead.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* 2008r2 and older */
USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AuditDeprecated' )
	DROP EVENT SESSION AuditDeprecated
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO


CREATE EVENT SESSION [AuditDeprecated] ON SERVER
ADD EVENT sqlserver.deprecation_announcement (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
	WHERE  [sqlserver].[database_id] &gt; 4 --exclude system databases
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
		),
ADD EVENT sqlserver.deprecation_final_support (
	ACTION ( sqlserver.database_id, 
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname)
	WHERE  [sqlserver].[database_id] &gt; 4
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
		)
ADD TARGET package0.asynchronous_file_target (  SET filename = N'C:\Database\XE\AuditDeprecated.xel'
									, max_rollover_files = ( 25 ) )
WITH (  MAX_MEMORY = 4096 KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 30 SECONDS
		, MAX_EVENT_SIZE = 0 KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO

ALTER EVENT SESSION AuditDeprecated ON SERVER
STATE = START;</pre><p>Slight differences between these two sessions. First, in the 2008 version of the script, I <img loading="lazy" class="alignright wp-image-3720" src="http://jasonbrimhall.info/wp-content/uploads/2016/11/rotten_orange.png" alt="rotten_orange" width="264" height="176" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/11/rotten_orange.png 600w, https://jasonbrimhall.info/wp-content/uploads/2016/11/rotten_orange-300x200.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/11/rotten_orange-50x33.png 50w" sizes="(max-width: 264px) 85vw, 264px" />have to provide database ids instead of names. That is a shortcoming of 2008 and 2008R2 implementations of Extended Events. Additionally, the file target is different between the two (recall that they renamed the file target). And lastly, there are a few actions that I included in the 2012 version of the script that are not available in 2008 and R2.</p>
<p>With the session in place, I am now going to run through some sample scripts that will generate deprecation events to occur. I am sticking with my 2014 instance for this segment. That is important to note because different events may occur for different versions of SQL Server. Additionally, the parse script I will share will require a slight change for 2008 and r2 (again related to the file target name).</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdventureWorks2014;
GO
--String alias
SELECT 'FullName' = FirstName + ' ' + MiddleName + '. ' + LastName
	FROM Person.Person
GO

--# table name
CREATE TABLE # ( c1 INT )
GO

--3 part column name
SELECT TOP 1 AdventureWorks2014.Person.Person.LastName
		, *
	FROM Person.Person

SELECT TOP 1 Person.Person.LastName
		, *
	FROM Person.Person
GO

--use :: for function calls
SELECT *
	FROM :: fn_virtualfilestats(2, 1)
GO

--using hints without WITH keyword
SELECT TOP 1 Person.LastName
		, *
	FROM Person.Person (TABLOCK)
GO

--use fn_get_sql
DECLARE @Handle VARBINARY(64);
SELECT @Handle = sql_handle
	FROM sys.dm_exec_requests
	WHERE session_id = @@SPID
		AND request_id = 0;
SELECT *
	FROM sys.fn_get_sql(@Handle);
GO

--remote servers
SELECT @@REMSERVER

--vardecimal
exec sp_db_vardecimal_storage_format 'Adventureworks2014', 'ON'
sp_tableoption 'Person.Person', 'vardecimal storage format', 1</pre><p>Now to take a peek at the data with this next script.</p><pre class="urvanov-syntax-highlighter-plain-tag">IF EXISTS (SELECT OBJECT_ID('tempdb.dbo.#xmlprocess'))
BEGIN
DROP TABLE #xmlprocess
END

SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.event_session_id--, ' AS event_predicate
	INTO #xmlprocess
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, ses.event_session_id
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					--INNER JOIN sys.server_event_session_events sese
					--	ON ses.event_session_id = sese.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'AuditDeprecated'
					) cte1
				OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;


SELECT x.event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, x.event_data.value('(event/@package)[1]', 'varchar(50)') AS package_name
		, DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP),
					x.event_data.value('(event/@timestamp)[1]',
										'datetime2')) AS [timestamp]
		,event_data.value('(event/data[@name="feature_id"]/value)[1]','bigint') AS feature_id
		,event_data.value('(event/data[@name="feature"]/value)[1]','varchar(max)') AS feature
		,event_data.value('(event/data[@name="message"]/value)[1]','varchar(max)') AS message
		,event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'varchar(max)') AS client_app_name
		,event_data.value('(event/action[@name="client_connection_id"]/value)[1]', 'uniqueidentifier') AS client_connection_id
		,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'varchar(max)') AS client_hostname
		,event_data.value('(event/action[@name="context_info"]/value)[1]', 'varbinary(max)') AS context_info
		,event_data.value('(event/action[@name="database_id"]/value)[1]', 'int') AS database_id
		,event_data.value('(event/action[@name="database_name"]/value)[1]', 'varchar(max)') AS database_name
		,event_data.value('(event/action[@name="nt_username"]/value)[1]', 'varchar(max)') AS nt_username
		,event_data.value('(event/action[@name="session_id"]/value)[1]', 'int') AS session_id
		,event_data.value('(event/action[@name="session_nt_username"]/value)[1]', 'varchar(max)') AS session_nt_username
		,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
		,event_data.value('(event/action[@name="username"]/value)[1]', 'varchar(max)') AS username
	FROM #xmlprocess x
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON x.event_data.value('(event/@name)[1]', 'varchar(50)') = sese.name
				AND x.event_session_id = sese.event_session_id
	ORDER BY timestamp
		, event_data.value('(event/action[@name="event_sequence"]/value)[1]',
							'varchar(max)');</pre><p>Now at long last, I can see what kind of data I am generating (they are really wide so I am just posting a snip).</p>
<p><img loading="lazy" class="alignright size-large wp-image-3722" src="http://jasonbrimhall.info/wp-content/uploads/2016/11/deprecated_features_results-1024x155.jpg" alt="deprecated_features_results" width="560" height="85" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/11/deprecated_features_results-1024x155.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/11/deprecated_features_results-300x45.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/11/deprecated_features_results-768x116.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/11/deprecated_features_results-50x8.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>With this, I can see the feature_id along with the description and even the tsql that generated the event. What you don&#8217;t see in this is that I also trap the source machine and the user name. If there is an application name included in the connection string, I also trap that. These pieces of data can prove critical to efficiently troubleshooting and finding the source of these events.</p>
<p>From here, one might wish to explore all of the events generated from this session in order to ensure the environment is properly prepared for upgrade. Most tools do not evaluate the code thoroughly to trap all of these events. Instead they do a cursory look through stored procedures or at the data types. As we all should know, not every piece of SQL code is actually stored in the database or even is it cached at the time of analysis. This is the type of thing that requires a long running trace to prove that you are that rockstar DBA.</p>
<h3>Conclusion</h3>
<p>In the article today, I have shown how it is possible to see the deprecation alerts that may be generated in your environment. This data is what can help set you apart as a rockstar when it comes time for that migration. If you have yet to read my series on Extended Events, I highly recommend it. You can find that series <a href="http://bit.ly/XE60Days">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3719" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/11/07/finding-deprecated-uses-in-sql-server/">Finding Deprecated Uses in SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/11/07/finding-deprecated-uses-in-sql-server/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Database Dropped</title>
		<link>https://jasonbrimhall.info/2016/09/09/database-dropped/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-dropped</link>
					<comments>https://jasonbrimhall.info/2016/09/09/database-dropped/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 09 Sep 2016 20:59:37 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[trace]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3705</guid>

					<description><![CDATA[<p>What do you do when a developer comes to you and asks, "Where did the database go?  The database was there one minute, and the next it was not."</p>
The post <a href="https://jasonbrimhall.info/2016/09/09/database-dropped/">Database Dropped</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>What do you do when a developer comes to you and asks, &#8220;Where did the database go?  The database was there one minute, and the next it was not.&#8221;  Only one thing could be <img loading="lazy" class="alignright wp-image-3706" src="http://jasonbrimhall.info/wp-content/uploads/2016/09/falling_rock_onDB.png" alt="database dropped" width="190" height="190" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/09/falling_rock_onDB.png 384w, https://jasonbrimhall.info/wp-content/uploads/2016/09/falling_rock_onDB-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/09/falling_rock_onDB-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/09/falling_rock_onDB-50x50.png 50w" sizes="(max-width: 190px) 85vw, 190px" />worse than the feeling of losing a database on your watch, and that would be losing a production database. It&#8217;s like magic—it&#8217;s there, and then it disappears. To compound the issue, when asking people if they know what might have happened, all will typically deny, deny, deny.</p>
<p>What do you do when you run into that missing database situation and the inevitable denial that will ensue?  This is when an audit can save the day.  Through an audit, you can discover who dropped the database and when it happened.  Then you have hard data to take back to the team to again ask what happened.  Taking the info from a <a title="Audit Schema Change" href="http://bit.ly/1wtDgeY">previous article of mine</a>, we can alter the script I published there and re-use it for our needs here.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @DBName sysname = 'AdventureWorks2014'
		,@d1 DATETIME
		,@diff INT;

SELECT ObjectName
		  , ObjectID
		  , DatabaseName
		  , StartTime
		  , EventClass
		  , EventSubClass
		  , ObjectType
		  , ServerName
		  , LoginName
		  , NTUserName
		  , ApplicationName
		  , CASE EventClass
				WHEN 46
					THEN 'CREATE'
				WHEN 47
					THEN 'DROP'
				--WHEN 164
				--	THEN 'ALTER'
			END AS DDLOperation
		INTO #temp_trace  
	FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
			( SELECT REVERSE(SUBSTRING(REVERSE(path),
					CHARINDEX('\',REVERSE(path)),256)) + 'log.trc'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) T  
  WHERE EventClass in (46,47) 
			AND EventSubclass = 0
			AND ObjectType = 16964-- i just want database related events   
			AND DatabaseName = ISNULL(@DBName,DatabaseName);


SELECT @d1 = MIN(StartTime) 
	FROM #temp_trace;

SET @diff= DATEDIFF(hh,@d1,GETDATE());


SELECT @diff AS HrsSinceFirstChange    
		, @d1 AS FirstChangeDate    
		, sv.name AS obj_type_desc
		, tt.ObjectType
		, tt.DDLOperation
		, tt.DatabaseName,tt.ObjectName,tt.StartTime
		, tt.EventClass,tt.EventSubClass
		, tt.ServerName,tt.LoginName, tt.NTUserName
		, tt.ApplicationName
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType ) )%2 AS l1     
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType,StartTime ))%2 AS l2    
	FROM #temp_trace tt
		INNER JOIN sys.trace_events AS te 
			ON tt.EventClass = te.trace_event_id
		INNER JOIN sys.trace_subclass_values tsv
			ON tt.EventClass = tsv.trace_event_id
			AND tt.ObjectType = tsv.subclass_value
		INNER JOIN master.dbo.spt_values sv 
			ON tsv.subclass_value = sv.number
			AND sv.type = 'EOD'
	ORDER BY StartTime DESC;

DROP TABLE #temp_trace;</pre><p>This script will now query the default trace to determine when a database was dropped or created.  I am limiting this result set through the use of this filter: ObjectType = 16964.  In addition to that, I have also trimmed the result-set down to just look for drop or create events.</p>
<p>This is the type of information that is already available within the default trace.  What if you wished to not be entirely dependent on the default trace for that information?  As luck would have it, you don&#8217;t need to be solely dependent on the default trace.  Instead you can use the robust tool called extended events.  If you would like to be able to take advantage of Extended Events to track this information, I recommend you read my <a title="Missing DB XE" href="http://bit.ly/XEMissingDB">follow-up article here</a>.</p>
<p>This has been a republication of my original content first posted <a href="http://bit.ly/SSGMissingDB">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3705" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/09/09/database-dropped/">Database Dropped</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/09/09/database-dropped/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Events By Feature</title>
		<link>https://jasonbrimhall.info/2016/08/30/events-by-feature/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=events-by-feature</link>
					<comments>https://jasonbrimhall.info/2016/08/30/events-by-feature/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 30 Aug 2016 12:16:56 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3689</guid>

					<description><![CDATA[<p>Within the world of SQL Server there are a few things one can be certain of - things will change. This is true of the features in SQL Server. Additionally, Extended Events is constantly evolving which underscores this constant change.</p>
The post <a href="https://jasonbrimhall.info/2016/08/30/events-by-feature/">Events By Feature</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class=" wp-image-3690 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/sql_features_xe.png" alt="sql_features_xe" width="176" height="235" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/sql_features_xe.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/sql_features_xe-225x300.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/08/sql_features_xe-38x50.png 38w" sizes="(max-width: 176px) 85vw, 176px" />Within the world of SQL Server there are a few things one can be certain of &#8211; things will change. This is true of the features in SQL Server. Additionally, Extended Events is constantly evolving which underscores this constant change.</p>
<p>With all of this change occurring within SQL Server, sometimes it is difficult to figure out how to troubleshoot or track issues that relate to new features. Within the need to figure out how to troubleshoot the new features, there is the need to understand what tools are out there to help troubleshoot.</p>
<p>It is no big secret that Profiler cannot help you trace any of the new features. To help perform the task of tracing events related to new features one must take advantage of the power of Extended Events. Even knowing that you can use XEvents, there is still a need to know what is related to the feature.</p>
<p>In this article, I will show how you can discover the events related to specific features. In addition, I will provide enough base information to help you perform other discovery type queries on your own as you continue your exploration of XEvents. In case you are a bit behind in your exploration of XEvents, I have the perfect solution for you &#8211; my series on the topic that is continually growing. You can explore the full list of articles in the series by visiting the <a href="http://bit.ly/XE60Days">table of contents &#8211; here</a>.</p>
<h3>Events and Features</h3>
<p>More and more I am being asked how to track which events belong to which features. I have also been seeing more people ask for a way to list the new features supported by XEvents. Thankfully there is adequate information within the XEvent metadata to help retrieve this type of information. The downside is that there is a bit of homework that must be done across a few versions of SQL Server to help produce the desired information. I have done that work and pulled the information into the following query to help make it easier for anybody else wishing to dive in and compare features and events across versions of SQL Server.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ServerMajorVersion DECIMAL(4, 2)
SELECT @ServerMajorVersion = CONVERT(DECIMAL(4, 2), PARSENAME(dt.fqn, 4) + '.'
		+ PARSENAME(dt.fqn, 3))
	FROM ( SELECT CONVERT(VARCHAR(20), SERVERPROPERTY('ProductVersion'))
			) dt ( fqn );

IF OBJECT_ID('tempdb.dbo.#XEVersions') IS NOT NULL
BEGIN
	DROP TABLE #XEVersions;
END

CREATE TABLE #XEVersions
	(VersionID INT IDENTITY(1,1)
		, Product VARCHAR(32)
		, ServerMajorVersion DECIMAL(4, 2) --INDEX CI_ServerMajorVer CLUSTERED
	);
CREATE CLUSTERED INDEX CI_ServerMajorVer ON	#XEVersions (VersionID);

INSERT INTO	#XEVersions
		( Product
			, ServerMajorVersion
		)
	VALUES
		( 'SQL Server 2008', 10.00)
		,( 'SQL Server 2008R2', 10.50)
		,( 'SQL Server 2012', 11.00)
		,( 'SQL Server 2014', 12.00)
		,( 'SQL Server 2016', 13.00);


IF OBJECT_ID('tempdb.dbo.#XECounts') IS NOT NULL
BEGIN
	DROP TABLE #XECounts;
END

CREATE TABLE #XECounts
	(
		[Feature] [NVARCHAR](3072) NOT NULL
		, [FeatureEventCount] [INT] NULL
		, [SQLVersion] [DECIMAL](4, 2) NULL
	);

INSERT INTO #XECounts
		( [Feature], [FeatureEventCount], [SQLVersion] )
	VALUES	( N'_UnAssigned', 27, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'access_methods', 23, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'alwayson', 100, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'broker', 42, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'cdc_logscan', 2, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'change_tracking', 2, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'checkpoint', 17, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'ckpt_trace', 37, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'ckptworker_trace', 21, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'clr', 3, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'cursor', 18, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'database', 42, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'deadlock_monitor', 7, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'deploy', 14, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'errors', 20, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'exception', 4, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'execution', 115, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'filetable', 13, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'fulltext', 8, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'garbage_collection', 1, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'gc', 4, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'hadr', 1, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'index', 9, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'init', 1, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'io', 33, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'latch', 6, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'lock', 15, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'memory', 35, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'merge_trace', 23, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'oledb', 5, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'optimization', 2, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'process', 12, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'query_store', 31, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'replication', 8, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'scheduling', 26, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'security', 3, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'server', 19, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'session', 17, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'storage_management', 13, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'synchronization', 2, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'task', 2, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'transaction', 10, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'transactions', 48, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'transmitter', 9, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'transport', 9, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'ucs', 8, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'warnings', 7, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'xtp', 15, CAST(12.00 AS DECIMAL(4, 2)) )
		, ( N'_UnAssigned', 9, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'access_methods', 6, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'broker', 73, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'cdc_logscan', 2, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'change_tracking', 1, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'clr', 2, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'cursor', 11, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'database', 21, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'deadlock_monitor', 6, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'errors', 5, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'exception', 3, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'execution', 14, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'io', 20, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'latch', 5, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'lock', 6, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'memory', 12, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'process', 12, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'replication', 7, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'scheduling', 21, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'server', 21, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'synchronization', 1, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'transactions', 6, CAST(10.50 AS DECIMAL(4, 2)) )
		, ( N'_UnAssigned', 83, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'access_methods', 19, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'alwayson', 117, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'appdomain', 5, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'backup_restore', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'broker', 42, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'cdc_logscan', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'change_tracking', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'checkpoint', 19, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'ckpt_close', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'ckpt_controller', 9, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'ckpt_trace', 40, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'ckptworker_trace', 21, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'clr', 3, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'columnstore', 41, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'cursor', 18, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'data_masking', 3, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'database', 48, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'dbseed', 14, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'deadlock_monitor', 7, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'deploy', 17, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'errors', 24, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'exception', 6, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'execution', 119, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'extensibility_errors', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'filetable', 13, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'fulltext', 8, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'garbage_collection', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'gc', 4, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'hadr', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'index', 9, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'init', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'io', 50, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'json', 7, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'latch', 8, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'lock', 16, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'memory', 43, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'merge_trace', 27, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'oledb', 6, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'optimization', 3, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'process', 12, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'query_store', 68, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'redo', 5, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'replication', 10, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'satellite_authentication', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'satellite_cargo_messages', 12, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'satellite_launchpad_communication', 5, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'scheduling', 26, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'security', 9, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'server', 23, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'session', 31, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'storage_management', 23, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'stretch', 62, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'synchronization', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'task', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'temporal', 14, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'transaction', 14, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'transactions', 53, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'transmitter', 9, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'transport', 10, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'ucs', 8, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'unload', 1, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'warnings', 7, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'xtp', 31, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'xtp_encryption', 3, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'xtp_io_governance', 2, CAST(13.00 AS DECIMAL(4, 2)) )
		, ( N'_UnAssigned', 5, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'access_methods', 6, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'broker', 73, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'cdc_logscan', 2, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'change_tracking', 1, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'clr', 2, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'cursor', 11, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'database', 21, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'deadlock_monitor', 6, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'errors', 5, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'exception', 3, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'execution', 14, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'io', 20, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'latch', 4, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'lock', 6, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'memory', 12, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'process', 12, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'replication', 7, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'scheduling', 21, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'server', 21, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'synchronization', 1, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'transactions', 2, CAST(10.00 AS DECIMAL(4, 2)) )
		, ( N'_UnAssigned', 26, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'access_methods', 18, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'alwayson', 97, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'broker', 42, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'cdc_logscan', 2, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'change_tracking', 2, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'clr', 3, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'cursor', 18, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'database', 40, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'deadlock_monitor', 6, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'errors', 19, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'exception', 4, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'execution', 106, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'filetable', 13, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'fulltext', 8, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'garbage_collection', 1, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'hadr', 1, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'index', 9, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'init', 1, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'io', 21, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'latch', 6, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'lock', 11, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'memory', 34, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'oledb', 5, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'process', 12, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'replication', 8, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'scheduling', 24, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'security', 3, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'server', 15, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'session', 14, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'storage_management', 1, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'synchronization', 2, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'task', 2, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'transactions', 46, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'transmitter', 9, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'transport', 9, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'ucs', 1, CAST(11.00 AS DECIMAL(4, 2)) )
		, ( N'warnings', 7, CAST(11.00 AS DECIMAL(4, 2)) );

IF OBJECT_ID('tempdb.dbo.#presel') IS NOT NULL
BEGIN
	DROP TABLE #presel;
END

SELECT oc.name AS EventName
		, oc.description AS column_description
		, ca.map_value AS SearchKeyword
		, @ServerMajorVersion AS SQLVersion
	INTO #presel
	FROM sys.dm_xe_objects oc
		OUTER APPLY ( SELECT mv.map_value
							FROM sys.dm_xe_object_columns occ
								INNER JOIN sys.dm_xe_map_values mv
									ON occ.type_name = mv.name
										AND occ.column_value = mv.map_key
										AND occ.object_package_guid = mv.object_package_guid
							WHERE occ.name = 'KEYWORD'
								AND occ.object_name = oc.name
					) ca
	WHERE oc.object_type = 'event';

/* version specific features */
SELECT *
	FROM #XECounts xc
	WHERE xc.SQLVersion = @ServerMajorVersion
		AND xc.Feature NOT IN ( SELECT Feature
									FROM #XECounts x
									WHERE x.SQLVersion &lt; @ServerMajorVersion );

/* change in feature counts*/
SELECT xv.Product
		, xc.Feature
		, xc.FeatureEventCount
		, ISNULL(fo.FeatureEventCount, 0) AS PreviousEditionCount
		, xc.FeatureEventCount - ISNULL(fo.FeatureEventCount, 0) AS NewEventCount
		, CASE	WHEN ISNULL(fo.Feature, '') = '' THEN 'New Feature'
				ELSE 'Existing Feature'
			END AS NewOrOld
	FROM #XECounts xc
		INNER JOIN #XEVersions xv
			ON xc.SQLVersion = xv.ServerMajorVersion
		FULL OUTER JOIN ( SELECT x2.Feature
									, x2.FeatureEventCount
								FROM #XECounts x2
									INNER JOIN #XEVersions xev
										ON x2.SQLVersion = xev.ServerMajorVersion
								WHERE xev.VersionID = ( SELECT VersionID - 1
															FROM #XEVersions x
															WHERE x.ServerMajorVersion = @ServerMajorVersion
														)
						) fo
			ON xc.Feature = fo.Feature
	WHERE 1 = 1
		AND xc.SQLVersion = @ServerMajorVersion;

/* specific counts for the current server just in case new events rolled out with a patch*/
SELECT MAX(xev.Product) AS Product
		, ISNULL(ou.Feature, '        Grand Total') AS FeatureCount
		, SUM(ou.FeatureEventCount) AS FeatureEventCount
	FROM ( SELECT ISNULL(p.SearchKeyword, '_UnAssigned') AS Feature
					, COUNT(*) AS FeatureEventCount
					, p.SQLVersion
				FROM #presel p
				GROUP BY p.SearchKeyword, p.SQLVersion
			) ou
		INNER JOIN #XEVersions xev
			ON ou.SQLVersion = xev.ServerMajorVersion
	GROUP BY ou.Feature WITH ROLLUP;</pre><p>In the preceding query, I have provided an aggregation of the events and features across multiple editions of SQL Server. This aggregate of data is necessary to help see how the features are changing and how the events are changing within the features that remain constant from one version to the next.</p>
<p>Once that data is aggregated, I then provide a couple of sample queries that show what can be done with the data. I need to stress here that I have not provided an exhaustive set of queries to explore this data seven ways to Sunday. I have left those types of exercises up to the reader to explore and experiment.</p>
<p>The first example query shows how to pull the new features that can be &#8220;Traced&#8221; in the current version of SQL Server on which the query is being executed. The second example provides a difference count between versions of SQL Server to help illustrate the evolution of XEvents within SQL Server. The third query is a simple query to list out the number of events for each feature in your version of SQL Server.</p>
<p>From here, one might wish to explore all of the events that are related to a specific feature. This would be easily accomplished by querying out the data from the #presel temp table based on the feature name. Orrrr&#8230;one could query the desired feature by following the guidelines in <a href="http://bit.ly/29WYHRk">this article</a>.</p>
<h3>Conclusion</h3>
<p>In the article today, I have shown how it is possible to see the new events and how they relate to the various features within SQL Server. Being able to correlate events that can trap information about new features can and will help you evolve into that rock-star DBA you are trying to become!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3689" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/30/events-by-feature/">Events By Feature</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/30/events-by-feature/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Finding the Right Path</title>
		<link>https://jasonbrimhall.info/2016/08/24/finding-the-right-path/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=finding-the-right-path</link>
					<comments>https://jasonbrimhall.info/2016/08/24/finding-the-right-path/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 24 Aug 2016 12:30:02 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3675</guid>

					<description><![CDATA[<p>What is this gaping hole in the coverage of Extended Events? To be honest, it is not a very complicated topic or very difficult gap to fill. It's just something that has been overlooked. The gap boils down to this: how does one consistently find the correct path to the Extended Event Log file (XEL file)?</p>
The post <a href="https://jasonbrimhall.info/2016/08/24/finding-the-right-path/">Finding the Right Path</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class=" wp-image-3678 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/xe_path1.png" alt="xe_path1" width="119" height="170" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/xe_path1.png 207w, https://jasonbrimhall.info/wp-content/uploads/2016/08/xe_path1-35x50.png 35w" sizes="(max-width: 119px) 85vw, 119px" />I have a fairly large backlog of articles that are in progress or that are planned for my series about Extended Events. Despite the backlog and planned articles, every now and then something else comes up that bumps things around. This article is an example of bumping the schedule around. You can see some of the backlog and the full list of articles in the series by visiting the <a href="http://bit.ly/XE60Days">table of contents &#8211; here</a>.</p>
<p>I bring that up for a couple of reasons. First and foremost being that the topic was recently raised as a &#8220;need&#8221; by some colleagues. The second being that I see the need and how it was lacking in coverage by anything I had already written.</p>
<p>What is this gaping hole in the coverage of Extended Events? To be honest, it is not a very complicated topic or very difficult gap to fill. It&#8217;s just something that has been overlooked. The gap boils down to this: how does one consistently find the correct path to the Extended Event Log file (XEL file)?</p>
<h3>Filling the Gap</h3>
<p>The gap I will be working to fill in this article deals with consistently finding the file path for Extended Event (XE) sessions. This gap rises due a few different things such as the ability to define a target in different manners, being able to move the logs directory, or even the fact that a target may not be added to the session (let alone a file target). These causes can all contribute to a bit of frustration and may pose as different symptoms when trying to get the file path.</p>
<p>One additional complication is tied to the running state of a session. For that complication, I talked briefly about it in my article about <a href="http://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/">better practices</a>. The state of the session could have an impact and could cause frustration when trying to retrieve the file path. All of these things are considerations that must be made when trying to retrieve the file path.</p>
<p>To find the file path, let&#8217;s start with some basics. The default path for XEL files is in the log directory of the instance. In addition to this default behavior, each session stores metadata about <a href="http://bit.ly/1Uu4QyY">running sessions</a> as well as <a href="http://bit.ly/1XfzO27">deployed sessions</a> that is accessible from DMVs and system catalogs.</p>
<h3>Log Path</h3>
<p>The first basic to tackle is the log path for the instance. I can query for the log path of the error log for the instance and rely on that as the path of my xel files. Should I choose this method, then I could execute the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ErrorPath VARCHAR(256) = CONVERT(VARCHAR(256),SERVERPROPERTY('ErrorLogFileName'));

SELECT LEFT(@ErrorPath,
			LEN(@ErrorPath) - CHARINDEX('\', REVERSE(@ErrorPath)) + 1) AS ErrorPath;</pre><p>Executing that query on my SQL 2014 instance produces the following results:</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3681" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath-1024x149.jpg" alt="errorpath" width="560" height="81" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath-1024x149.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath-300x44.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath-768x111.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath-50x7.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/errorpath.jpg 1047w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>Now the obvious problems with this method come from the fact that relying on this data is relying upon an assumption that you have set all of your XE Sessions to use the default log path. If you have declared your sessions to use a file target and did not specify a path, then the assumption is safe. However, if you are detail oriented, you probably have been somewhat explicit in how you define your event file target. This brings us to the next topic &#8211; defining the path.</p>
<h3>Defining The Path</h3>
<p>While a bit of bird-walk, it is necessary to cover this topic at this juncture. This brief discussion will help to understand some of the other issues with retrieving the path consistently.</p>
<p>When defining the path of the event path, there is a bit of flexibility in how one can define the file to be used. You can either declare the file as just the file name, or you can define the file as the folder path along with the file name. Both methods are completely legitimate. Unfortunately, this flexibility is what causes some of the pain with retrieving the file path consistently.</p>
<p>Let&#8217;s take a look at two quick, and acceptable, ways to add an event file to an XE Session. I will be re-using a session from a <a href="http://bit.ly/2b0xKuy">previous article</a> for these examples.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [AuditSelects] ON SERVER
ADD EVENT sqlserver.degree_of_parallelism (
	ACTION ( sqlserver.database_id, sqlserver.database_name,
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname,
	sqlserver.context_info, sqlserver.client_connection_id )
	WHERE  statement_type = ( 1 ) --type 1 is a select statement
	AND [sqlserver].[database_name] = N'AdventureWorks2014' 
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
			AND [sqlserver].[client_app_name] NOT LIKE 'Red Gate Software Ltd SQL Prompt%'
		)
ADD TARGET package0.event_file (  SET filename = N'C:\Database\XE\AuditSelects.xel'
									, max_rollover_files = ( 25 ) )
;
GO</pre><p>This is a pretty standard format I use for creating my sessions. The section I want to highlight though is the set of the filename near the end of the script. I will generally define the entire path for my xel files when I create a session &#8211; just as I have done in this example. Defining this path helps me to know exactly where I am putting the session for starters. Equally as important is that this path is easier to retrieve from metadata because I have explicitly defined the path.</p>
<p>Take this next example of the same session but with one minor difference.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [AuditSelects] ON SERVER
ADD EVENT sqlserver.degree_of_parallelism (
	ACTION ( sqlserver.database_id, sqlserver.database_name,
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname,
	sqlserver.context_info, sqlserver.client_connection_id )
	WHERE  statement_type = ( 1 ) --type 1 is a select statement
	AND [sqlserver].[database_name] = N'AdventureWorks2014' 
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
			AND [sqlserver].[client_app_name] NOT LIKE 'Red Gate Software Ltd SQL Prompt%'
		)
ADD TARGET package0.event_file (  SET filename = N'AuditSelects.xel'
									, max_rollover_files = ( 25 ) )
;
GO</pre><p>The minor difference in this example is just in how the filename was defined. It is technically accurate and acceptable to only use the filename instead of the path and filename as I did in the previous example. The problem here comes from the retrieval of the path from metadata.</p>
<h3>Getting the Path</h3>
<p>In the previous two examples, I showed two methods of defining the filename within a session. In the former example, this means I can more easily find the path. However, if I use the script in the beginning of the article to find my xel file paths, then I have made an inaccurate assumption. This leads to an inconsistency in how the file path is fetched. In the latter example, the assumptions concerning the default log path would be valid and could be applied here.</p>
<p>Since the assumptions do not prove to be consistent or accurate across the board, we need to both evaluate how the data for each would look and we would need to see how to retrieve this path more consistently. First up is looking at how the data for each of these example sessions would be stored in metadata.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sesf.*
		, ses.name AS SessionName
	FROM sys.server_event_sessions ses
		INNER JOIN sys.server_event_session_fields sesf
			ON ses.event_session_id = sesf.event_session_id
	WHERE sesf.name = 'filename'
		AND ses.name LIKE 'auditselect%'</pre><p>In the preceding query, I am looking at the deployed session metadata for two sessions, both of which start with &#8220;AuditSelect&#8221;. In the sys.server_event_session_fields view, there is an attribute called name that contains the value &#8220;filename&#8221;. This value will only exist if the session has an event file target defined for the session. Running the query will yield the following results (on my system).</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3684" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta-1024x112.png" alt="eventfile_meta" width="560" height="61" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta-1024x112.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta-300x33.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta-768x84.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta-50x5.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/eventfile_meta.png 1291w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>In this result set, I can see there is one of each of the two event file definition methods I described in the previous section. In the green highlight you will see that I have the entire filepath. In the red highlight, you will only see the filename. Nothing special has been done to this data in the return as you can verify from the posted script. These are the actual stored values. So this would indeed seem like we have a bit of a problem, right?</p>
<p>Well, this is where we get to be a little bit imaginative and employ a script such as the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Deployed Session Metadata */
DECLARE @SessionName VARCHAR(128) = 'AuditSelects';

IF EXISTS ( SELECT 1
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = @SessionName )
	BEGIN
		IF ( SELECT CHARINDEX('\', CONVERT(VARCHAR(256),sesf.value))
						FROM sys.server_event_sessions ses
							INNER JOIN sys.server_event_session_fields sesf
								ON ses.event_session_id = sesf.event_session_id
						WHERE sesf.name = 'filename'
							AND ses.name = @SessionName ) &gt; 0
			BEGIN
				SELECT ses.name AS SessionName
						, LEFT(CONVERT(VARCHAR(256),sesf.value),
								LEN(CONVERT(VARCHAR(256),sesf.value)) - CHARINDEX('\',
																REVERSE(CONVERT(VARCHAR(256),sesf.value)))+1) AS XEFilePath
					FROM sys.server_event_sessions ses
						INNER JOIN sys.server_event_session_fields sesf
							ON ses.event_session_id = sesf.event_session_id
					WHERE sesf.name = 'filename'
						AND ses.name = @SessionName;
			END;
		ELSE
			BEGIN
				SELECT TOP 1 cte1.SessionName
						, LEFT(t2.file_name,
								LEN(t2.file_name) - CHARINDEX('\',
																REVERSE(t2.file_name))
								+ 1) AS XEFilePath
					FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128), sesf.value),
											'.xel', '*.xel') AS targetvalue
									, ses.name AS SessionName
								FROM sys.server_event_sessions ses
									INNER JOIN sys.server_event_session_fields sesf
										ON ses.event_session_id = sesf.event_session_id
								WHERE sesf.name = 'filename'
									AND ses.name = @SessionName
							) cte1
						CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,
																NULL, NULL, NULL) t2;
			END;
	END;</pre><p>Wow, that is considerably longer than the first example in the article. That is true! This script accounts for a few of the conditions that cause inconsistencies (but not yet all of them) in retrieving the file path for a deployed event session. The key here is to understand this will fetch the path whether you enter a complete path or not while creating the session. I also throw a check in there to confirm that the session has a file target as well as a check to ensure the session is deployed to the server.</p>
<p>Looking at the output, I get results that are somewhat friendly and easy to understand without any of the guesswork.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3685" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/xelpath_result.jpg" alt="xelpath_result" width="494" height="93" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/xelpath_result.jpg 494w, https://jasonbrimhall.info/wp-content/uploads/2016/08/xelpath_result-300x56.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/xelpath_result-50x9.jpg 50w" sizes="(max-width: 494px) 85vw, 494px" /></p>
<p>What if the session has never been started and did not have the full path declared? Well, that is one of the inconsistencies I am working on still. (<em>Update 2019/05/17 &#8211; An updated script is coming out soon that handles this little issue.)</em></p>
<p>There is an alternative to this method as well. For the time being, this method would also be recommended in the event the session being researched happens to be one of the system sessions that is &#8220;private&#8221;. This next code chunk will show two different methods to parse the file path from running session metadata in the DMVs.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* use query() method for running session */
SELECT cte1.SessionName
		,CAST(cte1.target_data.query('data(/EventFileTarget/File/@name)') AS VARCHAR(256)) AS XEFilePath
	INTO #presel
	FROM ( SELECT target_data = CONVERT(XML, target_data), s.name AS SessionName
				FROM sys.dm_xe_session_targets t
					INNER JOIN sys.dm_xe_sessions s
						ON t.event_session_address = s.address
				WHERE t.target_name = 'event_file'
					AND s.name = 'system_health'
			) cte1;

SELECT p.SessionName
		, LEFT(p.XEFilePath,
				LEN(p.XEFilePath) - CHARINDEX('\', REVERSE(p.XEFilePath)) + 1) AS XEFilePath
	FROM #presel p;

DROP TABLE #presel;
GO

/* use value() method on Running Session Metadata */
SELECT FileEvent.FileTarget.value('(@name)[1]',
										'varchar(256)') AS [FilePath]
		,cte1.SessionName
	INTO #presel
	FROM ( SELECT target_data = CONVERT(XML, target_data), s.name AS SessionName
				FROM sys.dm_xe_session_targets t
					INNER JOIN sys.dm_xe_sessions s
						ON t.event_session_address = s.address
				WHERE t.target_name = 'event_file'
					AND s.name = 'system_health'
			) cte1
	CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File')FileEvent ( FileTarget );	

SELECT p.SessionName
		, LEFT(p.FilePath,
				LEN(p.FilePath) - CHARINDEX('\', REVERSE(p.FilePath)) + 1) AS XEFilePath
	FROM #presel p;

DROP TABLE #presel;
GO</pre><p></p>
<h3>Conclusion</h3>
<p>In the article today, I have shown some of the internals to retrieving file paths for Extended Event Sessions. I dove into metadata to pull out the path for the session and discussed some concerns for some of these methods. In the end, you have a few viable options to help retrieve the file path in a more consistent fashion.</p>
<p>To read more about Extended Events, I recommend <a href="http://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">this series of articles</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3675" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/24/finding-the-right-path/">Finding the Right Path</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/24/finding-the-right-path/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #081: Recap</title>
		<link>https://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-081-recap</link>
					<comments>https://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 18 Aug 2016 22:37:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3644</guid>

					<description><![CDATA[<p>August 2016 TSQL Tuesday Recap</p>
The post <a href="https://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/">T-SQL Tuesday #081: Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Sharpen Something</h3>
<p><img loading="lazy" class="alignleft wp-image-3590" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png" alt="sqlskillsharpener_pig" width="116" height="178" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png 391w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-196x300.png 196w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-33x50.png 33w" sizes="(max-width: 116px) 85vw, 116px" />In case you missed it (many did), TSQL Tuesday was a challenging event this month. I invited people to do a put a little more into writing a post than what they may usually do. There were some very good reasons for this. If you are interested, take a look back at the invite and see if you maybe want to give it a go outside the bounds of TSQL Tuesday. You can check out the <a href="http://bit.ly/2atogaq">original post here</a>.</p>
<p>Before I get into the nitty gritty I have a confession. This topic was a reminder for myself as much as it was a challenge to others to help me continue to drive and improve in various areas as I see fit.</p>
<p>There are other dirty little secrets too. Some may become apparent as you read through the recap.</p>
<h3>Recap of the Event</h3>
<p>One of the tricks to becoming and staying a top tier data talent or professional is a perpetual cycle to learn, adapt, change, and evolve. We <strong>must</strong> be in a continual cycle of self evaluation and self modification. Let&#8217;s call this by something else &#8211; we must be <em>agile</em>. There I said the five letter word. Think about it in broad strokes with your career &#8211; it is a development process with perpetual evaluation, review and tweaks.</p>
<p>Now think about the invite and see how that fits with what I just said or with the, <em>cough cough, </em>agile flow. You start (albeit very basically) with a need for enhancement, then you plan which pieces of the enhancement you can accomplish, you then do the work (whether successful or not), then after you deliver the work you conclude with a retrospective (what went well and what needs to change). Yes! I do feel rather dirty for sneaking this on everybody like this. That said, when you think about the model and apply it in broad strokes to your career path &#8211; it has merit.</p>
<p>Another way of viewing this is to think in terms of the following flowchart to help improve your personal mindset or maybe improve your personal mental power. The process is repetitive and follows a natural course. Once you have acted on some plan, you must review the performance and results and then gauge where your mindset needs to go from there to improve.</p>
<p><img loading="lazy" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/mindset_improvement_560.png" alt="mindset_improvement_560" usemap="#ga78137" width="560" height="399" border="0" /></p>
<map id="ga78137" name="ga78137">
<area alt="Jason Brimhall" shape="default" href="http://bit.ly/2aXBEAg" />
<area title="Rob Farley" alt="Rob Farley" coords="206,71,70" shape="circle" href="http://sqlblog.com/blogs/rob_farley/archive/2016/08/09/the-impact-of-compression-delay-in-real-time-operational-analytics.aspx" target="_blank" />
<area title="Steve Jones" alt="Steve Jones" coords="73,79,65.5" shape="circle" href="https://voiceofthedba.wordpress.com/2016/08/09/t-sql-tuesday-81-sharpening-skills/" target="_blank" />
<area title="Robert Davis" alt="Robert Davis" coords="314,314,69" shape="circle" href="http://sqlsoldier.net/wp/sqlserver/tsqltuesday81migratingdatabaseswithdelllitespeed" target="_blank" />
<area title="Kenneth Fisher" alt="Kenneth Fisher" coords="357,78,69" shape="circle" href="https://sqlstudies.com/2016/08/09/azure-whats-the-difference-between-sql-database-and-sql-server/" target="_blank" />
<area title="Kennie Nybo Pontoppidan" alt="Kennie Nybo Pontoppidan" coords="472,158,68.5" shape="circle" href="http://www.pontop.dk/single-post/2016/08/09/T-SQL-Tuesday-81---Going-back-to-the-classics-Snodgrass%E2%80%99-book-on-temporal-databases" target="_blank" />
<area title="Mala Mahadevan" alt="Mala Mahadevan" coords="470,303,70.5" shape="circle" href="https://curiousaboutdata.com/2016/08/09/tsql-tuesday-081-sharpening-something/" target="_blank" />
<area title="Wayne Sheffield" alt="Wayne Sheffield" coords="81,224,64" shape="circle" href="http://blog.waynesheffield.com/wayne/archive/2016/08/t-sql-tuesday-81-sharpen-something/" target="_blank" />
<area alt="Jason Brimhall" shape="default" href="http://bit.ly/2aXBEAg" /></map>
<p>&nbsp;</p>
<h3>In other Words</h3>
<p>Did you just look at the picture or did you explore the picture? If you hover the picture, you will find there are links to this months participants. There were only eight so not a ton of exploration is necessary.</p>
<p>Here are my thoughts on each of the posts submitted this month:</p>
<p><a href="http://blog.waynesheffield.com/wayne/archive/2016/08/t-sql-tuesday-81-sharpen-something/"><strong>Wayne Sheffield</strong></a> (<a href="http://blog.waynesheffield.com/">blog </a>| <a href="https://twitter.com/DBAWayne">twitter</a>) &#8211; You can find his link in the big arrow that restarts the cycle. I put his link here because he ran into a ton of blockers during his experiment and he is at a spot of practically restarting &#8211; again. This is not the first time he has restarted in his quest to learn more about Availability Groups. Wayne fully admits he is deficient in AG and states near the end of the post that he had to humble himself going through this exercise. That is awesome! We could all use a little humility on a more regular basis.</p>
<p><a href="https://curiousaboutdata.com/2016/08/09/tsql-tuesday-081-sharpening-something/"><strong>Mala Mahadevan</strong></a> (<a href="https://curiousaboutdata.com/">blog </a>| <a href="https://twitter.com/sqlmal">twitter</a>) &#8211; You can find her link in the &#8220;Results&#8221; circle. The reason for this choice is that Mala discusses her midlife <del>crisis</del> &#8211; erm career change. M<a href="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>ala held out for quite a while looking for just the right opportunity. When it came, she snatched it up. Along with that career change, she has implemented a plan to become more active in blogging and to learn more and more through various avenues. The increase in blogging and the ability to stick to her guns resulted in a new job/career she seems to be happy with at the moment.</p>
<p><a href="https://web.archive.org/web/20161120213222/http://sqlsoldier.net:80/wp/sqlserver/tsqltuesday81migratingdatabaseswithdelllitespeed"><strong>Robert Davis</strong></a> (<a href="https://web.archive.org/web/20190406125831/http://sqlsoldier.net/">blog </a>| <a href="https://twitter.com/SQLSoldier">twitter</a>) &#8211; Robert found himself placed in the performance circle thanks to his article involving a third party backup utility that should be heavy on the performance side. Robert needed something interesting to push him to reacquaint himself with this tool. Once he found that project that required just a touch of ingenuity, performance and a way to avoid the GUI, Robert found himself right at home with a great solution for his environment.</p>
<p><a href="http://www.pontop.dk/single-post/2016/08/09/T-SQL-Tuesday-81---Going-back-to-the-classics-Snodgrass%E2%80%99-book-on-temporal-databases"><strong>Kennie Nybo Pontoppidan</strong></a> (<a href="http://www.pontop.dk/">blog </a>| <a href="https://twitter.com/KennieNP">twitter</a>) &#8211; Kennie landed in the Actions node mostly because he decided to take the challenge and act on his long time desire to get better at the new temporal features. To do that, he decided to read a book by Snodgrass which seriously sounded like something from Harry Potter to me. Kennie outlines a bunch of information that he learned from the book such as tracking time based data from either a trans<strong>action</strong> or valid-time perspective.</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3657" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain-1024x561.png" alt="personal_growth_brain" width="560" height="307" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain-1024x561.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain-300x165.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain-768x421.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain-50x27.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/personal_growth_brain.png 1200w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p><a href="https://sqlstudies.com/2016/08/09/azure-whats-the-difference-between-sql-database-and-sql-server/"><strong>Kenneth Fisher</strong></a> (<a href="https://sqlstudies.com">blog</a> | <a href="https://twitter.com/sqlstudent144">twitter</a>) &#8211; I placed this one into the behavior node. Maybe it is a bit of a stretch, but it seems to make sense since he discussed some behavioral differences between Azure DB and SQL Server. Things just do not work exactly the same between the two. You will need to understand these differences if you find yourself in a spot where you must work with both.</p>
<p><a href="https://voiceofthedba.wordpress.com/2016/08/09/t-sql-tuesday-81-sharpening-skills/"><strong>Steve Jones</strong></a> (<a href="https://voiceofthedba.wordpress.com">blog </a>| <a href="https://twitter.com/way0utwest">twitter</a>) &#8211; When looking through the image, you will find that Steve landed solidly in the <em>mindset</em> node. When I read his contribution, I got the full impression that his mind was 100% in the right place. He set out to learn something and try to get better at it. Additionally, he blogged about a topic that is near and dear to me &#8211; Extended Events. Have I mentioned before that I have a lot of content about XE? <a href="http://bit.ly/XE60Days">You can read a bunch of it here</a>. Like Wayne, Steve was humble near the end of his article. He notes that he was clumsy as he started working with XE but that he is glad he did it as well. Read his article. He gave me a great idea of another use for XE and I am sure it may sound good to you too!</p>
<p><a href="http://blogs.lobsterpot.com.au/2016/08/09/the-impact-of-compression-delay-in-real-time-operational-analytics/"><strong>Rob Farley</strong></a> (<a href="http://blogs.lobsterpot.com.au">blog </a>| <a href="https://twitter.com/rob_farley">twitter</a>) &#8211; I planted Rob firmly on the attitude node. It seems clear to me that Rob had loads of attitude throughout his article about Operational Analytics. The attitude I perceived was that of humility and yearning. Rob feels like he has a lot to learn and his attitude is in the right place it seems to keep him going while he tries to learn more in the field of Operational Analytics.</p>
<p><a href="http://bit.ly/2aXBEAg"><strong>My Contribution</strong></a> link can be found by clicking on any spot in the image that is not already described. I wrote about my experiences with trying to pick up a little on JSON.</p>
<p>That is a wrap of all eight contributions. If you did not contribute this month, I recommend that you still try to do something with the challenge issued with this months TSQL Tuesday.</p>
<p>Edit: Added links to the articles with each persons name in the event this page is being viewed with Firefox. There seems to be an issue with the links in the image map within Firefox.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3644" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/">T-SQL Tuesday #081: Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/18/t-sql-tuesday-081-recap/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Audit All Select Statements</title>
		<link>https://jasonbrimhall.info/2016/08/08/audit-all-select-statements/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=audit-all-select-statements</link>
					<comments>https://jasonbrimhall.info/2016/08/08/audit-all-select-statements/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 08 Aug 2016 12:44:43 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3553</guid>

					<description><![CDATA[<p>Legislation and regulation sometimes dictates that certain activities must be tracked within a database. On occasion, it will be required that queries be audited and tracked to reach compliance with the legislation or regulation. To achieve this compliance, this article will demonstrate how to use Extended Events to audit statements being executed within the database.</p>
The post <a href="https://jasonbrimhall.info/2016/08/08/audit-all-select-statements/">Audit All Select Statements</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="wp-image-3630 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/audit_select.png" alt="audit_select" width="229" height="197" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/audit_select.png 500w, https://jasonbrimhall.info/wp-content/uploads/2016/07/audit_select-300x259.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/07/audit_select-50x43.png 50w" sizes="(max-width: 229px) 85vw, 229px" />Legislation and regulation sometimes dictates that certain activities must be tracked within a database. On occasion, it will be required that queries be audited and tracked to reach compliance with the legislation or regulation. To achieve this compliance, this article will demonstrate how to use Extended Events to audit statements being executed within the database.</p>
<p>Over the course of a few recent articles, I have included little hints here and there alluding to this article. In fact, now would be a good time to review one of these articles in preparation for what I will be sharing today. Take a moment to refresh your memory on this article about <a href="http://bit.ly/29WYHRk">finding the right event &#8211; here</a>.</p>
<h3>Backstory</h3>
<p>I have to be a little honest here. Prior to somebody asking how they could possibly achieve a statement audit via extended events, I had not considered it as a tool for the job. I would have relied on Audit (which is Extended Event related), or some home grown set of triggers. In this particular request, Audit was not fulfilling the want and custom triggers was not an option. Another option might have included the purchase of third party software but there are times when budget does not allow for nice expensive shiny software.</p>
<p>So, with a little prodding, I hopped into the metadata and poked around a bit to see what I could come up with to achieve this low-budget audit solution.</p>
<h3>Low-Budget Audit</h3>
<p>Using the handy scripts I have shown previously (and that I <a href="http://bit.ly/29WYHRk">just linked to</a>), I was able to explore the Extended Events metadata and find just what may work properly. The requirements in this case were that it needed to be done in XEvents and that it must capture SELECT statements. To find the events that seemed plausible for this task, I plugged the term &#8220;SELECT&#8221; into my queries as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @TermDescription VARCHAR(64) = 'Select'
	, @ColumnDesc VARCHAR(64) = 'statement'
	, @ReadFlag VARCHAR(64) = NULL; --readonly' --ALL if all columntypes are desired --data --customizable
 
SELECT oc.object_name AS EventName
		, oc.name AS column_name
		, oc.type_name
		, oc.column_type AS column_type
		, oc.column_value AS column_value
		, oc.description AS column_description
		, ca.map_value AS SearchKeyword
		, oc.column_type
	FROM sys.dm_xe_object_columns oc
		CROSS APPLY ( SELECT mv.map_value
							FROM sys.dm_xe_object_columns occ
								INNER JOIN sys.dm_xe_map_values mv
									ON occ.type_name = mv.name
										AND occ.column_value = mv.map_key
										AND occ.object_package_guid = mv.object_package_guid
							WHERE occ.name = 'KEYWORD'
								AND occ.object_name = oc.object_name
					) ca
	WHERE (oc.object_name = @TermDescription
		OR oc.description LIKE '%' + ISNULL(@ColumnDesc,@TermDescription) + '%')
		AND oc.column_type = ISNULL(@ReadFlag, oc.column_type)
	ORDER BY EventName, column_name;

GO</pre><p>From this query, there was really only one event that made any sense for my task &#8211; &#8220;degree_of_parallelism&#8221;. There was another event returned in the result set, but it made no sense to me as a possible candidate event for auditing select statements (it was ucs_transmitter_reclassify). From the results, I then took the keyword associated to degree_of_parallelism to see what else might be pertinent. I plugged that keyword &#8220;execution&#8221; into the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @Keyword VARCHAR(64) = 'execution' --'synchronization'
 
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,olm.file_version
		,xp.name AS PackageName
		,mv.map_value AS SearchKeyword
		,ch.Channel
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND oc.column_value = mv.map_key
			AND oc.name = 'KEYWORD'
		INNER JOIN sys.dm_xe_packages xp
			ON oc.object_package_guid = xp.guid
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = oc.object_name
			AND ch.PkgGuid = oc.object_package_guid
	WHERE mv.map_value = @Keyword
	;
GO</pre><p>The results of the previous query will be quite a bit more substantial. Some make sense to include in the audit and some do not. I opted to not included any of the events to keep things as clean and simple as possible.</p>
<h3>More Requirements</h3>
<p>I now have the base events covered that I want to use for my audit. That said, my base requirements are just not extensive enough. When I audit something, I really want to know who did it, when it was done, where it originated and what was it that they did. The degree_of_parallelism event will capture all of the select statements but it does not meet these additional requirements.</p>
<p>In order to meet the additional requirements, I will attach a handful of actions to the degree_of_parallelism event. The addition of the actions will provide all of the data I want and need. Combine the event and actions together, I came up with the following session definition.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'AuditSelects' )
	DROP EVENT SESSION AuditSelects
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO


CREATE EVENT SESSION [AuditSelects] ON SERVER
ADD EVENT sqlserver.degree_of_parallelism (
	ACTION ( sqlserver.database_id, sqlserver.database_name,
	sqlserver.nt_username, sqlserver.sql_text, sqlserver.username,sqlserver.session_nt_username,
	sqlserver.client_app_name, sqlserver.session_id, sqlserver.client_hostname,
	sqlserver.context_info, sqlserver.client_connection_id )
	WHERE  statement_type = ( 1 ) --type 1 is a select statement
	AND [sqlserver].[database_name] = N'AdventureWorks2014' 
			AND [sqlserver].[client_app_name] &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
			AND [sqlserver].[client_app_name] NOT LIKE 'Red Gate Software Ltd SQL Prompt%'
		)
ADD TARGET package0.event_file (  SET filename = N'C:\Database\XE\AuditSelects.xel'
									, max_rollover_files = ( 25 ) )
WITH (  MAX_MEMORY = 4096 KB
		, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 30 SECONDS
		, MAX_EVENT_SIZE = 0 KB
		, MEMORY_PARTITION_MODE = NONE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = OFF );
GO</pre><p>This is a very simple session to pull together. I have added a few things in on my predicate to help limit the scope of the session to the AdventureWorks2014 database and to make sure I am not trapping events related to the code completion tools shown. Notice here also that there is a <em>potential</em> chance to optimize this session. Can you find it? Hint: It may be in the predicate. Second hint: re-read this article about <a href="http://bit.ly/1MIGeDI">predicates</a>.</p>
<p>Now the trick to what makes this work to audit only the select statements is right there in the predicate. I have instructed the session to ignore any statement_type that is not a value of 1. As it turns out, statement_type of 1 is a select statement. To see how these values map, here is a quick query and the correlated results.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = 'degree_of_parallelism'
	,@ReadFlag VARCHAR(64) = 'readonly' --readonly' --ALL if all columntypes are desired
 
SELECT oc.object_name as EventName,oc.name as ColName,mv.name as MapName, map_key, map_value 
	FROM sys.dm_xe_map_values mv
		Inner Join sys.dm_xe_object_columns oc
			on mv.name = oc.type_name
			AND mv.object_package_guid = oc.object_package_guid
	WHERE oc.object_name = @EventName
		AND oc.column_type &lt;&gt; @ReadFlag
	ORDER BY MapName, mv.map_key;
GO</pre><p></p>
<h3><img loading="lazy" class="aligncenter size-large wp-image-3631" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype-1024x220.jpg" alt="dop_statementtype" width="560" height="120" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype-1024x220.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype-300x64.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype-768x165.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype-50x11.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/dop_statementtype.jpg 1242w" sizes="(max-width: 560px) 85vw, 560px" /></h3>
<p>Based on these values, should you want to audit a different query type, just change the predicate to use the map_key value that corresponds to the desired statement type.</p>
<h3>Testing</h3>
<p>Testing this session is rather simple. Here is a quick and dirty script to help test it.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION AuditSelects ON SERVER
STATE = START;

USE AdventureWorks2014;
GO

SELECT *
	FROM Person.Person;


/* parse the data */
IF EXISTS (SELECT OBJECT_ID('tempdb.dbo.#xmlprocess'))
BEGIN
DROP TABLE #xmlprocess
END

SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.event_session_id--, '' AS event_predicate
	INTO #xmlprocess
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, ses.event_session_id
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					--INNER JOIN sys.server_event_session_events sese
					--	ON ses.event_session_id = sese.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'AuditSelects'
					) cte1
				OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;


SELECT x.event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, x.event_data.value('(event/@package)[1]', 'varchar(50)') AS package_name
		, DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP),
					x.event_data.value('(event/@timestamp)[1]',
										'datetime2')) AS [timestamp]
		, event_data.value('(event/data[@name="dop"]/value)[1]',
							'bigint') AS dop
		, event_data.value('(event/data[@name="statement_type"]/value)[1]',
							'varchar(max)') AS statement_type
		, event_data.value('(event/data[@name="workspace_memory_grant_kb"]/value)[1]',
							'bigint') AS workspace_memory_grant_kb
		, event_data.value('(event/action[@name="client_app_name"]/value)[1]',
							'varchar(max)') AS client_app_name
		, event_data.value('(event/action[@name="client_connection_id"]/value)[1]',
							'uniqueidentifier') AS client_connection_id
		, event_data.value('(event/action[@name="client_hostname"]/value)[1]',
							'varchar(max)') AS client_hostname
		, event_data.value('(event/action[@name="context_info"]/value)[1]',
							'varbinary(max)') AS context_info
		, event_data.value('(event/action[@name="database_id"]/value)[1]',
							'int') AS database_id
		, event_data.value('(event/action[@name="database_name"]/value)[1]',
							'varchar(max)') AS database_name
		, event_data.value('(event/action[@name="nt_username"]/value)[1]',
							'varchar(max)') AS nt_username
		, event_data.value('(event/action[@name="session_id"]/value)[1]',
							'int') AS session_id
		, event_data.value('(event/action[@name="session_nt_username"]/value)[1]',
							'varchar(max)') AS session_nt_username
		, event_data.value('(event/action[@name="sql_text"]/value)[1]',
							'varchar(max)') AS sql_text
		, event_data.value('(event/action[@name="username"]/value)[1]',
							'varchar(max)') AS username
	FROM #xmlprocess x
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON x.event_data.value('(event/@name)[1]', 'varchar(50)') = sese.name
				AND x.event_session_id = sese.event_session_id
	ORDER BY timestamp
		, event_data.value('(event/action[@name="event_sequence"]/value)[1]',
							'varchar(max)');</pre><p></p>
<h3>Conclusion</h3>
<p>Building low cost solutions is a common requirement for the data professional. When given the opportunity, try things out to see what you can build to provide the solution. In this case, I have demonstrated how Extended Events, however unlikely a candidate, can provide a working solution to help audit any select statements occurring within your database.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3553" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/08/audit-all-select-statements/">Audit All Select Statements</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/08/audit-all-select-statements/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>BIT9 PathNames</title>
		<link>https://jasonbrimhall.info/2016/08/05/sql-agent-job-schedules-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-agent-job-schedules-2</link>
					<comments>https://jasonbrimhall.info/2016/08/05/sql-agent-job-schedules-2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 05 Aug 2016 21:09:17 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[BIT9]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Agent Job]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3599</guid>

					<description><![CDATA[<p>We live in a day and age when security (data, network, server, etc) is seemingly at the forefront of the daily news.</p>
The post <a href="https://jasonbrimhall.info/2016/08/05/sql-agent-job-schedules-2/">BIT9 PathNames</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We live in a day and age when security (data, network, server, etc) is seemingly at the forefront of the daily news. In our quest to improve security we seemingly always find more and more products that are supposed to help with that security. Sometimes, those products require a data repository. As it happens, it is not uncommon for that repository to be in a database. Today, I am looking into a specific issue with the Bit9 product.</p>
<h3>Why?</h3>
<p>There are some very good reasons as a matter of fact. One really big reason is that I could find no decent information about this issue. The bigger reason is the seemingly indifferent level of response and the delays I saw in response from the Bit9 support channels.</p>
<p>In this specific case, the first response from their support channels took more than two days. Subsequent responses were more than a week later. For the client, this actually caused delays in a project they were working on. Was the issue significant? It was not an outage causing issue, but it was one that did seem to continue to grow and cause concerns with disk space.</p>
<h3>The Issue</h3>
<p><a href="https://www.carbonblack.com/"><img loading="lazy" class=" wp-image-3616 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/bit9.png" alt="bit9" width="192" height="116" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9.png 380w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9-300x182.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9-50x30.png 50w" sizes="(max-width: 192px) 85vw, 192px" /></a>It may be appropriate to discuss what Bit9 does prior to breaking into the details about the issue. If you have never had any experience with this product before, you may be running a product from a competitor such as Symantec. Bit9 is a an endpoint protection tool from Carbon Black. This helps to prevent against malware and endpoint attacks. In short it is a security based tool to protect your computing enterprise.</p>
<p><em>Go ahead and click the image to link to their site if you wish to learn more about how it works. For me, the nitty gritty specifics on how it works is a bit outside the scope of this article.</em></p>
<p>In short, Bit9 records a record of every filename and every filepath for every client machine. It stores these in a database in SQL Server. This shouldn&#8217;t be too much of an issue. For one instance serving about 300 client machines we saw about 1.2 million paths being stored. One another instance with far fewer clients and far fewer actual paths on those clients (physically checked) we had 114 million paths stored in the database. The difference in size was 20GB vs ~160GB. When the server is installed with all defaults, you can imagine how this looked for this instance &#8211; a very bloated OS volume.</p>
<p>Investigating this issue from a database perspective, I looked to find what was consuming so much space in the database. To do that, I ran my <a href="http://bit.ly/tablespacer6">tablespace</a> script and discovered the following:</p>
<p><img loading="lazy" class="size-large wp-image-3618 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl-1024x185.png" alt="bit9_tablespacehl" width="560" height="101" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl-1024x185.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl-300x54.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl-768x138.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl-50x9.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_tablespacehl.png 1026w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>A significant standout there with the pathnames table. Looking at the definition of the table I see something far more interesting and disturbing all at once.</p>
<p><img loading="lazy" class="size-large wp-image-3620 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table-1024x785.png" alt="pathnames_table" width="560" height="429" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table-1024x785.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table-300x230.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table-768x589.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pathnames_table.png 1242w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>I see a table with three columns and two large string fields. Each of these fields has a non-clustered index on it. This may or may not be such a big problem (other than the fact that the size of the non-clustered indexes on this table are much larger than the data) except that each of the string fields is an exact duplicate of the other. That&#8217;s right. Within this table, the data is duplicated into this second string field and each field has its own index. Not only does it appear that I have a ton of duplicated data, it appears I have entirely useless indexes (neither had been touched for a read since the server had been up)</p>
<p>I inquired about this to the folks at Bit9, both from a design perspective and from an archival perspective. Absolute silence on the design (expected). The inquiry about archival (or purge) of non-essential data did fetch a response &#8211; albeit a painfully slow response. The basic question is: &#8220;Is it safe to purge or archive old or unnecessary data.&#8221; The response we received was &#8220;run this and we will tell you what to do next.&#8221;</p>
<p>Great, they sent a script to help determine the state of data within the database. I am not posting their script here. Suffice it to say that the script they sent was not very pretty. They query about 20 tables, union the results from those tables, then perform a not in operation to see how many of the pathnames are invalid. No problem. Executing the script did reveal the following:</p>
<p><img loading="lazy" class="aligncenter wp-image-3621 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/orphan_result-1024x61.png" alt="orphan_result" width="560" height="33" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/orphan_result-1024x61.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/orphan_result-300x18.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/orphan_result-768x46.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/orphan_result-50x3.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>There seems to be the problem. 95.89% of the rows being stored in the pathnames table are orphaned records! This is a bit of a problem. The software does not appear to manage removal of invalid paths. From here, I knew what the course of action needed to be and acted on it. A big piece of the equation was provided from the results of the script. Another piece was provided in the makeup of the script. From these pieces of information, I created a purge script to help manage the orphan problem. I then put that script into an agent job and set it to run on a weekly basis.</p>
<p>If you find yourself in the same boat, here is the script needed to purge the data. If running this, I recommend disabling the two non-clustered indexes and then performing the delete (especially if you sit at 96% orphaned and over 100 million rows). After deleting the mass amount of orphans, go ahead and rebuild the indexes to stay in compliance with the software contract until Bit9 responds about the index requirement and the schema of the table.</p><pre class="urvanov-syntax-highlighter-plain-tag">-- select count(1) from [dbo].[OrphanedPathnameIds] (nolock)
CREATE TABLE #pathname ( pathname_id BIGINT );
GO

INSERT INTO #pathname
		( pathname_id
		)
		SELECT pathname_id
			FROM dbo.pathnames
			WHERE pathname_id NOT IN (
				SELECT DISTINCT pathname_id
					FROM dbo.antibodies
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.antibody_instances
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.antibody_instances_deleted
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.antibody_instance_groups
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.temp_antibody_instances
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.processing_temp_antibody_instances1
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.processing_temp_antibody_instances2
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.processing_temp_antibody_instances3
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT old_pathname_id
					FROM dbo.temp_antibody_instances
					WHERE old_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT old_pathname_id
					FROM dbo.processing_temp_antibody_instances1
					WHERE old_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT old_pathname_id
					FROM dbo.processing_temp_antibody_instances2
					WHERE old_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT old_pathname_id
					FROM dbo.processing_temp_antibody_instances3
					WHERE old_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.antibody_instances_snapshots
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.approval_requests
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.internal_events
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT process_pathname_id
					FROM dbo.internal_events
					WHERE process_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT process_pathname_id
					FROM dbo.events
					WHERE process_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT process_pathname_id
					FROM dbo.remote_events
					WHERE process_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT process_pathname_id
					FROM dbo.remote_internal_events
					WHERE process_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT process_pathname_id
					FROM dbo.approval_requests
					WHERE process_pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.events
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.remote_events
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.remote_internal_events
					WHERE pathname_id IS NOT NULL
				UNION
				SELECT DISTINCT file_path_id
					FROM dbo.notification_files
					WHERE file_path_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_path_id
					FROM dbo.notification_files
					WHERE proc_path_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_path_id
					FROM dbo.notification_directories
					WHERE proc_path_id IS NOT NULL
				UNION
				SELECT DISTINCT dir_path_id
					FROM dbo.notification_directories
					WHERE dir_path_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_path_id
					FROM dbo.notification_regkeys
					WHERE proc_path_id IS NOT NULL
				UNION
				SELECT DISTINCT pathname_id
					FROM dbo.uploaded_files
					WHERE pathname_id IS NOT NULL );
GO

CREATE TABLE #filenames ( filename_id BIGINT );
GO
INSERT INTO #filenames
		( filename_id
		)
		SELECT filename_id
			FROM dbo.filenames
			WHERE filename_id NOT IN (
				SELECT DISTINCT filename_id
					FROM dbo.antibodies
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.antibody_instances
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.antibody_instances_deleted
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.antibody_instance_groups
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.temp_antibody_instances
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.processing_temp_antibody_instances1
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.processing_temp_antibody_instances2
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.processing_temp_antibody_instances3
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT old_filename_id
					FROM dbo.temp_antibody_instances
					WHERE old_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT old_filename_id
					FROM dbo.processing_temp_antibody_instances1
					WHERE old_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT old_filename_id
					FROM dbo.processing_temp_antibody_instances2
					WHERE old_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT old_filename_id
					FROM dbo.processing_temp_antibody_instances3
					WHERE old_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.antibody_instances_snapshots
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.approval_requests
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.internal_events
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.events
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT process_filename_id
					FROM dbo.internal_events
					WHERE process_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT process_filename_id
					FROM dbo.events
					WHERE process_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.remote_internal_events
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.remote_events
					WHERE filename_id IS NOT NULL
				UNION
				SELECT DISTINCT process_filename_id
					FROM dbo.remote_internal_events
					WHERE process_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT process_filename_id
					FROM dbo.remote_events
					WHERE process_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT process_filename_id
					FROM dbo.approval_requests
					WHERE process_filename_id IS NOT NULL
				UNION
				SELECT DISTINCT file_name_id
					FROM dbo.notification_files
					WHERE file_name_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_name_id
					FROM dbo.notification_files
					WHERE proc_name_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_name_id
					FROM dbo.notification_directories
					WHERE proc_name_id IS NOT NULL
				UNION
				SELECT DISTINCT proc_name_id
					FROM dbo.notification_regkeys
					WHERE proc_name_id IS NOT NULL
				UNION
				SELECT DISTINCT filename_id
					FROM dbo.uploaded_files
					WHERE filename_id IS NOT NULL );

GO


--select *
DELETE fn
	FROM #filenames f
		INNER JOIN dbo.filenames fn
			ON f.filename_id = fn.filename_id;


SELECT TOP 5000000 p.pathname_id
	INTO #presel
	FROM #pathname p;

--select *
DELETE pn
	FROM #presel p
		INNER JOIN pathnames pn
			ON p.pathname_id = pn.pathname_id;

DELETE pn
	FROM #presel p
		INNER JOIN #pathname pn
			ON p.pathname_id = pn.pathname_id;

DROP TABLE #presel;
DROP TABLE #pathname;
DROP TABLE #filenames;</pre><p>Yep! It is just like that. The worst part of the whole thing is actually the delete. The delete operation will touch about 37 indexed views to update and delete. Be prepared for a long running process if you have a situation like I encountered.</p>
<p>For kicks, here is what that plan would look like in one of my favorite tools (SQL Sentry Plan Explorer).</p>
<p><img loading="lazy" class="aligncenter size-large wp-image-3624" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan-1024x736.png" alt="bit9_deleteplan" width="560" height="403" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan-1024x736.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan-300x216.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan-768x552.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/bit9_deleteplan.png 1600w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>What is your pain scale and story?</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-3625" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/pain_scale.png" alt="pain_scale" width="797" height="291" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/pain_scale.png 797w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pain_scale-300x110.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pain_scale-768x280.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/pain_scale-50x18.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3599" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/05/sql-agent-job-schedules-2/">BIT9 PathNames</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/05/sql-agent-job-schedules-2/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #081: Sharpen Something &#8211; Reminder</title>
		<link>https://jasonbrimhall.info/2016/08/02/t-sql-tuesday-081-sharpen-something-reminder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-081-sharpen-something-reminder</link>
					<comments>https://jasonbrimhall.info/2016/08/02/t-sql-tuesday-081-sharpen-something-reminder/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 02 Aug 2016 17:04:56 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3611</guid>

					<description><![CDATA[<p>This month I am asking you to not only write a post but to do a little homework - first. In other words, plan to do something, carry out that plan, and then write about the experience.</p>
The post <a href="https://jasonbrimhall.info/2016/08/02/t-sql-tuesday-081-sharpen-something-reminder/">T-SQL Tuesday #081: Sharpen Something – Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Sharpen Something</h3>
<p><img loading="lazy" class="alignleft wp-image-3590" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png" alt="sqlskillsharpener_pig" width="116" height="178" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png 391w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-196x300.png 196w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-33x50.png 33w" sizes="(max-width: 116px) 85vw, 116px" />Last week I sent out the invite for the August TSQL Tuesday blog party. In that invite I promised to send out a reminder seven days prior to the event. Well &#8211; it is that time.</p>
<p>You are cordially invited to <a href="http://bit.ly/2aaRDwR">read the invite for TSQL Tuesday 81</a> and plan your entry for the party.</p>
<p>In the invite, I shared the details for the event including examples of what I am looking for as an entry for the event.</p>
<p>I hope we will be seeing you next Tuesday, August 9th in attendance at this month&#8217;s party. I am sure it will prove to be an interesting experience one way or another.</p>
<h3>Bonus Example</h3>
<p>In the original invite I provided a list of examples of what one could do for this TSQL Tuesday. Today, I am providing one more example in a slightly different format. Recall that the invite requested that participants set out to accomplish something, make a plan and report on that &#8220;goal&#8221;, the plan, and the outcome.</p>
<p>So, let&#8217;s say I have discovered that I write too much in the passive voice. Based on that information, I would like to overcome the passivity in my writing voice, therefore my goal would be to learn how to write more assertively (less passively). In order to accomplish that goal, I may need to read up on the topic and learn exactly what it means to write passively. Then I would need to examine articles that I have written. And then I would need to practice writing more assertively. After all of that is done, I may have somebody (or something) analyze a brand new article or two to determine if I have achieved my desire.</p>
<p>After having executed on that plan, I will write about the experience including what the initial goal and plan were and also on what worked or didn&#8217;t work while trying to reach that goal. To summarize, here is an outline of that example:</p>
<h4>What I will Accomplish</h4>
<p>I will learn how to write more assertively (or just Write more assertively)</p>
<h4>How Will I do that</h4>
<p>Research what it means to write passively</p>
<p>Research what it means to write assertively</p>
<p>Evaluate &#8220;assertively&#8221; written articles</p>
<p>Take Notes on how to write assertively</p>
<p>Evaluate my articles</p>
<p>Practice writing assertively</p>
<p>Write a new article and have it reviewed to judge the voice whether it seems too passive or not</p>
<h4>Report on The Successes and Failures</h4>
<p>Write whether or not each step succeeded or failed.</p>
<p>Write if a step was unnecessary</p>
<p>Write about the experience and your thoughts about the experience.</p>
<p>Did you achieve or fail overall?</p>
<h3>What is T-SQL Tuesday?</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Adam Machanic on his blog.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday, Août 9e, 2016, and 00:00 GMT Wednesday Août 10e, 2016.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3611" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/02/t-sql-tuesday-081-sharpen-something-reminder/">T-SQL Tuesday #081: Sharpen Something – Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/02/t-sql-tuesday-081-sharpen-something-reminder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Easily Shred Event Data</title>
		<link>https://jasonbrimhall.info/2016/08/01/easily-shred-event-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=easily-shred-event-data</link>
					<comments>https://jasonbrimhall.info/2016/08/01/easily-shred-event-data/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 01 Aug 2016 12:01:06 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3595</guid>

					<description><![CDATA[<p>Parsing XML is the epitome of salt in a wound for a DBA. Parsing the XML from Extended Events need not be so painful. Read further to discover how to remove the pain from the task of XML parsing.</p>
The post <a href="https://jasonbrimhall.info/2016/08/01/easily-shred-event-data/">Easily Shred Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="wp-image-3596 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/shred_xe.png" alt="shred_xe" width="234" height="251" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/shred_xe.png 714w, https://jasonbrimhall.info/wp-content/uploads/2016/07/shred_xe-279x300.png 279w, https://jasonbrimhall.info/wp-content/uploads/2016/07/shred_xe-46x50.png 46w" sizes="(max-width: 234px) 85vw, 234px" />It has been nearly a year since I started an extensive series about Extended Events. Previous to that start, I had already written a bunch of articles about Extended Events.</p>
<p>Among the batch of articles preceding the 60 day series one can find an article about shredding extended event data. Then as a part of the series (the first article in the 60 day series) one can find how to shred the action payload data attached to an extended event session.</p>
<p>You can read the article on shredding XEvent payload data <a href="http://bit.ly/1Jvy9uM">here</a>. Then you can follow that up by reading how to shred the Action data <a href="http://bit.ly/1ig9HYJ">here</a>. And once you are done with those and you really want to learn more about Extended Events, please read the whole series which can be <a href="http://bit.ly/XE60Days">found here</a>.</p>
<p>All of that reading to catch up should keep you busy for a tad bit.</p>
<h3>Upgrade</h3>
<p>A year is a really long time to go without updating a script &#8211; according to some. Today, I have an update for both of the XML shredding scripts you just read about in the list of articles mentioned moments earlier in this post.</p>
<p>Before I dive into the script, let&#8217;s revisit a sample of the XML from an event session payload. Within an event session, you can see that there are nodes for both the data and the actions (highlighted in green and red). With all of this information found within the same XML for the session, it somewhat makes sense to try and parse all of the data at once.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml.png"><img loading="lazy" class="alignnone wp-image-2835 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml.png" alt="action_xml" width="939" height="588" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml.png 939w, https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml-300x188.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml-50x31.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>In addition to parsing all of the XML for the data and the actions at the same time, it seems to also make sense to generate the statements that would parse the XML within a single effort. As you would have noted, my previous scripts were just that &#8211; <em>scripts</em>. That implies executing a separate script for each the data and the actions. Maybe it would make more sense to execute a single script.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/07/leaving_pain.png"><img loading="lazy" class="alignright wp-image-3603" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/leaving_pain.png" alt="leaving_pain" width="184" height="183" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/leaving_pain.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/07/leaving_pain-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/07/leaving_pain-50x50.png 50w" sizes="(max-width: 184px) 85vw, 184px" /></a>It is that notion of a single script that constitutes this upgraded version of the script.</p>
<h3>One Script</h3>
<p>In the following script, I have tried to accomplish just that &#8211; a single script to create the entire XML parser for me, for you, and for anybody wishing to use it. I don&#8217;t want to have to remember the subtle nuances of how to parse each of the events each time I need to parse the session data. I want something that is quick, easy, and repeatable.</p>
<p>With all of that said, here is the script that I now use to parse my session data. You should notice that it has been simplified and is more extensive now.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = NULL --'query_post_execution_showplan'--'sp_statement_completed'
	,@ReadFlag VARCHAR(64) = 'readonly' --NULL if all columntypes are desired
	,@SessionName	VARCHAR(128) = 'AuditDeprecated' --'system_health' --NULL if all Sessions are desired --'Deadlock' --NULL
	,@UniqueEventColumns	TINYINT = 1 --1 for unique payload columns across all events within the session, NULL for all columns in session
	,@UniqueActions TINYINT = 1 --1 for unique actions, NULL for all actions in the session

/*gen tsql to parse session payload */
SELECT '/* parse the data */
IF EXISTS (SELECT OBJECT_ID(''tempdb.dbo.#xmlprocess''))
BEGIN
DROP TABLE #xmlprocess
END

SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.event_session_id--, '' AS event_predicate
	INTO #xmlprocess
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),''.xel'',''*.xel'') AS targetvalue, ses.event_session_id
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					--INNER JOIN sys.server_event_session_events sese
					--	ON ses.event_session_id = sese.event_session_id
				WHERE sesf.name = ''filename''
					AND ses.name = ''' + @SessionName +'''
					) cte1
				OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;


SELECT x.event_data.value(''(event/@name)[1]'', ''varchar(50)'') AS event_name
		, x.event_data.value(''(event/@package)[1]'', ''varchar(50)'') AS package_name
		, DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP),
					x.event_data.value(''(event/@timestamp)[1]'',
										''datetime2'')) AS [timestamp]';

WITH presel AS (
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,',event_data.value(''(event/data[@name="' + oc.name + '"]/value)[1]'',''' + 
			CASE 
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name = 'guid'
				THEN 'uniqueidentifier'
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name = 'boolean'
				THEN 'bit'
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name = 'callstack'
				THEN 'varchar(max)'
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name &lt;&gt; 'unicode_string'
					AND oc.type_name &lt;&gt; 'ansi_string'
					AND oc.type_name &lt;&gt; 'ptr'
					AND oc.type_name NOT LIKE '%int%'
				THEN oc.type_name
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name LIKE '%int%'
				THEN 'bigint'
				ELSE 'varchar(max)' END + ''') AS ' + oc.name + '' AS ColumnXML
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,ca.map_value AS SearchKeyword
		,sesea.SessionName
		,rownum = ROW_NUMBER() OVER (PARTITION BY sesea.SessionName, oc.name ORDER BY oc.object_name)
	FROM sys.dm_xe_object_columns oc
	-- do we have any custom data types
		OUTER APPLY (SELECT DISTINCT mv.name FROM sys.dm_xe_map_values mv
			WHERE mv.name = oc.type_name
			AND mv.object_package_guid = oc.object_package_guid) xmv
	--just get the unique events that are tied to a session on the server (stopped or started state)
		CROSS APPLY (SELECT DISTINCT sese.name,ses.name AS SessionName
						FROM sys.server_event_session_events sese
							INNER JOIN sys.server_event_sessions ses
								ON sese.event_session_id = ses.event_session_id) sesea
	--keyword search phrase tied to the event
		CROSS APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = oc.object_name) ca
	WHERE oc.column_type &lt;&gt; @ReadFlag
		AND sesea.name = oc.object_name
		AND oc.object_name = ISNULL(@EventName,oc.object_name)
		AND sesea.SessionName = ISNULL(@SessionName,sesea.SessionName)
)

SELECT p.EventName
	 , p.column_name
	 , p.type_name
	 , p.ColumnXML
	 , p.column_type
	 , p.column_value
	 , p.column_description
	 , p.SearchKeyword
	 , p.SessionName
	FROM presel p
	WHERE p.rownum = ISNULL(@UniqueEventColumns,p.rownum)
	ORDER BY p.SessionName,p.EventName
	;

/* auto generate the xml associated to an event session action deployed to the server */
WITH presel AS (
	SELECT p.name AS package_name
	        ,o.name AS action_name
			,',event_data.value(''(event/action[@name="' + esa.name + '"]/value)[1]'', ''' + 
			CASE 
				WHEN o.type_name = 'guid'
				THEN 'uniqueidentifier'
				WHEN o.type_name = 'boolean'
				THEN 'bit'
				WHEN o.type_name = 'binary_data'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'callstack'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'filetime'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'cpu_cycle'
				THEN 'varbinary(max)'
				WHEN ISNULL(o.type_name,'') = ''
				THEN NULL
				WHEN o.type_name &lt;&gt; 'unicode_string'
					AND o.type_name &lt;&gt; 'ansi_string'
					AND o.type_name &lt;&gt; 'ptr'
					AND o.type_name NOT LIKE '%int%'
				THEN o.type_name
				WHEN o.type_name LIKE '%int%'
				THEN 'int'
				ELSE 'varchar(max)' END + ''') AS ' + esa.name +'' AS ActionXML
			,ses.name AS EventSessionName
			, ese.name AS EventName
	        ,o.description
			, rownum = ROW_NUMBER() OVER (PARTITION BY ses.name,o.name ORDER BY ese.name)
	FROM sys.dm_xe_packages AS p
		INNER JOIN sys.dm_xe_objects AS o
			ON p.guid = o.package_guid
		INNER JOIN sys.server_event_session_actions esa
			ON o.name = esa.name
		INNER JOIN sys.server_event_sessions ses
			ON esa.event_session_id = ses.event_session_id
		INNER JOIN sys.server_event_session_events ese
			ON esa.event_session_id = ese.event_session_id
			AND ese.event_id = esa.event_id
	WHERE o.object_type = 'action'
		AND (o.capabilities IS NULL OR o.capabilities &amp; 1 = 0)
		AND (p.capabilities IS NULL OR p.capabilities &amp; 1 = 0)
		AND ese.name = ISNULL(@EventName,ese.name)
		AND ses.name = ISNULL(@SessionName,ses.name)
)
SELECT p.package_name
	 , p.action_name
	 , p.ActionXML
	 , p.EventSessionName
	 , p.EventName
	 , p.description
	FROM presel p
	WHERE p.rownum = ISNULL(@UniqueActions,p.rownum)
	ORDER BY p.EventSessionName, p.action_name, p.EventName
	;

/* gen last piece of xml parsing sql code block*/
SELECT '	FROM #xmlprocess x
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON x.event_data.value(''(event/@name)[1]'', ''varchar(50)'') = sese.name
				AND x.event_session_id = sese.event_session_id
	ORDER BY timestamp
		, event_data.value(''(event/action[@name="event_sequence"]/value)[1]'',
							''varchar(max)'');'</pre><p>Not only does this script slice and dice for you&#8230;Wait that&#8217;s not quite right.</p>
<p>This script doesn&#8217;t just generate the XML shredding strings for the payload and action data. This script also will produce the rest of the tsql statements that should precede and conclude the XML parsing statements. Yes it uses dynamic sql. That is to your advantage in this case.</p>
<p>Could there be other enhancements? Absolutely! More will be coming.</p>
<p>Enjoy this script and happy parsing.</p>
<h3>Extra Extra &#8211; Read All About It!</h3>
<p>From the comments, you will see that Brent Ozar (<a href="https://www.brentozar.com/">blog </a>| <a href="https://twitter.com/BrentO/">twitter</a>) made an excellent suggestion. To be honest, I considered sharing some examples during the initial write of this article. I had opted against it then, not considering it in the same way that Brent puts it. So, in this addendum I have a quick example using an XEvent Session that I have not yet written about in all of my articles on <a href="http://bit.ly/sqlRnnrXE">Extended Events</a> (pseudo spoiler alert).</p>
<p>Let&#8217;s use the AuditSelects XEvent Session I have deployed and running (remember a session can be deployed but may be in the &#8220;stopped&#8221; state). If I want to figure out what data has been captured for this session, I can take the session name and plug it into the script shown in this article.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params.png"><img loading="lazy" class="size-large wp-image-3606 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params-1024x157.png" alt="parsexe_params" width="560" height="86" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params-1024x157.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params-300x46.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params-768x118.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsexe_params.png 1251w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Ignore the green tsql comments for now (you can read them direct from the script). Highlighted in gold is the variable for the session name. By entering a valid session name for this variable, I can restrict the results to just the metadata for that specific session. In addition, note that I have highlighted, in a pale chartreuse, two variables that will give me unique column names for each of the events and actions within each session. This is important because some events have the same name for different attributes as other events. If events with the same attribute names are used in the same session, you will get a duplication of data. Maybe you want the duplicate data. Maybe you don&#8217;t.</p>
<p>The session name variable is used in each of the next three code segments. Each segment in the script will generate sql statements that will need to be copied into a new query window. I will leave the further breakdown of the script as an exercise for you. What I want to do here is show the results from executing this script.</p>
<p>When I execute the script, I will have four result sets returned to me (in grid mode). It will look something like shown in the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results.png"><img loading="lazy" class="size-large wp-image-3607 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results-1024x510.png" alt="parser_results" width="560" height="279" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results-1024x510.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results-300x150.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results-768x383.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parser_results-50x25.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Breaking this down into three colors is probably easiest to see how things fit together. Highlighted in red, I have the build out of the pre-processing statements and the build of the &#8220;select&#8221; statement that will be returning our data to us. Then in blue comes the guts of the query &#8211; all of the beautiful XML parsing statements. The segments in blue correlates to the columns in the select list. And at the bottom of the image I have the finishing pieces that includes my predicates, from, and joins. Each of the highlighted segments will then be copied and pasted to a new query window and look something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether.png"><img loading="lazy" class="size-large wp-image-3608 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether-1024x783.png" alt="parsed_gluedtogether" width="560" height="428" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether-1024x783.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether-300x229.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether-768x587.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/08/parsed_gluedtogether.png 1621w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>And there you have it. Sure there are still some manual steps in it, but you no longer need to memorize all of that glorious XML parsing syntax. You only need to copy and paste with this version of the script.</p>
<p>Enjoy your adventures in parsing XML!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3595" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/08/01/easily-shred-event-data/">Easily Shred Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/08/01/easily-shred-event-data/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #081: Sharpen Something</title>
		<link>https://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-081-sharpen-something</link>
					<comments>https://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 27 Jul 2016 23:46:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3589</guid>

					<description><![CDATA[<p>This month I am asking you to not only write a post but to do a little homework - first. In other words, plan to do something, carry out that plan, and then write about the experience.</p>
The post <a href="https://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/">T-SQL Tuesday #081: Sharpen Something</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Sharpen Something</h3>
<p>It has now been 30 months since the last time I hosted a TSQL Tuesday, that was TSQL Tuesday 51. I <a href="http://bit.ly/1oQkFTz">recapped that event here</a> with the <a href="http://bit.ly/1ikg6fJ">original invite here</a>. I can&#8217;t believe it has been that long since I last hosted. It only seems like yesterday.</p>
<p><img loading="lazy" class="alignleft  wp-image-3590" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png" alt="sqlskillsharpener_pig" width="169" height="259" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig.png 391w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-196x300.png 196w, https://jasonbrimhall.info/wp-content/uploads/2016/07/sqlskillsharpener_pig-33x50.png 33w" sizes="(max-width: 169px) 85vw, 169px" />Coming into the present day, we are now at TSQL Tuesday 81. For this month, I would like to try and up the ante a bit. Usually we only get about a weeks notice prior to the event to think about the article to write for the event.</p>
<p>This time, I want to invite everybody just a little bit sooner and will follow-up with a reminder seven days prior to the event. The reason I want to do this is because I think this may be a touch more difficult this time.</p>
<p>&nbsp;</p>
<p>This month I am asking you to not only write a post but to do a little homework &#8211; <em>first</em>. In other words, plan to do something, carry out that plan, and then write about the experience. There is a lot going into that last sentence. Because of that, let me try to explain through a few examples of what I might like to see. Hopefully these examples will help you understand the intent and how this month the topic relates to &#8220;<strong>Sharpening Something</strong>&#8220;.</p>
<h2 style="text-align: left;">EXAMPLES</h2>
<ol>
<li>You have learned about a really cool feature called <a href="https://azure.microsoft.com/en-us/services/devtest-lab/">Azure DevTest Lab</a>. Having heard about it, you wish to implement this feature to solve some need in your personal development or corporate environment. Develop a plan to implement the feature and tell us the problem it solves and about your experiences in getting it to work from start to end. <em>An example of how I might try to use this might involve the creation of a disposable and easy setup environment for Precons, Workshops, and various other types of training.</em></li>
<li>There is a really awesome book about SQL Server you heard about and you decided to buy it. Plan to sit down and read the book. Take a nugget or two from the book and tell us how you can use that nugget of information within your personal or professional environment.</li>
<li>You know you are extremely deficient at a certain SQL Skill. Tell me what that skill is and develop a plan to get better at that skill. Report on the implementation of this skill and how you are doing at improving. Maybe that skill is about Extended Events, PoSH or availability groups.</li>
<li>Similar to the skill deficiency, you know you do not understand a certain concept within SQL Server as well as you feel you should. Maybe that concept is indexing or statistics (for example). Create a two week plan to become more proficient at that concept. Follow that plan and report on your progress.</li>
</ol>
<p>In recap, this is an invite to make a short term goal covering the next two weeks. Tell everybody what that goal is (in your tsql tuesday post of course) and how you went about creating a plan for that goal and how you have progressed during the two week interval.</p>
<h3>What is T-SQL Tuesday?</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg"><img loading="lazy" class="alignright wp-image-1969 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Adam Machanic on his blog.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday, Août 9e, 2016, and 00:00 GMT Wednesday Août 10e, 2016.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3589" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/">T-SQL Tuesday #081: Sharpen Something</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/07/27/t-sql-tuesday-081-sharpen-something/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>Another Query to Help Find the Right Event</title>
		<link>https://jasonbrimhall.info/2016/07/21/another-query-to-help-find-the-right-event/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=another-query-to-help-find-the-right-event</link>
					<comments>https://jasonbrimhall.info/2016/07/21/another-query-to-help-find-the-right-event/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 21 Jul 2016 19:30:26 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3559</guid>

					<description><![CDATA[<p>Finding the right event or combination of events to monitor may seem like quite a daunting task with so many events to explore and (frequently) too little familiarity with Extended Events.</p>
The post <a href="https://jasonbrimhall.info/2016/07/21/another-query-to-help-find-the-right-event/">Another Query to Help Find the Right Event</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Finding the right event or combination of events to monitor may seem like quite a daunting task with so many events to explore and <img loading="lazy" class="wp-image-3556 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing.png" alt="xvnt_crossing" width="173" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing-50x50.png 50w" sizes="(max-width: 173px) 85vw, 173px" />(frequently) too little familiarity with Extended Events. In this follow-up article to <a href="http://bit.ly/2arQWit">Extended Event Help Queries</a>, I will share another means to quickly explore the Extended Events metadata in the effort to find the precise event to fit your needs.</p>
<p>Today I will be sharing a new query or two that I have used on more than one occasion to help track down the event(s) that I wanted to, at least, try while troubleshooting specific problems within the SQL Server Instance. I found these queries useful once again in a recent opportunity to help out some friends from the SQL Community. (Maybe, just maybe, these are really just a spin of other previously shared queries.) I will share the most recent experience in another follow-up post.</p>
<p>For the sake of posterity, I am also adding this to the <a href="http://bit.ly/XE60Days">60 Days of Extended Events Table of Contents</a>.</p>
<h3>Is There an Event that Contains pertinent Data?</h3>
<p>In my previous article I demonstrated how to find an event based solely on the name or description of the event. This is fantastic if the event name (or description) contains one of the magical words you have used. What if the event name or description has nothing to do with the terms you selected? Or, what if the data you seek may be attached to the event but wouldn&#8217;t necessarily stand out as a description for that event (by name or description details for that event)?</p>
<p>Now comes the more difficult task right? If the name or description of the event doesn&#8217;t relate to the search terms then you just might overlook a few events and be stuck trying to troubleshoot a problem. An equally big problem this could cause is yet another invisible barrier to using Extended Events. It would be easy to slide down the slippery slope and not transition to Extended Events just because an event, applicable to the problem at hand, could not be found.</p>
<p>This is where searching on the payload comes in handy. Remember from a <a href="http://bit.ly/1K1F2Yg">previous article</a> that the payload is the event data that is attached to each event. Imagine how much more accurate we can become by extending our search from the name and description of the event object to next search on the payload names and descriptions? That is exactly what I will now show.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @TermDescription VARCHAR(64) = 'Select'
	, @ColumnDesc VARCHAR(64) = 'statement'
	, @ReadFlag VARCHAR(64) = NULL; --readonly' --ALL if all columntypes are desired --data --customizable
 
SELECT oc.object_name AS EventName
		, oc.name AS column_name
		, oc.type_name
		, oc.column_type AS column_type
		, oc.column_value AS column_value
		, oc.description AS column_description
		, ca.map_value AS SearchKeyword
		, oc.column_type
	FROM sys.dm_xe_object_columns oc
		CROSS APPLY ( SELECT mv.map_value
							FROM sys.dm_xe_object_columns occ
								INNER JOIN sys.dm_xe_map_values mv
									ON occ.type_name = mv.name
										AND occ.column_value = mv.map_key
										AND occ.object_package_guid = mv.object_package_guid
							WHERE occ.name = 'KEYWORD'
								AND occ.object_name = oc.object_name
					) ca
	WHERE (oc.object_name = @TermDescription
		OR oc.description LIKE '%' + ISNULL(@ColumnDesc,@TermDescription) + '%')
		AND oc.column_type = ISNULL(@ReadFlag, oc.column_type)
	ORDER BY EventName, column_name;

GO</pre><p>Basically, I am searching against the object_columns metadata dmv for Extended Events just to find any columns that match my theoretical needs. In this case, I am trying to find anything that may help me find events related to the terms &#8220;select&#8221; or &#8220;statement&#8221;. When run, there will be quite a few results for these terms. That may actually be a bit of a problem (just the same as if nothing were returned in the results). There is a fix for that (well probably several fixes as you begin to tweak the query).</p>
<p>One possible fix is to also include map_values to refine the search. Another fix might be to change the search terms. And still other fixes might include tweaking the predicate. For today, I am going to demonstrate the inclusion of map_values as a secondary tweak to help isolate the needed event.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @TermDescription VARCHAR(64) = 'Select'
	, @ColumnDesc VARCHAR(64) = 'statement'
	, @ReadFlag VARCHAR(64) = NULL; --readonly' --ALL if all columntypes are desired --data --customizable
 
SELECT oc.object_name AS EventName
		, oc.name AS column_name
		, oc.type_name
		, oc.column_type AS column_type
		, oc.column_value AS column_value
		, oc.description AS column_description
		, ca.map_value AS SearchKeyword
		, mv.map_value AS MapValue
		, mv.map_key AS MapKey
		, oc.column_type
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND mv.object_package_guid = oc.object_package_guid
		CROSS APPLY ( SELECT mv.map_value
							FROM sys.dm_xe_object_columns occ
								INNER JOIN sys.dm_xe_map_values mv
									ON occ.type_name = mv.name
										AND occ.column_value = mv.map_key
										AND occ.object_package_guid = mv.object_package_guid
							WHERE occ.name = 'KEYWORD'
								AND occ.object_name = oc.object_name
					) ca
	WHERE (oc.object_name = @TermDescription
		OR oc.description LIKE '%' + ISNULL(@ColumnDesc,@TermDescription) + '%')
		AND mv.map_value = @TermDescription
		AND oc.column_type = ISNULL(@ReadFlag, oc.column_type);</pre><p>In this iteration, my result-set is trimmed significantly due to the predicate and the requirement for a match based on the map_value name. Ultimately, this trimmed my results down to precisely the events that I needed in this case. With this slightly more advanced version, I have greater visibility into the Extended Event realm to help me find just the right event to match my needs.</p>
<h3>Are there other Events related to the new found Event?</h3>
<p>&nbsp;</p>
<p>This is some pretty awesome stuff so far. But it doesn&#8217;t end right there. Many events are tied together to help provide a more holistic view of the problem. These events are tied together via keyword. You can read more about keywords <a href="http://bit.ly/1KDJrUP">here</a>. By searching for events based on a keyword, we can get a lot more intelligent about the sessions we create with Extended Events.</p>
<p>Taking the single result from the last query and then using the SearchKeyword value, for that event, in this next query &#8211; I can potentially go from a Great DBA to a Super DBA.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @Keyword VARCHAR(64) = 'execution' --'synchronization'
 
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,olm.file_version
		,xp.name AS PackageName
		,mv.map_value AS SearchKeyword
		,ch.Channel
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_map_values mv
			ON oc.type_name = mv.name
			AND oc.column_value = mv.map_key
			AND oc.name = 'KEYWORD'
		INNER JOIN sys.dm_xe_packages xp
			ON oc.object_package_guid = xp.guid
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = oc.object_name
			AND ch.PkgGuid = oc.object_package_guid
	WHERE mv.map_value = @Keyword
	ORDER BY EventName
	;
GO</pre><p>I intentionally included the columns from each of the matching events. Doing this, I can also see what potential payload may be trapped when I attempt to trap any of the events from this result set.</p>
<h3>Conclusion</h3>
<p>There is great power in Extended Events. There is more power in being able to query the metadata for Extended Events in order to trap the appropriate information to properly troubleshoot a problem.</p>
<p>Have fun with these scripts and I hope you enjoy.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3559" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/07/21/another-query-to-help-find-the-right-event/">Another Query to Help Find the Right Event</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/07/21/another-query-to-help-find-the-right-event/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Event Help Queries</title>
		<link>https://jasonbrimhall.info/2016/07/19/extended-event-help-queries/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-event-help-queries</link>
					<comments>https://jasonbrimhall.info/2016/07/19/extended-event-help-queries/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 19 Jul 2016 21:37:36 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2708</guid>

					<description><![CDATA[<p>When working with Extended Events, there are times when a little more information is, well, helpful.  You know you want to use extended events to try and monitor for a specific thing to happen.</p>
The post <a href="https://jasonbrimhall.info/2016/07/19/extended-event-help-queries/">Extended Event Help Queries</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>When working with Extended Events, there are times when a little more information is, well, helpful.  You know you want to use extended events to try and monitor for a specific thing <img loading="lazy" class="alignright wp-image-3556" src="http://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing.png" alt="xvnt_crossing" width="173" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing.png 225w, https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/07/xvnt_crossing-50x50.png 50w" sizes="(max-width: 173px) 85vw, 173px" />to happen.  But sometimes you don&#8217;t know if there is an event for that &#8220;thing&#8221;, or maybe you don&#8217;t know if there is a session already in place to do that specific task (or if it is even running), or maybe you just need better information about the event to see what kind of data it captures when it is fired.</p>
<p>Sometimes, this information is easy enough to find.  Sometimes, it is less than evident how to find the wanted information.  Some of the information may be visible through the GUI (if you are using SQL Server 2012 or later), and sometimes it is just flat out easier to run a quick script.  Today, I would like to share a few quick scripts to help find some of this information that can make the life of the DBA just a bit easier.</p>
<h3>Does an Event Exist?</h3>
<p>First let&#8217;s tackle the problem of discovery.  When we want to use extended events to try and troubleshoot a problem or to capture more information, it is really good to know if such an event exists.  There are many events that capture data for various different things within SQL Server.  More and more events are being added with each release.  More and more data is being made available to the DBA to help perform a better job and to help the DBA better understand what is really happening within the database environment.</p>
<p>In order to determine if there might be an event, that can provide the data for that one &#8220;thing&#8221; that may be happening within your environment, we could start by querying the SQL Server Internals.  This next query will do just that for us.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.object_name AS EventName
		,p.name AS PackageName
		,o.description AS EventDescription
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.object_name
			and o.package_guid = c.object_package_guid
		INNER JOIN sys.dm_xe_packages p
			ON o.package_guid = p.guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND (c.object_name like '%file_size%'
			or c.object_name like '%growth%')
	ORDER BY o.package_guid;</pre><p>This will query the DMVs related to Extended Events and provide us with the event names that contain the terms used in the filter / predicate.  In this case, I am looking for any events that contain the terms &#8220;growth&#8221; or &#8220;file_size&#8221;.  This is in an effort to try and find anything that might be related to database files changing sizes.  You may have seen one of the previous articles on tracking file size changes <a href="http://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">here</a> or <a href="http://bit.ly/SSGFileSizeChange">here</a>.</p>
<p>The use of the right term to try and trap the right data for the problem that is happening can greatly decrease the time required to find the correct event.  There may be a bit of an art involved in finding the correct search term.  A little practice can help improve the ability to find the appropriate event more quickly.</p>
<h3>Is the Data any Good?</h3>
<p>Knowing if an Extended Event exists for the desired problem is one thing.  Knowing what data can be parsed from that event is another thing.  Many times, we may not know what kind of data can be trapped with each of the events.  Many times, we may just not be trapping enough data.  And of course, knowing what kind of data can be trapped by the event may help us in filtering that data down to what is usable for efficient troubleshooting.</p>
<p>Finding that data is just a matter of another simple query against the DMVs.  Let&#8217;s take a look at the query that can help us find the data we need:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = 'trace_flag_changed'
	,@ReadFlag VARCHAR(64) = 'readonly' --NULL if all columntypes are desired

SELECT oc.object_name as EventName
		,oc.name AS column_name, oc.type_name,
		oc.column_type AS column_type,
		oc.column_value AS column_value,
		oc.description AS column_description
	FROM sys.dm_xe_objects AS o
		INNER JOIN sys.dm_xe_object_columns AS oc
			ON o.name = oc.object_name
			AND o.package_guid = oc.object_package_guid
	WHERE o.name = @EventName
		AND (oc.capabilities IS NULL 
				OR oc.capabilities &amp; 1 = 0)
		AND oc.column_type &lt;&gt; @ReadFlag
	   ;
GO</pre><p>In this case, I have taken the name of the event about which I want to learn more details.  In addition, I only want to retrieve the data columns that retrieve data that could change.  As you can see, I am investigating &#8220;trace_flag_changed&#8221;.  You may recall that particular event from a previous <a href="http://bit.ly/ssgflagcapture">article and you can read more about it here</a>.</p>
<p>You may also be looking at the query and thinking it seems a little overly complex for what we want.  Well, it is.  Here is an alternate version:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = 'trace_flag_changed'
	,@ReadFlag VARCHAR(64) = 'readonly' --NULL if all columntypes are desired

SELECT oc.object_name as EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description 
	FROM sys.dm_xe_object_columns oc
	WHERE oc.object_name = @EventName
		AND oc.column_type &lt;&gt; @ReadFlag
	;</pre><p>The discovery of the columns available in each event will give us some options to filter as well as some options in what kind of data we parse from the resulting event.</p>
<h3>Did I Already Create that Session?</h3>
<p>This is arguably less critical than the others.  After all, some will just drop and recreate the session.  But why drop the session if you don&#8217;t need to?  On the other hand, a quick glimpse in the GUI could also display that information.  Sadly that doesn&#8217;t work for all versions of SQL Server (e.g. SQL Server 2008).  Maybe you have the session running, or maybe it is simply created and not in the running state.</p>
<p>Finding these sessions and whether they are running or not is rather simple.  Just run this next query and it will help you figure out if the session is there or not.  All you need to do is plug in the name of the session and away you go.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(64) = 'TrackDBFileChange';

SELECT sn.SessionName
	, CASE WHEN ISNULL(es.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		End as XESessionExists
	, CASE WHEN ISNULL(xe.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		End as XESessionRunning
	FROM (Select @SessionName as SessionName) sn
		LEFT OUTER JOIN sys.server_event_sessions es
			ON sn.SessionName = es.name
		LEFT OUTER JOIN sys.dm_xe_sessions xe
			ON es.name = xe.name
	;</pre><p>This query has been confirmed to work in SQL 2008 and up through SQL 2014.  It should simplify some of the attempts to better understand what is happening with any sessions that might be out there.</p>
<p>These are a few quick and simple queries to help you along your way to becoming better acquainted with Extended Events.  I hope these will be useful to you and that you will get to know and use extended events regularly.</p>
<p><em>Update: This post is being added to the 60 day series which can be found <a href="https://xevents.jasonbrimhall.info">here</a>. While in here fixing a formatting issue that was discovered, it made sense to also include it in the ongoing library of articles on Extended Events.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2708" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/07/19/extended-event-help-queries/">Extended Event Help Queries</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/07/19/extended-event-help-queries/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Agent Job Schedules</title>
		<link>https://jasonbrimhall.info/2016/03/29/sql-agent-job-schedules/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-agent-job-schedules</link>
					<comments>https://jasonbrimhall.info/2016/03/29/sql-agent-job-schedules/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 29 Mar 2016 21:46:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Agent Job]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3477</guid>

					<description><![CDATA[<p>SQL Agent job schedules should be easy to read for humans if for nothing else than the fact that you have to provide this information to the auditors from time to time.</p>
The post <a href="https://jasonbrimhall.info/2016/03/29/sql-agent-job-schedules/">SQL Agent Job Schedules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Many moons ago, I posted a script to help report on the human friendly scheduling <a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/sched_report.png" rel="attachment wp-att-3478"><img loading="lazy" class="wp-image-3478 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/sched_report.png" alt="sched_report" width="142" height="164" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/sched_report.png 231w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sched_report-43x50.png 43w" sizes="(max-width: 142px) 85vw, 142px" /></a>information for SSRS subscriptions. You can read all about that <a href="http://bit.ly/UwcgTY">here</a>.</p>
<p>In a very similar fashion, today I want to share how easy it is to turn the internal schedules for SQL Agent jobs into something that is more human friendly. SQL Agent job schedules should be easy to read for humans if for nothing else than the fact that you have to provide this information to the auditors from time to time. We all know they can&#8217;t properly interpret the numeric job schedules and properly determine what they mean.</p>
<p>The job schedules work quite well with the current design &#8211; which is not human friendly. The use of numbers is a streamlined approach and far more efficient. It may be a bit more useful to us if there were some sort of translation table that was stored. A stored translation table would make it terribly easy to figure out what is happening within the schedules for the SQL Agent jobs. We don&#8217;t have that, so we often have to do a little trial and error. Or we rely on people that have done that trial and error &#8211; with a little verification on our part. Afterall, these scripts are posted on the internet.</p>
<h2>SQL Agent Job Schedules</h2>
<p>I am not going to break down the script. With the similarity to the aforementioned SSRS script, I would recommend looking there for a little bit of an explanation. Here is the script to retrieve SQL Agent Job Schedules from your MSDB instance.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
DECLARE @weekDay TABLE
	(
		mask INT
		, maskValue VARCHAR(32)
	);

INSERT INTO @weekDay
		SELECT 1
				, 'Sunday'
		UNION ALL
		SELECT 2
				, 'Monday'
		UNION ALL
		SELECT 4
				, 'Tuesday'
		UNION ALL
		SELECT 8
				, 'Wednesday'
		UNION ALL
		SELECT 16
				, 'Thursday'
		UNION ALL
		SELECT 32
				, 'Friday'
		UNION ALL
		SELECT 64
				, 'Saturday';

WITH	myCTE
			AS ( SELECT sched.name AS 'scheduleName'
							, sched.enabled AS SchedEnabled
							, sched.schedule_id
							, jobsched.job_id
							, CASE	WHEN sched.freq_type = 1 THEN 'Once'
									WHEN sched.freq_type = 4
											AND sched.freq_interval = 1
									THEN 'Daily'
									WHEN sched.freq_type = 4
									THEN 'Every '
											+ CAST(sched.freq_interval AS VARCHAR(5))
											+ ' days'
									WHEN sched.freq_type = 8
									THEN REPLACE(REPLACE(REPLACE(( SELECT maskValue
																FROM @weekDay AS x
																WHERE sched.freq_interval
																&amp; x.mask &lt;&gt; 0
																ORDER BY mask
																FOR
																XML RAW
																),
																'"/&gt;&lt;row maskValue="',
																', '),
															'&lt;row maskValue="',
															''), '"/&gt;', '')
											+ CASE	WHEN sched.freq_recurrence_factor &lt;&gt; 0
															AND sched.freq_recurrence_factor = 1
													THEN '; weekly'
													WHEN sched.freq_recurrence_factor &lt;&gt; 0
													THEN '; every '
															+ CAST(sched.freq_recurrence_factor AS VARCHAR(10))
															+ ' weeks'
												END
									WHEN sched.freq_type = 16
									THEN 'On day '
											+ CAST(sched.freq_interval AS VARCHAR(10))
											+ ' of every '
											+ CAST(sched.freq_recurrence_factor AS VARCHAR(10))
											+ ' months'
									WHEN sched.freq_type = 32
									THEN CASE	WHEN sched.freq_relative_interval = 1
												THEN 'First'
												WHEN sched.freq_relative_interval = 2
												THEN 'Second'
												WHEN sched.freq_relative_interval = 4
												THEN 'Third'
												WHEN sched.freq_relative_interval = 8
												THEN 'Fourth'
												WHEN sched.freq_relative_interval = 16
												THEN 'Last'
											END
											+ CASE	WHEN sched.freq_interval = 1
													THEN ' Sunday'
													WHEN sched.freq_interval = 2
													THEN ' Monday'
													WHEN sched.freq_interval = 3
													THEN ' Tuesday'
													WHEN sched.freq_interval = 4
													THEN ' Wednesday'
													WHEN sched.freq_interval = 5
													THEN ' Thursday'
													WHEN sched.freq_interval = 6
													THEN ' Friday'
													WHEN sched.freq_interval = 7
													THEN ' Saturday'
													WHEN sched.freq_interval = 8
													THEN ' Day'
													WHEN sched.freq_interval = 9
													THEN ' Weekday'
													WHEN sched.freq_interval = 10
													THEN ' Weekend'
												END
											+ CASE	WHEN sched.freq_recurrence_factor &lt;&gt; 0
															AND sched.freq_recurrence_factor = 1
													THEN '; monthly'
													WHEN sched.freq_recurrence_factor &lt;&gt; 0
													THEN '; every '
															+ CAST(sched.freq_recurrence_factor AS VARCHAR(10))
															+ ' months'
												END
									WHEN sched.freq_type = 64 THEN 'StartUp'
									WHEN sched.freq_type = 128 THEN 'Idle'
								END AS Frequency
							, ISNULL('Every '
										+ CAST(sched.freq_subday_interval AS VARCHAR(10))
										+ CASE	WHEN sched.freq_subday_type = 2
												THEN ' seconds'
												WHEN sched.freq_subday_type = 4
												THEN ' minutes'
												WHEN sched.freq_subday_type = 8
												THEN ' hours'
											END, 'Once') AS SubFrequency
							, REPLICATE('0', 6 - LEN(sched.active_start_time))
							+ CAST(sched.active_start_time AS VARCHAR(6)) AS start_time
							, REPLICATE('0', 6 - LEN(sched.active_end_time))
							+ CAST(sched.active_end_time AS VARCHAR(6)) AS end_time
							, REPLICATE('0', 6 - LEN(jobsched.next_run_time))
							+ CAST(jobsched.next_run_time AS VARCHAR(6)) AS next_run_time
							, CAST(jobsched.next_run_date AS CHAR(8)) AS next_run_date
						FROM msdb.dbo.sysschedules AS sched
							INNER JOIN msdb.dbo.sysjobschedules AS jobsched
								ON sched.schedule_id = jobsched.schedule_id
						WHERE sched.enabled = 1
				)
	SELECT j.name AS JobName
			, j.enabled
			, j.category_id
			, sp.name AS JobOwner
			, c.name
			, c.category_class
			, js.step_id
			, js.step_name
			, js.subsystem
			, js.command
			, js.database_name
			, js.database_user_name
			, ct.next_run_date
			, ct.next_run_time
			, ct.start_time
			, ct.end_time
			, ct.Frequency
			, ct.SubFrequency
			, ct.scheduleName AS ScheduleName
			, ct.SchedEnabled--, ss.
		FROM dbo.sysjobs j
			INNER JOIN dbo.sysjobsteps js
				ON j.job_id = js.job_id
			INNER JOIN dbo.syscategories c
				ON j.category_id = c.category_id
			INNER JOIN sys.server_principals sp
				ON j.owner_sid = sp.sid
			INNER JOIN myCTE ct
				ON ct.job_id = j.job_id;</pre><p>This script will only retrieve the SQL Agent Job schedules that are not SSRS related and that are not SSIS maintenance package related. The SSRS stuff has already been introduced, and a quick eval of those blog posts will show the differences between grabbing SSRS information vs. grabbing just SQL Agent Jobs.</p>
<p>Stay tuned. I will post a script for the SSIS related scheduling information.</p>
<p>Now, go forth and audit your agent jobs. Document the schedules in an easy to read format. Give that report / document to the auditors and your manager and look like a rock star for the day!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3477" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/03/29/sql-agent-job-schedules/">SQL Agent Job Schedules</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/03/29/sql-agent-job-schedules/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Index Cannot Be Reorganized&#8230;</title>
		<link>https://jasonbrimhall.info/2016/03/15/index-cannot-be-reorganized/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=index-cannot-be-reorganized</link>
					<comments>https://jasonbrimhall.info/2016/03/15/index-cannot-be-reorganized/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 16 Mar 2016 01:13:09 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Administration]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Index Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3445</guid>

					<description><![CDATA[<p>Working diligently as any good DBA might, you have established maintenance routines for each of the SQL Servers under your purview. Then a small problem occurs: Index Cannot Be Reorganized...</p>
The post <a href="https://jasonbrimhall.info/2016/03/15/index-cannot-be-reorganized/">Index Cannot Be Reorganized…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space.jpg" rel="attachment wp-att-3446"><img loading="lazy" class=" wp-image-3446 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space-300x245.jpg" alt="sunburst_space" width="250" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space-300x245.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space-768x627.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space-1024x836.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space-50x41.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sunburst_space.jpg 1059w" sizes="(max-width: 250px) 85vw, 250px" /></a>Working diligently as any good DBA might, you have established maintenance routines for each of the SQL Servers under your purview.</p>
<p>As a part of this maintenance you have scripted solutions to intelligently manage and maintain the fragmentation levels for each of the indexes within each database on each instance.</p>
<p>To further show how diligent you are as a DBA, the outcomes of each maintenance run are logged and you review the logs each morning. This routine helps keep you on top of everything that is happening within the environment.</p>
<p>For months, maybe even years, things are running smoothly. Never a failure. Never an error. Just routine log review day after day. Then one day it happens &#8211; there is an error. The index maintenance script failed one night.</p>
<h2>Index Cannot be Reorganized&#8230;</h2>
<p>You receive the error message similar to the following:</p>
<p><span style="color: #ff0000;"><em>Msg 2552, Level 16, State 1, Line 1 The index &#8220;blah&#8221; (partition 1) on table &#8220;blah_blah_blah&#8221; cannot be reorganized because page level locking is disabled</em></span></p>
<p>Immediately, you start double-checking yourself and verifying that it worked the previous night. You even go so far as to confirm that the same index was previously reorganized. How is it possible that it is failing now on this index. What has changed? Has something changed?</p>
<p>Time for a little digging and investigating, so the dirty work begins. On one side of the coin you are relieved to be able to do something different. On the other side of that coin, you are rather annoyed that something seems to have changed. These feelings are perfectly normal!</p>
<p>First things first &#8211; you investigate the indexes in question to confirm what the error is saying. This is easily done with a query such as the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT i.name AS IdxName
		, SCHEMA_NAME(o.schema_id) AS SchName
		, OBJECT_NAME(i.object_id) AS ObjName
		, i.allow_page_locks
	FROM sys.indexes i
		INNER JOIN sys.objects o
			ON o.object_id = i.object_id
	WHERE OBJECTPROPERTY(i.object_id,'IsMSShipped') = 0;</pre><p>Scrolling through the results, you notice (eventually) that the IX_SpecialOfferProduct_ProductID in the AdventureWorks2014 database has page locks disabled. You are absolutely certain that this index was created allowing page locks. Pondering the problem for a moment, you recall having <a href="http://bit.ly/1wtDgeY">read about the default trace</a> (there are several articles on the default trace &#8211; <a href="http://bit.ly/deftraceSearch">here</a>) and the thought occurs to try and see if there is a breadcrumb there about the change. Using the query from that <a href="http://bit.ly/1wtDgeY">default trace</a> article, a picture starts to unscramble. Here is that query reposted and a snippet of the results:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @DBName sysname = 'AdventureWorks2014'
		,@d1 DATETIME
		,@diff INT;

SELECT ObjectName
		  , ObjectID
		  , DatabaseName
		  , StartTime
		  , EventClass
		  , EventSubClass
		  , T.TextData AS SQLStatement
		  , ObjectType
		  , ServerName
		  , LoginName
		  , NTUserName
		  , ApplicationName
		  , CASE EventClass
				WHEN 46
					THEN 'CREATE'
				WHEN 47
					THEN 'DROP'
				WHEN 164
					THEN 'ALTER'
			END AS DDLOperation
		INTO #temp_trace  
	FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
			( SELECT REVERSE(SUBSTRING(REVERSE(path),
					CHARINDEX('\',REVERSE(path)),256)) + 'log.trc'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) T  
  WHERE EventClass in (46,47,164) 
			AND EventSubclass = 0
			AND ObjectType &lt;&gt; 21587-- don't bother with auto-statistics as it generates too much noise   
			AND DatabaseName = @DBName;


SELECT @d1 = MIN(StartTime) 
	FROM #temp_trace;

SET @diff= DATEDIFF(hh,@d1,GETDATE());


SELECT @diff AS HrsSinceFirstChange    
		, @d1 AS FirstChangeDate 
		, tt.StartTime AS LastChange   
		, sv.name AS obj_type_desc
		, tt.ObjectType
		, tt.DDLOperation
		, tt.SQLStatement
		, tt.DatabaseName,tt.ObjectName
		, tt.EventClass,tt.EventSubClass
		, tt.ServerName,tt.LoginName, tt.NTUserName
		, tt.ApplicationName
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType ) )%2 AS l1     
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType,StartTime ))%2 AS l2    
	FROM #temp_trace tt
		INNER JOIN sys.trace_events AS te 
			ON tt.EventClass = te.trace_event_id
		INNER JOIN sys.trace_subclass_values tsv
			ON tt.EventClass = tsv.trace_event_id
			AND tt.ObjectType = tsv.subclass_value
		INNER JOIN master.dbo.spt_values sv 
			ON tsv.subclass_value = sv.number
			AND sv.type = 'EOD'
	ORDER BY StartTime DESC;

DROP TABLE #temp_trace;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit.png" rel="attachment wp-att-3448"><img loading="lazy" class="alignnone wp-image-3448 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit-1024x64.png" alt="index_deftrace_audit" width="560" height="35" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit-1024x64.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit-300x19.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit-768x48.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_deftrace_audit-50x3.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This is a great start. Not seen in the results is the timestamp showing when it was done &#8211; which was due solely to snipping. Also not shown is the text of the statement that was run for those three events. So close, yet so far away. This is not quite enough to have the smoking gun evidence to show Jason (me) that I did something wrong and unauthorized. What to do now?</p>
<p>All is not lost yet! Your stunning memory kicks in and you recall several articles about using <a href="http://jasonbrimhall.info/2015/07/08/database-settings-changes-red-handed/">Extended Events to audit server and database changes</a>. Better yet, you recall that you deployed an XE session to the server where this error occurred. And yes, you are slightly embarrassed that you failed to remove the XE session after fiddling with it. We won&#8217;t tell anybody that you deployed a test XE session to a production server as if it were your sandbox. The session currently deployed is trapping all object changes unlike the following session that has it filtered down to just objects that are indexes.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'ObjChangeAudit' )
	DROP EVENT SESSION ObjChangeAudit 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION ObjChangeAudit ON SERVER
ADD EVENT sqlserver.object_altered ( SET collect_database_name = ( 1 )
	ACTION ( sqlserver.sql_text,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.client_hostname,
	package0.collect_system_time,package0.event_sequence ) 
	WHERE database_name = 'AdventureWorks2014'
		AND object_type = 'INDEX'
			OR object_type = 'OBJ'
	)
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\ObjChangeAudit.xel' )
WITH (STARTUP_STATE = OFF
	,TRACK_CAUSALITY = ON);

/* start the session */
ALTER EVENT SESSION ObjChangeAudit 
ON SERVER 
STATE = START;
GO</pre><p>You query the trace file with a query like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.event_session_id--, '' AS event_predicate
	INTO #xmlprocess
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, ses.event_session_id
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					--INNER JOIN sys.server_event_session_events sese
					--	ON ses.event_session_id = sese.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'ObjChangeAudit'
					) cte1
				OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;

SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/data[@name="database_name"]/value)[1]',
							'varchar(max)') AS DBName
		, event_data.value('(event/data[@name="ddl_phase"]/text)[1]',
							'varchar(max)') AS DDLPhase
		, event_data.value('(event/data[@name="object_type"]/text)[1]',
							'varchar(max)') AS object_type
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		, event_data.value('(event/action[@name="collect_system_time"]/value)[1]',
							'varchar(max)') AS SystemTime
		, event_data.value('(event/action[@name="client_hostname"]/value)[1]',
							'varchar(max)') AS ClientHostName
		, event_data.value('(event/action[@name="server_principal_name"]/value)[1]',
							'varchar(max)') AS ServerPrincipalName
		, event_data.value('(event/action[@name="nt_username"]/value)[1]',
							'varchar(max)') AS nt_username
		, event_data.value('(event/action[@name="sql_text"]/value)[1]',
							'varchar(max)') AS sql_text
	FROM #xmlprocess x
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON x.event_data.value('(event/@name)[1]', 'varchar(50)') = sese.name
			AND x.event_session_id = sese.event_session_id
	ORDER BY timestamp,event_data.value('(event/action[@name="event_sequence"]/value)[1]',
							'varchar(max)');

DROP TABLE #xmlprocess;</pre><p>Wow! Look at the results! There is a smoking gun finally.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit.png" rel="attachment wp-att-3449"><img loading="lazy" class="alignnone wp-image-3449 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit-1024x55.png" alt="index_xe_audit" width="560" height="30" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit-1024x55.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit-300x16.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit-768x41.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit-50x3.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Two results happen to pin the root cause of the change squarely on my shoulders. Yup, Jason changed that index to disallow page locks. I highlighted three different areas of interest in the results. The yellow and green indicate the DDL phase. One row for the start of the statement, and another row for the commit of that statement. The red highlight shows me the exact change that was made to this index. This is all very good info!</p>
<h3>What Now?</h3>
<p>It really is great to have the smoking gun. If something is broke and it worked previously, it is essential to find the root cause. With a root cause under the belt, what needs to be done to fix the failure? That is a little bit easier that finding the root cause. That is, unless there is a technical reason for the index to no longer allow page locks (maybe that smoking gun is less of a smoking gun and more like baby spittle after all).</p>
<p>Here is how you fix the problem:</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER INDEX IX_SpecialOfferProduct_ProductID ON Sales.SpecialOfferProduct SET (ALLOW_PAGE_LOCKS = ON) 
GO</pre><p></p>
<h3>But, But, But&#8230;</h3>
<p>The Extended Events session would be very noisy and capture every alter index statement, right? It should capture statements like the following, right?</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER INDEX IX_SpecialOfferProduct_ProductID ON Sales.SpecialOfferProduct REBUILD
GO

ALTER INDEX IX_SpecialOfferProduct_ProductID ON Sales.SpecialOfferProduct REORGANIZE
GO

ALTER INDEX IX_SpecialOfferProduct_ProductID ON Sales.SpecialOfferProduct REBUILD WITH (DATA_COMPRESSION = PAGE)
GO</pre><p>The answer to that question is: Yes, Yes, Yes. These statements are all captured due to the use of the ALTER statement. Here are the results of the XE session with all of these scripts having been executed:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2.png" rel="attachment wp-att-3450"><img loading="lazy" class="alignnone wp-image-3450 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2-1024x174.png" alt="index_xe_audit2" width="560" height="95" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2-1024x174.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2-300x51.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2-768x131.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/03/index_xe_audit2-50x9.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If you want to audit when the indexes are changing and how they are changing, this will do just the trick. If there are a ton of changes, then be prepared for a deluge of information.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3445" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/03/15/index-cannot-be-reorganized/">Index Cannot Be Reorganized…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/03/15/index-cannot-be-reorganized/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Virginia Tour 2016</title>
		<link>https://jasonbrimhall.info/2016/03/11/the-virginia-tour-2016/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-virginia-tour-2016</link>
					<comments>https://jasonbrimhall.info/2016/03/11/the-virginia-tour-2016/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 11 Mar 2016 17:10:29 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Speaking]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3440</guid>

					<description><![CDATA[<p>Three days of presentations in Richmond Virginia. From Naked SQL to Wheel of Doom - there is a wide breadth of knowledge to be shared.</p>
The post <a href="https://jasonbrimhall.info/2016/03/11/the-virginia-tour-2016/">The Virginia Tour 2016</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/db_nsfw.png" rel="attachment wp-att-3441"><img loading="lazy" class="alignright wp-image-3441" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/db_nsfw-259x300.png" alt="db nsfw" width="191" height="221" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/db_nsfw-259x300.png 259w, https://jasonbrimhall.info/wp-content/uploads/2016/03/db_nsfw-43x50.png 43w, https://jasonbrimhall.info/wp-content/uploads/2016/03/db_nsfw.png 389w" sizes="(max-width: 191px) 85vw, 191px" /></a>Long Time Coming</h2>
<p>With less than a week before the Richmond SQLSaturday event, I am finally getting this post done &#8211; maybe.</p>
<p>This is not just a one day event for me. No no! I will be presenting for three consecutive days on many things SQL Server related. The Virginia Tour 2016 really is more of a Richmond Tour 2016 (March 16-19) with all three days being presentations in the Richmond area.</p>
<p>The tour starts off with a visit to the Richmond User Group. You can find details on the evening and event on their website &#8211; <a href="http://rva.sqlpass.org/Home/tabid/13075/ctl/Details/Mid/23907/ItemID/891/Default.aspx?SkinSrc=[G]Skins/pass_chapter_2012/Fixed_2_Column_Right_Sidebar" class="broken_link">here</a>.</p>
<p>Here is a quick recap of the NSFW (<strong>N</strong>aked <strong>S</strong>ql: <strong>F</strong>undamentals to <strong>W</strong>isdom) session:</p>
<blockquote><p>Ever feel like there are just too many layers with SQL Server? You peel off a layer and behold there is yet another layer. SQL Server is rather complex. The complexities can be rather frustrating from time to time.</p>
<p>Join this NSFW (not safe for whining) session as we strip SQL down to the bare bones. I will help you undress the complexities of a few of the basic SQL Server concepts. These concepts will include locks, principals, query directives and deadlocks.</p>
<p>In this session I will disrobe misunderstandings related to the aforementioned topics. I will show the different types of principals in SQL Server. I will also show various scenarios involving locks and deadlocks along with some of their effects with and without query directives. The goal is to better understand these topics and to hopefully stop using and perpetuating common mis-uses of terminology and common misconceptions about the technology.</p></blockquote>
<p>This should be a light-hearted and fun session with a bit of NSFW learning. Just hope the censors don&#8217;t get to the slide deck first!</p>
<p>After the user group presentation to kick off the week, there will be an all-day encore on Friday. Friday is officially a part of the SQLSaturday event. You are welcome to come and participate in my all day workshop &#8211; <strong>Monitoring SQL Server with Extended Events</strong>. There is an event page with details for registering that you can visit &#8211; <a href="https://www.eventbrite.com/e/monitoring-sql-server-with-extended-events-registration-20982153185">here</a>!</p>
<p>Here is some of what I will be covering in day 2 of this Richmond tour:</p>
<blockquote><p>Every good enterprising DBA has the prime directive of monitoring the SQL Servers under his/her jurisdiction. The last thing a DBA wants to hear is that there is a problem with a database under his/her purview from an end-user.</p>
<p>SQL Server has progressed over time to give better and better information to the DBA.  Much of this information can be used in a home grown solution to monitor SQL Server. With the constant increase in surface area from Extended Events, the power to build a home grown solution becomes more and more feasible while being limited only by the imagination of the enterprising DBA (or developer or data professional). This full day workshop will introduce you to an Extended Events based solution to achieve that home-grown monitoring goal.</p>
<p>This full day session on Extended Events will help prepare you to put this tool to immediate use as you walk back to your daily duties.  This workshop will teach you about Extended Events starting with the basics and moving through how to create XE sessions that will get the right data for you, while doing so with minimal impact.</p>
<p>You will be exposed to advanced troubleshooting techniques as we work through complex issues that are made easier through the use of XE.  Take advantage of this opportunity to dive into the world of Extended Events and learn how you can make best use of this tool in your SQL 2008+ environment.</p></blockquote>
<p>This will be a fun day if for nothing else than it is about Extended Events and how to glean great information from your SQL Servers. That and we will keep it light. Just remember, the more you are involved in the workshop the better it will be!</p>
<p><a href="http://www.sqlsaturday.com/486/eventhome.aspx" rel="attachment wp-att-3442"><img loading="lazy" class="alignleft wp-image-3442" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/sqlsat486web.png" alt="sqlsat486web" width="234" height="114" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/sqlsat486web.png 236w, https://jasonbrimhall.info/wp-content/uploads/2016/03/sqlsat486web-50x24.png 50w" sizes="(max-width: 234px) 85vw, 234px" /></a>After a brief break to grab some zzzz&#8217;s, I will be wrapping up this tour with the grand finale &#8211; <strong><a href="http://www.sqlsaturday.com/486/eventhome.aspx">SQL Saturday 486</a></strong>!!</p>
<p>Not only will I be presenting at this event, I have also volunteered.</p>
<p>I will have a short introductory style presentation about Extended Events. I intend to show a little profiler and a little Extended Events. As usual, I intend to keep the session light, fun and engaging. Here is a little more info on that session:</p>
<blockquote><p>
Extended Events were introduced in SQL Server 2008. With SQL 2014, we have seen a significant upgrade to this feature. Join me for a little adventure into the realm of extended events. We will discuss how to use extended events to aid in performance tuning and in day to day administration. We will also explore some background and the architecture of extended events. This is a fast paced session and will be a lot of fun. Attendees will be able to take back several sample XE sessions to help troubleshoot different issues and get to more intimately know their data/environment.</p></blockquote>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/03/wheelofdoom.png" rel="attachment wp-att-3443"><img loading="lazy" class="wp-image-3443 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/03/wheelofdoom.png" alt="wheelofdoom" width="170" height="171" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/03/wheelofdoom.png 250w, https://jasonbrimhall.info/wp-content/uploads/2016/03/wheelofdoom-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2016/03/wheelofdoom-50x50.png 50w" sizes="(max-width: 170px) 85vw, 170px" /></a>Then to cap the day, I will be helping to assist with the Wheel of Doom.</p>
<p>The name of the session sounds much worse than it really is. The premise is simple. Speakers and attendees are invited to submit a lightening talk style session with slide deck. Then attendees of the session can volunteer to spin the wheel and present whichever session pops up.</p>
<p>This session is to help people get over the nerve of presenting. It will be very light-hearted and entertaining. No judgement, no shaming, just have fun with it!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3440" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/03/11/the-virginia-tour-2016/">The Virginia Tour 2016</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/03/11/the-virginia-tour-2016/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Alter Event Session</title>
		<link>https://jasonbrimhall.info/2016/01/07/alter-event-session/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=alter-event-session</link>
					<comments>https://jasonbrimhall.info/2016/01/07/alter-event-session/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 08 Jan 2016 01:20:52 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3408</guid>

					<description><![CDATA[<p>Altering an Extended Event session is not necessarily a difficult task, but it is a very useful ability. Having this basic skill in your wheelhouse can be very positive and useful for you!</p>
The post <a href="https://jasonbrimhall.info/2016/01/07/alter-event-session/">Alter Event Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/candycane.png" rel="attachment wp-att-3409"><img loading="lazy" class="wp-image-3409 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/candycane-193x300.png" alt="candycane" width="140" height="218" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/candycane-193x300.png 193w, https://jasonbrimhall.info/wp-content/uploads/2016/01/candycane-32x50.png 32w, https://jasonbrimhall.info/wp-content/uploads/2016/01/candycane.png 482w" sizes="(max-width: 140px) 85vw, 140px" /></a>Ready for a change of pace? Good! Today is a really good time to start looking into one of the more basic concepts related to Extended Event Session management.</p>
<p>Consider the occasional need to change a trace. Maybe you added the wrong event to the trace, or maybe you neglected to include the event in the first place. There is also the possibility that all of the events are correct but the actions or predicates may not be completely ideal for your trace session. What if it is just as simple as a missing target or adding another target to the session? All of these are potential changes to an XEvent session that might be needed.</p>
<p>Today, I will cover how easy it is to modify these sessions without dropping the entire session as many examples on the internet show. Each of the configuration changes just mentioned can be handled through some pretty simple scripts (and yes through the GUI as well).</p>
<h3>Altered States</h3>
<p>&nbsp;</p>
<p>There is no getting around it. To demonstrate how to change event sessions, an event session must first exist. Let&#8217;s use the following as the demo session.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.auto_stats ( SET collect_database_name = ( 1 )
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name )
	WHERE ( [database_name] = N'AdventureWorks2014' ) )
ADD TARGET package0.ring_buffer ( SET max_events_limit = ( 666 )
									, max_memory = ( 65536 )
									, occurrence_number = ( 3 ) )
WITH ( MAX_MEMORY = 4096 KB
		, EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 5 SECONDS
		, MAX_EVENT_SIZE = 2048 KB
		, MEMORY_PARTITION_MODE = PER_NODE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = ON );
GO</pre><p>This session starts with a ring_buffer target. There is a single event in the session. This event has a few actions applied to it along with a predicate on the database_name field. I also have several of the settings for this session defined (whether at the custom field level or at the session level).</p>
<p>After deploying this session, I quickly realize that I flubbed it up a bit. I forgot a few things. Since those items are missing, I need to get them added without negatively impacting the already gathered data. Let&#8217;s start with the missing target. I don&#8217;t know how I missed it, but I completely forgot to add a file target to this session. The file target is a must have, so let&#8217;s get it added.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* target change */
ALTER EVENT SESSION [AlteredState] ON SERVER
ADD TARGET package0.event_file ( SET filename = N'AlteredState'
	, max_file_size = ( 50 )
	, max_rollover_files = ( 6 ) );
GO</pre><p>Phew, that problem has been easily rectified. Further review of the session shows the next problem. My manager requires that the dispatch latency be no more than 4 seconds and that the event memory not exceed 4090 kb. My manager is a little intense about some of these settings. To ensure I adhere to his requirements, I need to change my session settings now.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* set operations change */
ALTER EVENT SESSION [AlteredState] ON SERVER
WITH ( MAX_MEMORY = 4090 KB
		, MAX_DISPATCH_LATENCY = 4 SECONDS
 );
GO</pre><p>Good! We are rolling right along here. Fixed a couple of problems real quick with that session and I can continue on with other tasks for the day. Shortly after lunch the manager stops in and asks who changed various database settings. Looking into this session that was just deployed to try and capture some of those events, I get that sinking feeling when I realize that I completely missed that requirement. D&#8217;oh! That&#8217;s ok for now because I hadn&#8217;t turned off the default trace, but I better get the proper event added to the session.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* add event */
ALTER EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.object_altered (
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name )
	)
;
GO</pre><p>The next time something changes with the database, it will now be captured. Sadly, too many things are crossing over the desk and I am trying to move too quickly. I forgot to enable the custom field to collect the database name, I better make that adjustment.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* event custom field change */
ALTER EVENT SESSION [AlteredState] ON SERVER
DROP EVENT sqlserver.object_altered;
ALTER EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.object_altered (SET collect_database_name=(1)
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name )
	)
;
GO</pre><p>Nice, I have that adjustment made. Unfortunately this is where it does become a bit more complicated. Notice that I had to drop the event from the session first before making that change to the custom field setting for that event? This should be minimal in overall impact since it does not remove the already captured events from the session target. But it is an extra step that must be remembered when making a change that affects an Event within the session.</p>
<p>So far so good. I can capture the events that relate to a database change. I can figure out who made the change and the statement made for the change, right? Nope. I missed that during the setup. I guess I better add that in so I have better information for auditing the changes made to the database. I can start capturing that with the addition of the correct actions.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* oops wrong actions for the new event */
ALTER EVENT SESSION [AlteredState] ON SERVER
DROP EVENT sqlserver.object_altered;
ALTER EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.object_altered (SET collect_database_name=(1)
	ACTION ( package0.event_sequence, sqlserver.client_hostname,sqlserver.nt_username,sqlserver.server_principal_name,
	sqlserver.database_name, sqlserver.sql_text )
	)
;
GO</pre><p>Everything is now settled in with that session. I go about my merry way for a couple of weeks. Then, one day, I find I need to review the logs to determine who has been changing database settings again. When looking at the log data I discover there are all sorts of object changes being logged to the event session log files. In review of the session definition I figure out the problem. I missed a predicate limiting the captured events to only those that are database type changes. I might as well get that added in.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* oops, missed that predicate */
ALTER EVENT SESSION [AlteredState] ON SERVER
DROP EVENT sqlserver.object_altered;
ALTER EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.object_altered (SET collect_database_name=(1)
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name, sqlserver.sql_text )
	WHERE ([object_type]='DATABASE')
	)
;
GO</pre><p>This will now change the event session so the object_altered event will only capture &#8220;database&#8221; type events. These are the types of events that include settings changes at the database level.</p>
<p>Making changes to an event session without needing to drop and recreate the entire session is a pretty powerful tool. If I script that session as it is now configured, I would get the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [AlteredState] ON SERVER
ADD EVENT sqlserver.auto_stats ( SET collect_database_name = ( 1 )
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name )
	WHERE ( [database_name] = N'AdventureWorks2014' ) ),
ADD EVENT sqlserver.object_altered ( SET collect_database_name = ( 1 )
	ACTION ( package0.event_sequence, sqlos.cpu_id, sqlserver.database_id,
	sqlserver.database_name, sqlserver.sql_text )
	WHERE ( [object_type] = 'DATABASE' ) )
ADD TARGET package0.event_file ( SET filename = N'AlteredState'
									, max_file_size = ( 50 )
									, max_rollover_files = ( 6 ) ),
ADD TARGET package0.ring_buffer ( SET max_events_limit = ( 666 )
									, max_memory = ( 65536 )
									, occurrence_number = ( 3 ) )
WITH ( MAX_MEMORY = 4090 KB
		, EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS
		, MAX_DISPATCH_LATENCY = 4 SECONDS
		, MAX_EVENT_SIZE = 2048 KB
		, MEMORY_PARTITION_MODE = PER_NODE
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = ON );
GO</pre><p>Compare this to the starting session, and it is apparent that all of the changes implemented are now intact.</p>
<p>Altering an Extended Event session is not necessarily a difficult task, but it is a very useful ability. Having this basic skill in your wheelhouse can be very positive and useful for you!</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3408" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/01/07/alter-event-session/">Alter Event Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/01/07/alter-event-session/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Waiting, is it a Bad Thing?</title>
		<link>https://jasonbrimhall.info/2016/01/06/waiting-is-it-a-bad-thing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=waiting-is-it-a-bad-thing</link>
					<comments>https://jasonbrimhall.info/2016/01/06/waiting-is-it-a-bad-thing/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 06 Jan 2016 07:31:19 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3399</guid>

					<description><![CDATA[<p>One of the more useful troubleshooting tools (granted when used properly and not with a knee jerk approach) is waits. There are waits in SQL Server that are very specific to Extended Events.</p>
The post <a href="https://jasonbrimhall.info/2016/01/06/waiting-is-it-a-bad-thing/">Waiting, is it a Bad Thing?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/stockinghat.png" rel="attachment wp-att-3400"><img loading="lazy" class="wp-image-3400 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/stockinghat-245x300.png" alt="stockinghat" width="184" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/stockinghat-245x300.png 245w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stockinghat-41x50.png 41w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stockinghat.png 669w" sizes="(max-width: 184px) 85vw, 184px" /></a>Despite the desire to get away from the GUI talk in these articles about Extended Events, I have so far been unable to do it. Each article of late has something more to deal with the user interface. Let&#8217;s see what we can do with the GUI today.</p>
<p>One of the more useful troubleshooting tools (granted when used properly and not with a knee jerk approach) is waits. There are waits in SQL Server that are very specific to Extended Events. Not all waits are bad. Some are innocuous. But with a shoot from the hip approach, these waits can cause many DBAs to focus on the wrong thing.</p>
<p>In this article, I will show one particular wait for Extended Events. As a matter of fact, if you were paying attention to the last article, you will have already seen this wait in passing. To get a quick glimpse or to recall what was discussed, please read the article about the <a href="http://bit.ly/22I4PhN">live stream target here</a>.</p>
<h3>Patience Padowan</h3>
<p>The first thing I want to do is clear my wait stats. Here is a quicky on doing that. Understand that this clears out the wait stats and resets the counters to 0. If you track your waits on a regular basis, this may cause a raised eyebrow by your team-mates.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC SQLPERF("sys.dm_os_wait_stats",CLEAR);</pre><p>After clearing my waits, I can check for a baseline. When checking for this baseline it is important to note that I have nothing ready from an extended event target currently. I will start that after getting my baseline. Here is what my waits look like prior to working with the target data from any XEvent Session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/baseline.png" rel="attachment wp-att-3403"><img loading="lazy" class="alignnone wp-image-3403 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/baseline-1024x196.png" alt="baseline" width="560" height="107" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/baseline-1024x196.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/baseline-300x57.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/baseline-768x147.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/baseline-50x10.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/baseline.png 1087w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This is pretty vanilla prior to working with the targets. That is a good thing for now. This gives me a good sense that the baseline is a good starting point. Now, similar to what was shown in the live stream article previously mentioned, I am going to open a live stream viewer for the system_health session. At this point, you could wait for a minute or three and then re-query the waits. <em>This additional step would be to help show that the XE wait has not yet introduced itself.</em></p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png" rel="attachment wp-att-3387"><img loading="lazy" class="alignnone wp-image-3387 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png" alt="descendintostream" width="524" height="502" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png 524w, https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream-300x287.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream-50x48.png 50w" sizes="(max-width: 524px) 85vw, 524px" /></a></p>
<p>Perfect. Now I have a live stream viewer open for the system_health session. I have a good baseline. Now I just need to watch the viewer for a bit. I am doing this to ensure enough time has passed by that my waits have incremented. After a few events pop into the system_health session, I will re-query my waits.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit.png" rel="attachment wp-att-3404"><img loading="lazy" class="alignnone wp-image-3404 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit-1024x231.png" alt="xe_waitingabit" width="560" height="126" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit-1024x231.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit-300x68.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit-768x173.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit-50x11.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/xe_waitingabit.png 1060w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Look at how that wait has zoomed clear to the top! This wait is huge! This wait does not appear until the &#8220;Watch Live Data&#8221; option is being used to tap into the streaming target (really should be anything that is tapping into the live stream target via the GUI or via some other program). An example of &#8220;some other program&#8221; could be as simple as somebody querying the sys.fn_MSxe_read_event_stream function from management studio and trying to return the live stream data (as was discussed in the previously mentioned article).</p>
<p>Not understanding what causes the XE_LIVE_TARGET_TVF wait type can cause a data professional, or two, to chase their tail on something that may not be an issue overall. I have seen this happen on more than one occasion where somebody has spent hours trying to chase down the problem that this wait indicates. It doesn&#8217;t necessarily indicate a problem (unless you are a shoot from the hip gun-slinging troubleshooter type). It just means that the process accessing the live stream is waiting for more data to come through. That said, if this wait is high, maybe it is time to look into who might be tapping into the Live stream target.</p>
<p>Pretty straight forward and short today. I hope this helps avoid some time-waste for something that can be ignored most of the time.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3399" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/01/06/waiting-is-it-a-bad-thing/">Waiting, is it a Bad Thing?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/01/06/waiting-is-it-a-bad-thing/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>A day in the Stream</title>
		<link>https://jasonbrimhall.info/2016/01/04/a-day-in-the-stream/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-day-in-the-stream</link>
					<comments>https://jasonbrimhall.info/2016/01/04/a-day-in-the-stream/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 05 Jan 2016 04:38:55 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3385</guid>

					<description><![CDATA[<p>Explore the little function called sys.fn_MSxe_read_event_stream and discover just a little bit more of what Extended Events may be doing behind the scenes with the live data viewer.</p>
The post <a href="https://jasonbrimhall.info/2016/01/04/a-day-in-the-stream/">A day in the Stream</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/hoho.png" rel="attachment wp-att-3386"><img loading="lazy" class=" wp-image-3386 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/hoho-300x283.png" alt="hoho" width="239" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/hoho-300x283.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/hoho-768x724.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/hoho-50x47.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/hoho.png 774w" sizes="(max-width: 239px) 85vw, 239px" /></a>Enough talk of the GUI with Extended Events (see previous articles in the series if you want to revisit the stickiness of the GUI &#8211; <a href="http://bit.ly/1NXXNxR">here</a>). It is time for a bit of a diversion and something quick.</p>
<p>While it may be a quick traipse today, it won&#8217;t be the last article on the subject. It is merely an interesting bird walk into a corner of the Extended Events garden that is seldom visited. Today I will explore the little function called sys.fn_MSxe_read_event_stream.</p>
<p>This function, as the name implies, is used to read the event stream and is most commonly seen when watching the live stream of events for a session. I will show a little bit of that.</p>
<h3>Gradually Descending into the Stream</h3>
<p>First, let&#8217;s set the stage so you can confirm that I am not entirely off my rocker here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png" rel="attachment wp-att-3387"><img loading="lazy" class="alignnone wp-image-3387 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png" alt="descendintostream" width="524" height="502" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream.png 524w, https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream-300x287.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/descendintostream-50x48.png 50w" sizes="(max-width: 524px) 85vw, 524px" /></a></p>
<p>By selecting &#8220;Watch Live Data&#8221; from the context menu after right clicking on the &#8220;system_health&#8221; session, I will be given a window just like the window discussed in the past few articles when discussing the GUI. After launching that window, a quick query to your favorite requests and sessions DMVs will reveal a little bit about this function that we are diving into today.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery.png" rel="attachment wp-att-3390"><img loading="lazy" class="alignnone wp-image-3390 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery-1024x48.png" alt="activestreamquery" width="560" height="26" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery-1024x48.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery-300x14.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery-768x36.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/activestreamquery-50x2.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If I click on the query text in that previous result set, I can see the following to be the query that is executing for the &#8220;live data&#8221; stream.</p><pre class="urvanov-syntax-highlighter-plain-tag">(@source nvarchar(256),@sourceopt int)
SELECT type, data 
	FROM sys.fn_MSxe_read_event_stream (@source, @sourceopt)</pre><p>Cleaning it up a bit and giving some useful values to the parameters, I might have something like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* read from livestream */
DECLARE @source NVARCHAR(256) = 'system_health'
	, @sourceopt INT = 0;
SELECT type
		, data
	FROM sys.fn_MSxe_read_event_stream(@source, @sourceopt);</pre><p>Running that particular query from a management studio window would be rather pointless. It doesn&#8217;t ever return unless you cancel the query. The key to this one though is the second parameter. The second parameter tells us what kind of source we want to use for the stream of data. There are two values (that I have been able to find) that can be used: 0 and 1. A value of 0 pulls from the live stream target. A value of 1 pulls from the file target. If using a value of 1, then the first parameter needs to be adjusted accordingly as well. If the two parameters do not match, then an error is thrown.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* read from file */
DECLARE @source NVARCHAR(256) = 'system_health_*.xel'
	, @sourceopt INT = 1;
SELECT type
		, data
	FROM sys.fn_MSxe_read_event_stream(@source, @sourceopt)
	;
GO</pre><p>As it happens, I have several log files in the default directory for the system_health and the HKEngine sessions that are deployed and running on my instance of SQL Server. Here is a sample of those files:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/event_files.png" rel="attachment wp-att-3388"><img loading="lazy" class="alignnone wp-image-3388 " src="http://jasonbrimhall.info/wp-content/uploads/2016/01/event_files.png" alt="event_files" width="524" height="436" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/event_files.png 969w, https://jasonbrimhall.info/wp-content/uploads/2016/01/event_files-300x250.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/event_files-768x640.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/event_files-50x42.png 50w" sizes="(max-width: 524px) 85vw, 524px" /></a></p>
<p>So far so good, right? Let&#8217;s go ahead and execute that second query (that reads from the file target) and see what happens:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1.jpg" rel="attachment wp-att-3391"><img loading="lazy" class="alignnone wp-image-3391 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1-1024x316.jpg" alt="stream_file1" width="560" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1-1024x316.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1-300x92.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1-768x237.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_file1-50x15.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This to me is far from useful as of yet. But there are a couple of rabbit holes to dig into from here. The first being the different types that we can see here. Let&#8217;s refashion the query to restrict the types being returned and see what happens:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1.png" rel="attachment wp-att-3392"><img loading="lazy" class="alignnone wp-image-3392 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1-1024x258.png" alt="stream_filesrabbit1" width="560" height="141" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1-1024x258.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1-300x76.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1-768x194.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1-50x13.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit1.png 1747w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>First, in blue we see that type 2 is exactly the same every single time. In my environment I have exactly four of that type. If I look on the file system, I can see that I have four files as well. This seems to indicate (not yet validated in my plucking at it) that this represents a file. Then type 1 is identical up until the point where I have it highlighted in orange. Just an interesting side note there is all.</p>
<p>If I perform the same thing for the HKEngine session, I see something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2.png" rel="attachment wp-att-3393"><img loading="lazy" class="alignnone wp-image-3393 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2-1024x407.png" alt="stream_filesrabbit2" width="560" height="223" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2-1024x407.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2-300x119.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2-768x306.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2-50x20.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/stream_filesrabbit2.png 1830w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Notice the difference here? Now I have two type 1 entries for each file that has been created. In addition, one of the type 1 entries is exactly the same for all files created.</p>
<p>But without being able to translate the data returned, this is really just a fun exercise into the live stream. That said, I give you one last interesting tidbit for today while leaving the second rabbit hole (translating the data into human readable text) for another time (besides just using the event file function to read it).</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC OUTPUTBUFFER(53)</pre><p>Recall from an earlier result that my spid for the live data viewer was spid 53. If run an output buffer for that spid, I will see something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer.png" rel="attachment wp-att-3395"><img loading="lazy" class="alignnone wp-image-3395 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer-1024x362.png" alt="outputbuffer" width="560" height="198" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer-1024x362.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer-300x106.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer-768x272.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/outputbuffer-50x18.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Not the friendliest of outputs to peruse and try to figure out, but it does give you a sense of what is going on there. If you know how to convert the data output from sys.fn_MSxe_read_event_stream, I would be interested in seeing what you do for it.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3385" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/01/04/a-day-in-the-stream/">A day in the Stream</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/01/04/a-day-in-the-stream/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Hidden GUI Gems</title>
		<link>https://jasonbrimhall.info/2016/01/02/hidden-gui-gems/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hidden-gui-gems</link>
					<comments>https://jasonbrimhall.info/2016/01/02/hidden-gui-gems/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 02 Jan 2016 23:22:21 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3368</guid>

					<description><![CDATA[<p>I have a few gems that are available to you in the GUI. These gems should help solidify your understanding of the tools available through the GUI to help work with Extended Events</p>
The post <a href="https://jasonbrimhall.info/2016/01/02/hidden-gui-gems/">Hidden GUI Gems</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake.png" rel="attachment wp-att-3369"><img loading="lazy" class=" wp-image-3369 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake-289x300.png" alt="frostedsnowflake" width="252" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake-289x300.png 289w, https://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake-768x798.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake-986x1024.png 986w, https://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake-48x50.png 48w, https://jasonbrimhall.info/wp-content/uploads/2016/01/frostedsnowflake.png 1144w" sizes="(max-width: 252px) 85vw, 252px" /></a>The GUI for Extended Events offers some power to help you get started with trying to work with Extended Events. As I have shown over the past few articles, some of this power comes with a bit of cost and may in fact not be as powerful as just using a script. You can flip back through the <a href="http://bit.ly/1R1I4RS">previous articles via this link</a>.</p>
<p>Today, I have a few gems that are available to you in the GUI. These gems should help solidify your understanding of the tools available through the GUI to help work with Extended Events. So far I haven&#8217;t hid my preference for using a script over the GUI. That said, the GUI can be useful for a thing or two. I will explain in better detail further into the article.</p>
<h3>Playing in the Mud</h3>
<p>To show these gems, a little setup is required first. So I am going to start with the following sample session (started from the GUI):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat.png" rel="attachment wp-att-3372"><img loading="lazy" class="alignnone wp-image-3372 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat-1024x729.png" alt="debugwhat" width="560" height="399" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat-1024x729.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat-300x214.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat-768x547.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/debugwhat.png 1503w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The setup thus far is rather simple, I have selected two optional settings &#8211; &#8220;start the event session immediately after session creation&#8221; and &#8220;track how events are related to one another.&#8221; The next thing to do within the GUI is to make my way through the events and select the events I need. The events I want to select need to help me track information related to the SQL process stopping (exiting) and any info related to when a memory dump is created.</p>
<p>To try and find the appropriate events, I will go to the Events tab, click the drop down shown in the green box and select &#8220;Event names and descriptions&#8221; from the menu.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect.png" rel="attachment wp-att-3374"><img loading="lazy" class="alignnone wp-image-3374 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect-1024x540.png" alt="filtering_eventselect" width="560" height="295" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect-1024x540.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect-300x158.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect-768x405.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect-50x26.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect.png 2030w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>After making that selection, then I can type a keyword within the text box under &#8220;Event library&#8221;. Typing in the term &#8220;dump&#8221; will produce no results. This means either I have no events that will meet my requirements or I need to try a different term, right?</p>
<p>Well, just to verify the results I desire to confirm what I have seen by using a script. Executing the following script:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.OBJECT_NAME AS EventName
		,p.name AS PackageName
		,o.description AS EventDescription
		,ch.Channel
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.OBJECT_NAME
			and o.package_guid = c.object_package_guid
		INNER JOIN sys.dm_xe_packages p
			ON o.package_guid = p.guid
		INNER JOIN (SELECT c.object_name AS EventName,c.object_package_guid AS PkgGuid, v.map_value AS Channel
					FROM sys.dm_xe_object_columns c
						INNER JOIN sys.dm_xe_map_values v
							ON c.type_name = v.name
								AND c.column_value = CAST(v.map_key AS NVARCHAR)
					WHERE c.name = 'channel') ch
			ON ch.EventName = c.object_name
			AND ch.PkgGuid = c.object_package_guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND (c.OBJECT_NAME like '%dump%'
			or o.description like '%dump%'
			--OR o.description LIKE '%grant%'
			)
	ORDER BY o.package_guid;</pre><p>This confirms my suspicion. The script returns several results with the term &#8220;dump&#8221; when querying both the descriptions and event names just as I did with the GUI. There is an interesting development however. All of the results show as being in the debug channel.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script.png" rel="attachment wp-att-3376"><img loading="lazy" class="alignnone wp-image-3376 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script-1024x428.png" alt="filtering_eventselect_script" width="560" height="234" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script-1024x428.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script-300x125.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script-768x321.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/filtering_eventselect_script-50x21.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>So why do these results not display from the GUI? Well that is one of the hidden gems. The debug channel is not shown in the GUI results by default. This will prevent any events from that channel from being displayed. This can be changed by checking the box displayed in the following image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter.png" rel="attachment wp-att-3378"><img loading="lazy" class="alignnone wp-image-3378 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter-1024x719.png" alt="channelfilter" width="560" height="393" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter-1024x719.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter-768x539.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/channelfilter.png 1848w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Consider here the name of the Channel for a moment. These events may be obfuscated from search results by default for a good reason. Some of these events can have a significant performance impact on the instance. That said, there is the occasional good reason to need to use the events from this channel in order to troubleshoot specific issues on the server. You just have to dig harder at it.</p>
<p>Having resolved that issue, I have resolved on using the stack_trace and sql_exit_invoked events. So I select both of the events and then move on to the Data Storage tab so I can configure the target. The target I have chosen to use is the event_file target. Now that I have selected the events and configured a target, I can slick the script button. I recommend always using the script button rather than committing the session direct from the GUI. Clicking the script button here will yield the next gem.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat.png" rel="attachment wp-att-3380"><img loading="lazy" class="alignnone wp-image-3380 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat-1024x711.png" alt="Xe_debugwhat" width="560" height="389" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat-1024x711.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat-300x208.png 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat-768x533.png 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/Xe_debugwhat.png 1856w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I have scripted the session I configured in the GUI. Overlaying the general page of the session with the produced script shows the gem. While the track_causality setting does get scripted, the option to start the session after creating the session does not properly script. This is an interesting problem. While this produces a small negative impact, it is one to bear in mind. If you need to have the session started, then make sure to manually start it or script the start of the session to confirm it has been done.</p>
<p>A third gem is one that I have not shown here but one to play with in your free time. If you change the name of the session and then script it, see what happens.</p>
<p>These are just a few more gems that I have shown in the GUI tools for Extended Events. I recommend using a script where possible (which is just about everywhere), and I have not hid that fact. While useful to a small degree, I do not recommend using the GUI for most tasks (again with a recommendation to use a script instead). Using a script has numerous benefits above and beyond the use of a GUI.</p>
<p>If for some reason you are not using Extended Events simply because you wanted to use a graphical interface, I recommend reconsidering. The series of posts I have on Extended Events has plenty of useful scripts that will provide the functionality and ease of use for Extended Events to mitigate that internal lust for the GUI.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3368" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/01/02/hidden-gui-gems/">Hidden GUI Gems</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/01/02/hidden-gui-gems/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Filtering Logged Data</title>
		<link>https://jasonbrimhall.info/2016/01/01/filtering-logged-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtering-logged-data</link>
					<comments>https://jasonbrimhall.info/2016/01/01/filtering-logged-data/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 01 Jan 2016 12:39:19 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3345</guid>

					<description><![CDATA[<p>Explore how to customize the view of the GUI for working with XEvent Log files or XEL files. This further customization does include working with filters.</p>
The post <a href="https://jasonbrimhall.info/2016/01/01/filtering-logged-data/">Filtering Logged Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/grnsnowmn.png" rel="attachment wp-att-3350"><img loading="lazy" class="wp-image-3350 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/grnsnowmn-211x300.png" alt="grnsnowmn" width="167" height="237" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/grnsnowmn-211x300.png 211w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grnsnowmn-35x50.png 35w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grnsnowmn.png 592w" sizes="(max-width: 167px) 85vw, 167px" /></a>Over the course of the past couple of articles, I have shown some interesting if not useful functionality in the user interface for working with Extended Event log files. Those articles on merging files and customizing the view can be read <a href="http://bit.ly/1NQBYjr">here</a> and <a href="http://bit.ly/1P1ZFDs">here</a>.</p>
<p>Today, I am going to explore how to further customize the view of the GUI for working with Extended Event Log files or XEL files. This further customization does include working with filters. Prior to proceeding, it would be beneficial to review the aforementioned articles &#8211; they do outline some building blocks for this article.</p>
<h3>Sifting through it all</h3>
<p>Even with a well tuned XE session, sometimes there is just a deluge of data. A deluge of data can make it more difficult from time to time to find exactly what is the most likely candidate to be the cause of the problem currently at hand (whatever that may be).</p>
<p>When dealing with a large quantity of data, it becomes necessary to filter that data down. Filtering it down will make it significantly easier to handle &#8211; when an appropriate filter is utilized. The GUI permits the implementation of filters in a couple of different ways to help with these dives into the XE logged data.</p>
<p>When convinced to use the GUI to peruse the log data, there are a few possibilities in how to create a filter (and yes it would be better to do it with a script). The first of these methods is actually quite simple. Let&#8217;s start with a grid display of the same session used in the previous couple of articles:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid.jpg" rel="attachment wp-att-3351"><img loading="lazy" class="alignnone wp-image-3351 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid-1024x314.jpg" alt="starter_grid" width="560" height="172" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid-1024x314.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid-300x92.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid-768x236.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid-50x15.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/starter_grid.jpg 1694w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From here, if I right click one of the cells as shown below, I will be prompted with a context menu:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1.png" rel="attachment wp-att-3355"><img loading="lazy" class="alignnone wp-image-3355 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1-1024x483.png" alt="grid_filter" width="560" height="264" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1-1024x483.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1-300x141.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1-768x362.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1-50x24.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/grid_filter-1.png 1598w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>By right clicking a value in the grid, an option to &#8220;Filter by this value&#8221; will be given in the context menu. Selecting that option will open a new window allowing for further configuration of the filter or to just accept the filter as-is.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2.png" rel="attachment wp-att-3354"><img loading="lazy" class="alignnone wp-image-3354 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2-1024x623.png" alt="filter_window2" width="560" height="341" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2-1024x623.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2-300x182.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2-768x467.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/filter_window2.png 1289w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From the &#8220;Filters&#8221; window, you can see there is the option to set a time based filter, to create a filter on values for the fields within the trace log or to combine the two. This is pretty straight forward here. That said, recall that filters configured here can be saved in the viewsetting file discussed in the prior article (mentioned at the beginning of this article).</p>
<h3>Further Analysis</h3>
<p>After filtering down the results, what if you wish to now perform more complex analysis? Maybe the analysis is to be done for trending purposes, or maybe something else. Regardless of the purpose, the need is there and you wish to know how to do it (but for some reason have a serious allergen against doing the work via a script). Luckily there just happens to be a magic button within the GUI that helps to perform this task.</p>
<p>Within the GUI, we are given the opportunity to group and aggregate data. The aggregations cannot be performed without first performing a grouping (very similar to the requirements via script). The grouping can contain multiple fields or just a single field. Let&#8217;s take a quick peek.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe.jpg" rel="attachment wp-att-3361"><img loading="lazy" class="alignnone wp-image-3361 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe-1024x46.jpg" alt="groups_xe" width="560" height="25" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe-1024x46.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe-300x13.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe-768x34.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe-50x2.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/groups_xe.jpg 1629w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Clicking on the Grouping button, the following window opens, permitting the configuration of the groups.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind.jpg" rel="attachment wp-att-3363"><img loading="lazy" class="alignnone wp-image-3363" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind.jpg" alt="group_wind" width="560" height="435" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind.jpg 984w, https://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind-300x233.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind-768x596.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/group_wind-50x39.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This looks pretty familiar and standard. It is rather simple in design and function. Move columns from left to right to add to the grouping. To remove from the grouping, move from right to left.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe.jpg" rel="attachment wp-att-3360"><img loading="lazy" class="alignnone wp-image-3360 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe-1024x46.jpg" alt="aggregs_xe" width="560" height="25" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe-1024x46.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe-300x13.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe-768x34.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe-50x2.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2016/01/aggregs_xe.jpg 1629w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>With the group established, then comes the fun part to help with analysis. This is where aggregations comes into play. Within an aggregation; we can perform counts, max, min, avg and sum. Depending on the field, the aggregation that can be performed may be restricted. Clicking the aggregation button, one will see the following window:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2016/01/agg_wind.jpg" rel="attachment wp-att-3364"><img loading="lazy" class="alignnone wp-image-3364" src="http://jasonbrimhall.info/wp-content/uploads/2016/01/agg_wind.jpg" alt="agg_wind" width="560" height="671" srcset="https://jasonbrimhall.info/wp-content/uploads/2016/01/agg_wind.jpg 734w, https://jasonbrimhall.info/wp-content/uploads/2016/01/agg_wind-250x300.jpg 250w, https://jasonbrimhall.info/wp-content/uploads/2016/01/agg_wind-42x50.jpg 42w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Given the session being evaluated and the columns that have been chosen previously, I am restricted to the columns shown in the preceding image. Aggregations can only be performed on columns selected in the &#8220;Column Chooser&#8221;. The rest of the configuration of the aggregation is merely an exercise in plug and play to determine which fields or aggregation will serve your needs the best.</p>
<p>For this exercise and the chosen grouping, I am going to go with Average on the duration field and then sort the aggregation by that same field in a descending order. For your purposes, feel free to choose something more meaningful or appropriate to your needs.</p>
<h3>Cautionary Tale</h3>
<p>If there happens to be a rather large number of events within the session file(s) being evaluated, don&#8217;t expect this to work without a hitch or three. Trying to load a 1GB trace file (read that as a default size on an XE trace file) with over 600,000 events, SSMS regularly crashed on me while trying to apply a filter, a group, and even the aggregation. None of this has been an issue while trying to perform similar types of groupings and aggregations with large trace files via script.</p>
<p>If you are going to attempt to manipulate aggregations, groupings, filters etc. via the GUI with large trace files, understand that you may run into errors and crashes when using the graphical interface rather than a script. The choice is yours!</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3345" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2016/01/01/filtering-logged-data/">Filtering Logged Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2016/01/01/filtering-logged-data/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Customize the XEvent Log Display</title>
		<link>https://jasonbrimhall.info/2015/12/31/customize-the-xevent-log-display/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customize-the-xevent-log-display</link>
					<comments>https://jasonbrimhall.info/2015/12/31/customize-the-xevent-log-display/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 31 Dec 2015 12:17:36 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3334</guid>

					<description><![CDATA[<p>Explore how to configure the XEvents GUI with specific views to suit your needs and tastes for data display by adding, removing or changing the column orders.</p>
The post <a href="https://jasonbrimhall.info/2015/12/31/customize-the-xevent-log-display/">Customize the XEvent Log Display</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/lego_gift.png" rel="attachment wp-att-3335"><img loading="lazy" class="wp-image-3335 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/lego_gift-300x245.png" alt="lego_gift" width="234" height="191" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/lego_gift-300x245.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/lego_gift-50x41.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/lego_gift.png 682w" sizes="(max-width: 234px) 85vw, 234px" /></a>In the previous article I showed a couple of methods to <a href="http://bit.ly/1NQBYjr">merge Extended Event Log files</a>. In that article I mentioned the ability to customize the display in the GUI for the merged log files.</p>
<p>Today, I am going to explore how to configure the GUI with filters and different column sets or orders. To proceed, it will require a refresher course via the prior article. If you need a primer in how to merge the XEL files, or to open the XEL files from within the GUI, I recommend taking the time now to read that <a href="http://bit.ly/1NQBYjr">prior article</a>.</p>
<h3>Getting Sticky Again</h3>
<p>This should be a rather quick foray into the world of the GUI and how to customize. Just bear in mind that it is a small building block.</p>
<p>Taking up from the prior article, I will continue to use the same sample session and sample data.</p>
<p>Let&#8217;s start with a screenshot where we left off the last time:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display.jpg" rel="attachment wp-att-3332"><img loading="lazy" class="alignnone wp-image-3332 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-969x1024.jpg" alt="merge_gui_display" width="560" height="592" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-969x1024.jpg 969w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-284x300.jpg 284w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-768x812.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-47x50.jpg 47w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display.jpg 979w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>By itself, this is not the prettiest of layouts. Sure there is good information, but the layout is rather simple and leaves one wanting more. The &#8220;more&#8221; comes easily enough after some familiarity with the GUI. Suppose you desire to change the order of the columns presented in this view, or to even select different columns, there are two methods to achieve that goal. The first option would be to do as shown here:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options.png" rel="attachment wp-att-3337"><img loading="lazy" class="alignnone wp-image-3337 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options-1024x283.png" alt="method1_xe_gui_options" width="560" height="155" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options-1024x283.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options-300x83.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options-768x212.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options-50x14.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method1_xe_gui_options.png 1702w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>By right clicking an empty space in the title bar, a context menu will be made available. There are several options here that can be a bit fun to peruse. I will just focus on the &#8220;Choose Columns&#8221; option for now.</p>
<p>The alternative for this method is to look in the toolbar. There will be an XE specific toolbar available when looking at an XE log file. In this toolbar there is a &#8220;Choose Columns&#8221; button. This method will get us to the same end result as the first.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options.png" rel="attachment wp-att-3338"><img loading="lazy" class="alignnone wp-image-3338 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options-1024x77.png" alt="method2_xe_gui_options" width="560" height="42" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options-1024x77.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options-300x23.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options-768x58.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/method2_xe_gui_options.png 1329w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Selecting the &#8220;Choose Columns&#8221; from either method just presented will open a new window such as the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns.jpg" rel="attachment wp-att-3339"><img loading="lazy" class="alignnone wp-image-3339 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns-1024x659.jpg" alt="choosecolumns" width="560" height="360" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns-1024x659.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns-300x193.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns-768x495.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns-50x32.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/choosecolumns.jpg 1202w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This kind of screen should be fairly familiar and easily discernible. One the left is a set of available columns that can be added in the display. On the right is the list of columns currently being displayed in tabular format. In between there is a set of buttons to add, remove, add all, or remove all columns. In the top right is a means of re-ordering the columns as presented in the display table. Pick a few and sort the columns to a suitable display mode and you are all set.</p>
<p>Recall from the image showing method one that there is an option to remove the column. This same function can be performed from the context menu or from this &#8220;Choose Columns&#8221; window.</p>
<p>For the order of the columns, there is another fancy means to do that as well other than through the &#8220;Choose Columns&#8221; window. Columns can be dragged and dropped from the initial screen to change the presentation order easily enough. Sometimes it is far easier to use the &#8220;Choose Columns&#8221; window to do that. Pick your poison here and run with it.</p>
<h3>Super Stickey</h3>
<p>This is fantastic if the manipulation of the display settings is a one-off adventure. What if you need to do this multiple times? Maybe, just maybe, this needs to be done for 100 servers. The process I have just shown can become exceedingly tedious. In addition, every time an XEL file is opened, it defaults back to the same settings I have already shown. What do you do in cases like that?</p>
<p>Beyond using a script (the recommended method by the way), there is an alternative.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options.png" rel="attachment wp-att-3340"><img loading="lazy" class="alignnone wp-image-3340 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options-1024x77.png" alt="displaysett_xe_gui_options" width="560" height="42" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options-1024x77.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options-300x23.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options-768x58.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options-50x4.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/displaysett_xe_gui_options.png 1329w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The alternative is found in the toolbar discussed earlier in this article. The option is &#8220;Display Settings.&#8221; After picking the columns and the order and getting the display dialed in just right, the view can be saved. The view settings will be saved as an XML file with the extension of viewsetting. This view can then be used to immediately apply to a freshly opened log file. Sure it is still an extra step or two to open that view and can still become a bit tedious, but it is far better than resetting the view every time. And a bonus is that the saved viewsetting file will also save merged columns, groupings, aggregations, column order, and filters defined in the view.</p>
<p>Then again, all of this is easily achieved through a tsql script which is far more scalable when dealing with multiple servers or the need to review the data more than once. The choice is yours when using XE.</p>
<p>Though I mentioned the creation of a filter for the displayed log data, I will not be delving into that topic today. It would be a very suitable exercise for the reader to figure out how to apply a filter through this tool. Or wait until the next time when that topic will be covered along with aggregations and groups. In the meantime, I recommend trying to figure it out with a little picking and plucking through the GUI-ness.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3334" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/12/31/customize-the-xevent-log-display/">Customize the XEvent Log Display</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/12/31/customize-the-xevent-log-display/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Log Files from Different Sources</title>
		<link>https://jasonbrimhall.info/2015/12/30/log-files-different-sources/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=log-files-different-sources</link>
					<comments>https://jasonbrimhall.info/2015/12/30/log-files-different-sources/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 30 Dec 2015 12:52:08 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3324</guid>

					<description><![CDATA[<p>While working with Extended Events, or with any sort of logging or tracing utility, it becomes critical to consume the data from disparate sources or even to consume the data from a source server on a different server.</p>
The post <a href="https://jasonbrimhall.info/2015/12/30/log-files-different-sources/">Log Files from Different Sources</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Well, it has been quite a pause between articles in the series. It is well past time to continue the series. With such a delay in the series, it is prudent to remind all that there is a series on Extended Events I had done over the course of two months. <a href="http://bit.ly/XE60Days">The complete table of contents for this series can be found here</a>. <a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log.jpg" rel="attachment wp-att-1799"><img loading="lazy" class=" wp-image-1799 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log-300x225.jpg" alt="yule log" width="247" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log-300x225.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log.jpg 384w" sizes="(max-width: 247px) 85vw, 247px" /></a>Truth be told, I had intended to start this series again as my usual 12 days of Christmas series. Sadly, I am a bit behind on that series. Maybe some of there will be multiple posts a day to help catch up.</p>
<p>As was the case throughout the course of the series, I intend over the next few articles to continue to produce building blocks that may be helpful for later articles, or concepts. With that in mind, the chosen topic today is very basic in nature. While basic, it is a rather important topic.</p>
<p>While working with Extended Events, or with any sort of logging or tracing utility, it becomes critical to consume the data from disparate sources or even to consume the data from a source server on a different server. The question becomes: How to consume that data?</p>
<h3>Getting Sticky</h3>
<p>When it comes to working with log files from different sources, or most tasks within SQL Server for that matter, there are two general methods. The first method is of the type frequently frowned upon by the more senior of database professionals, sysadmins and so forth. This first method is to use the graphical user interface or GUI. This is more of a point and click method. This is also a method that I will generally shy away from for most tasks. That said, this method is easily performed through the GUI and is reasonably safe.</p>
<p>The first step is illustrated with the following image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge.jpg" rel="attachment wp-att-3331"><img loading="lazy" class="aligncenter wp-image-3331 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge-1024x692.jpg" alt="XE_merge" width="560" height="378" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge-1024x692.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge-300x203.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge-768x519.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge-50x34.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge.jpg 1317w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From within Management Studio, navigate the file menu as shown in the preceding image. After clicking on &#8220;Merge Extended Event Files&#8221;, a dialog will open as shown (in the background) of the next image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog.png" rel="attachment wp-att-3329"><img loading="lazy" class="aligncenter wp-image-3329 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog-1024x754.png" alt="XE_merge_opendialog" width="560" height="412" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog-1024x754.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog-300x221.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog-768x566.png 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog-50x37.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/12/XE_merge_opendialog.png 1481w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Clicking add from the &#8220;Merge Extended Event Files&#8221; window will open a dialog that permits you to navigate to the location of the XEL files that need to be opened and merged. Once located, a single file or multiple files can be selected. One should proceed carefully here to ensure against opening too many files or files that may be too large. Opening too many files or files that are too large can cause various unwanted effects.</p>
<p>Once the file(s) is(are) open, a grid like window will be open in SSMS that looks like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display.jpg" rel="attachment wp-att-3332"><img loading="lazy" class="aligncenter wp-image-3332 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-969x1024.jpg" alt="merge_gui_display" width="560" height="592" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-969x1024.jpg 969w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-284x300.jpg 284w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-768x812.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display-47x50.jpg 47w, https://jasonbrimhall.info/wp-content/uploads/2015/12/merge_gui_display.jpg 979w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From here, one can manipulate the display to something more suitable to his/her display preferences (e.g. filtering or column layout). I will not cover that here but will be saving it (the display customization tutorial) for another time. That aside, I have just shown how easy it is to look into an Extended Event Log file through the use of the GUI.</p>
<h3>Not So Sticky</h3>
<p>For the less sticky  (less GUI) method, I have shown a similar routine in the past that lays the groundwork for how to do this via script. You can read a little about that <a href="http://bit.ly/1Qwycff">here</a>. Building on that method, there is a tweak to be made &#8211; we must specifically name the path to the XEL files to be <em>merged</em> rather than try to build it dynamically.</p>
<p>Using the same session files as shown in the GUI examples, I will show how to proceed with the <em>merge</em> via script.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* xel and xem are required for 2008 and r2 even if using sql 2012 or later to interpret the data
files copied down from remote server 
*/
INSERT into DBA.dbo.SlowQueriesXE
SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name,''
	FROM sys.fn_xe_file_target_read_file(
		--xel path xel = extended event log
		'G:\Database\XE\XE\SlowQueries*.xel'
		--mdpath or xem path xem = extended event metadata
		,	'G:\Database\XE\XE\SlowQueries*.xem'
		--initial file name
		, NULL
		--initial file offset
		, NULL) t2
GO</pre><p>This script lays out a rather simple process. That process being to load the log data into a table (in a database of your choosing) and then once loaded, query the data to better understand what has been captured. In the preceding script I left a few notes. It is important to understand that if trying to pull in the logs from a SQL 2008 or R2 instance then the XEM file must be included (as I have done for this particular example).</p>
<p>To parse the data into a friendly format that I can use for analysis, I would do something like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT pars.*, map.map_value
	FROM (
		SELECT x.event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
				--, xe.event_data.value('(@package)[1]', 'varchar(50)') AS package_name
				, DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP),
							x.event_data.value('(event/@timestamp)[1]', 'datetime2')) AS [timestamp]
				, x.event_data.value('(event/action[@name="sql_text"]/value)[1]',
									'varchar(max)') AS sql_text
				, x.event_data.value('(event/action[@name="session_id"]/value)[1]',
									'varchar(max)') AS session_id		
				, x.file_offset,x.predicate--,x.file_name
				,event_data.value('(event/data[@name="cpu_time"]/value)[1]','bigint') AS cpu_time
				,event_data.value('(event/data[@name="duration"]/value)[1]','bigint') AS duration
				,event_data.value('(event/data[@name="physical_reads"]/value)[1]','bigint') AS physical_reads
				,event_data.value('(event/data[@name="logical_reads"]/value)[1]','bigint') AS logical_reads
				,event_data.value('(event/data[@name="writes"]/value)[1]','bigint') AS writes
				,event_data.value('(event/data[@name="row_count"]/value)[1]','bigint') AS row_count
				,event_data.value('(event/data[@name="result"]/value)[1]','varchar(max)') AS result
				, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@handle)[1]','varchar(max)') AS stackhandle
				, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@offsetStart)[1]','bigint') AS stackoffset
				, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@offsetEnd)[1]','bigint') AS stackoffsetend
				--, x.event_data
			FROM DBA.dbo.SlowQueriesXE x) pars
		LEFT OUTER JOIN (SELECT oc.object_name as EventName,oc.name as ColName,mv.name as MapName, map_key, map_value 
							FROM sys.dm_xe_map_values mv
								Inner Join sys.dm_xe_object_columns oc
									on mv.name = oc.type_name
									AND mv.object_package_guid = oc.object_package_guid
							WHERE oc.object_name = 'sql_batch_completed'
								AND oc.column_type &lt;&gt; 'readonly'
							) map
			ON pars.result = map.map_key;</pre><p>From here it is really easy to add/remove columns or re-order the columns into a more friendly format for the person reviewing the data. This is incredibly easy &#8211; especially given the appropriate recipe / script / process. I would also venture that this method will require fewer resources and lead to less chance of error.</p>
<p>Enjoy working with evaluating and merging these XEL files from different sources. It should be fun!</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3324" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/12/30/log-files-different-sources/">Log Files from Different Sources</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/12/30/log-files-different-sources/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tricks and Treats with XE</title>
		<link>https://jasonbrimhall.info/2015/10/30/tricks-and-treats-with-xe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tricks-and-treats-with-xe</link>
					<comments>https://jasonbrimhall.info/2015/10/30/tricks-and-treats-with-xe/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 30 Oct 2015 12:30:44 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3310</guid>

					<description><![CDATA[<p>With the proximity to Halloween, it's not hard (knowing me) to figure out why I originally decided to terminate this series on the Eve of Halloween day. Join me as I share some treats and a trick to use with Extended Events.</p>
The post <a href="https://jasonbrimhall.info/2015/10/30/tricks-and-treats-with-xe/">Tricks and Treats with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Halloween is a great time of year. It is unfortunate that it is just one day of the year. That said, I do like to think of the <img loading="lazy" class="wp-image-2529 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-173x300.png" alt="phantasmrip" width="151" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-173x300.png 173w, https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-28x50.png 28w, https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip.png 376w" sizes="(max-width: 151px) 85vw, 151px" />month of October as Halloween Month. I have several posts over the years that geek out over the cross-over between Halloween and SQL Server.</p>
<p>With the proximity to Halloween, it&#8217;s not hard (knowing me) to figure out why I originally decided to terminate this series on the Eve of Halloween day. Then again, as it turns out, I decided to bring the series back to life on the other side of Halloween. In short, it was to be killed on Halloween Eve and then implicitly converted to some living dead creature. You pick whether it is a zombie (which is far better suited to SQL Server) or a vampire.</p>
<p>If you are interested in the previous Halloween posts, here is a list of a few of them:</p>
<h3>XE Related</h3>
<p><a href="http://bit.ly/ssgghost">Ghosts in your Database I</a></p>
<p><a href="http://bit.ly/rnnrGhosts1">Ghosts in your Database II</a></p>
<p><a href="http://bit.ly/rnnrGhosts2">Ghosts &#8211; an eXtrasensory Experience</a></p>
<h3>DB and Fun Related</h3>
<p><a href="http://jasonbrimhall.info/?s=halloween">All Halloween posts</a></p>
<p>That list is my Halloween treat this year. Now for the trick with a very strong warning. Because of this warning, I am not posting any code showing how to perform the trick.</p>
<h2>Warning</h2>
<p><span style="color: #ff0000;"><em><strong>DO NOT ATTEMPT THIS ON ANY PRODUCTION SERVER. I BEAR NO RESPONSIBILITY FOR ANY PRODUCTION SERVER CHANGES DUE TO THE READING OF THIS ARTICLE (OR ANY OTHER ARTICLE I HAVE WRITTEN). SOLE RESPONSIBILITY OF CHANGES OR ACTIONS TAKEN BELONG TO THE PERSON PERFORMING THE ACT OR CHANGE. IN OTHER WORDS, YOU ARE SOLELY RESPONSIBLE FOR BREAKING YOUR PRODUCTION ENVIRONMENT IF YOU IMPLEMENT THIS IN PRODUCTION!!!</strong></em></span></p>
<p>I have debated seriously over even publishing this &#8220;trick&#8221; for Halloween because of how deliciously evil it is. I will try and paint the picture in broad strokes. I will leave it up to you to connect the dots.</p>
<h3>Problem</h3>
<p>A third party vendor has provided an application along with some database requirements. Among these requirements is that the application account must use the &#8216;sa&#8217; login. You have a strict policy that &#8216;sa&#8217; must never be used for any applications or by the end-users. This is an extremely protected account by policy. The dilemma you have been presented is that the CEO insists that this application must be used (never happens right?) and the vendor insists the application will not function properly without the use of &#8216;sa&#8217; (I can hear you chortle at that).</p>
<p>Now you, as the DBA, are stuck between a rock and an even harder place. Being smart (and somewhat smart and sadistic), you insist that the use of the &#8216;sa&#8217; login should not be performed because it will break SQL Server (in reality we know the login does not break SQL Server, but something inevitably will break due to a mis-step by the person using it a) when they shouldn&#8217;t, and b) because they lack proper training). Inside you are grinning from ear to ear because you have some devilish ideas, some of which you learned by attending a <a href="http://www.sqlsaturday.com/446/Sessions/Details.aspx?sid=38088">session</a> by Rob Volk (<a href="https://twitter.com/sql_r">twitter</a>) where he shows some devilish methods to deter the use of &#8216;sa&#8217;.</p>
<p>For the sake of the scenario, let&#8217;s just say you have a policy preventing the implementation of logon triggers (as suggested by Rob) due to a couple of mishaps a few months back. Somebody implemented a logon trigger that wasn&#8217;t properly configured and it happened to prevent all users from accessing the server (including the dba&#8217;s). Ruh roh!</p>
<h3>And then&#8230;</h3>
<p>Later in the week, after reading about the power of Extended Events, you decide to play around and do a little discovery. You come across <a href="http://bit.ly/1NjPjBk">this blog post</a> that shows you how to find all of the possible events within the XEvent Engine. So you run the script that you found and shown here:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xo.name AS EventName, xo.description
	FROM sys.dm_xe_objects xo
	WHERE xo.object_type = 'event'
		AND (xo.capabilities_desc &lt;&gt; 'private'
		OR xo.capabilities_desc IS NULL)
	ORDER BY xo.name;</pre><p>And while looking through the events and descriptions you discover that there is an event to log all of the successful logins. Not thinking anything of the third party vendor (because it just makes your blood boil) you begin to dream of the potential for auditing all successful logins (established connections) for all users and documenting who may be doing what and when.</p>
<p>After taking a few notes about the potential for the login event and getting access and logins under better control, you continue along your journey through Extended Events by reading <a href="http://bit.ly/1F0b2x1">this article</a> about Actions. Feeling comfortable enough from the article, you do what any good data professional, trying to learn a new topic, would do &#8211; you start exploring using the provided query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xp.name AS PackageName
		, xo.name AS ActionName
		, xo.description AS ObjDescription
		, xo.capabilities_desc
	FROM sys.dm_xe_packages AS xp
		INNER JOIN sys.dm_xe_objects AS xo
			ON xp.guid = xo.package_guid
	WHERE ( xp.capabilities IS NULL
			OR xp.capabilities &amp; 1 = 0
			)
		AND ( xo.capabilities IS NULL
				OR xo.capabilities &amp; 1 = 0
			)
		AND xo.object_type = 'action'
	ORDER BY ActionName, PackageName;</pre><p>While looking through the available actions, you see one in particular that causes you to <a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/mangled.png"><img loading="lazy" class=" wp-image-3314 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-300x300.png" alt="mangled" width="196" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/mangled.png 600w" sizes="(max-width: 196px) 85vw, 196px" /></a>raise an eyebrow (not both, just one). There is an action called &#8220;debug_break&#8221;. You squirm and ponder for quite a bit at the name and definition of this particular object. You wonder out loud &#8220;why would anybody ever want that in there?&#8221;</p>
<p>Your co-worker interrupts with &#8220;Do what?&#8221;</p>
<p>To which you reply &#8220;Oh nothing important. It was just something I read.&#8221; After which you dismiss it, realize the time of day, pack up and head home for the evening. Hours later after the work day has long since been finished, you awaken in a cold sweat with an &#8220;Aha!&#8221; that startles your slumbering neighbors dog. Immediately you pull out your laptop, connect to your local sandbox instance and get to work with a wry smile and devious giggle.</p>
<p>Upon returning to work the next day, you call the vendor and work out a solution to build them a sandbox server to provide a proof of concept. You grant them the use of sa to use for their application login. Sitting down together and connected to the new sandbox, the vendor attempts to login and the following happens:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke.jpg"><img loading="lazy" class="alignnone wp-image-3315 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke-1024x159.jpg" alt="DEBUG_broke" width="560" height="87" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke-1024x159.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke-300x47.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke-50x8.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/DEBUG_broke.jpg 1402w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Slack-jawed and speechless the vendor pales in complexion. Deep down inside you giggle like an elementary grade school girl &#8211; content with yourself. BATTLE WON!</p>
<p>After the vendor departs with a promise to rework the security requirements, you restart the service on the sandbox and go about the rest of your work week with a silly grin from ear to ear and nobody the wiser.</p>
<p>That concludes the trick. In the tradition of Halloween, you knocked on my virtual door of Extended Events and I, in accordance with the traditions of Halloween, gave you a trick and a treat.</p>
<p>I hope this helps you to understand the power of Extended Events. Thinking through a problem and reaching a solution is what XEvents can help to provide. I hope this Halloween XE article was enjoyable to you. Stay tuned as the XE 60 Day series goes full Zombie starting next week.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3310" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/30/tricks-and-treats-with-xe/">Tricks and Treats with XE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/30/tricks-and-treats-with-xe/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Default Sessions</title>
		<link>https://jasonbrimhall.info/2015/10/29/default-sessions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=default-sessions</link>
					<comments>https://jasonbrimhall.info/2015/10/29/default-sessions/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 29 Oct 2015 13:00:18 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3295</guid>

					<description><![CDATA[<p>The focus of this article will be to introduce the default sessions deployed with SQL Server. Some of these are internal and "private" while others are more "public" and like a user defined session.</p>
The post <a href="https://jasonbrimhall.info/2015/10/29/default-sessions/">Default Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="size-medium wp-image-3297 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/defaults-300x195.png" alt="defaults" width="300" height="195" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/defaults-300x195.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/defaults-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/defaults.png 551w" sizes="(max-width: 300px) 85vw, 300px" />So I have blasted through a lot of technical articles about Extended Events. There is a lot of groundwork that has been covered with layers of building blocks that have been stacked. Now it&#8217;s time to take a step back as I near the end of the original goal for this series.</p>
<p>I say original goal, but that really only means the goal pertaining to the length of the series. I had a goal for content that has yet to be reached. Due to that, I have pushed the series into overtime. So, really, that means this is merely a step back to a lighter topic today as I jump into half-time (or something like that) of the series.</p>
<h2>Default Sessions</h2>
<p>In the previous article I mentioned some of the default sessions for Azure SQL Database. I will not be going into any further detail about those sessions at this time. Discussion on those default sessions will have to be reserved for a later date.</p>
<p>The focus of this article will be to introduce the default sessions deployed with SQL Server. Some of these are internal and &#8220;private&#8221; while others are more &#8220;public&#8221; and like a user defined session.</p>
<h3>system_health</h3>
<p>The system_health default session is the most common of all of the default sessions. This session is akin to a true black box recorder in SQL Server. There is a ton of information that can be trapped via this event session. One caveat to this session is that if you are looking at the session in SQL Server 2008/R2 then the session really should be modified to include a file target.</p>
<h3>sp_server_diagnostics session</h3>
<p>The name of this session almost gives it away. This is an internal private session that executes a stored procedure by the same name: sp_server_diagnostics. Since it is a private internal session, I do not have all of the details on the internals. But since it is related to the sp_server_diagnostics stored procedure, it isn&#8217;t hard to make the leap at what it does. In addition, there are some events with a similar name which helps to better understand what is happening here.</p>
<p>The sp_server_diagnostics stored procedure captures diagnostic and health information about SQL Server to help alert to potential failures. This procedure runs continuously in repeat mode. Here are some of the results from my laptop for this procedure:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics.jpg"><img loading="lazy" class="alignnone wp-image-3301 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics-1024x184.jpg" alt="sp_server_diagnostics" width="560" height="101" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics-1024x184.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics-300x54.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics-50x9.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics.jpg 1466w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Notice there are five different domains of interest in this result set. If I look at the events by the same namesake, I will see the following possible data points:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe.jpg"><img loading="lazy" class="alignnone wp-image-3302 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe-1024x168.jpg" alt="sp_server_diagnostics_result_xe" width="560" height="92" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe-1024x168.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe-300x49.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe-50x8.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xe.jpg 1371w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Wait, there&#8217;s more! Diving in deeper into the event, I can see the following possible component_names / domains for the maps in this event:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap.png"><img loading="lazy" class="alignnone wp-image-3303 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap-1024x319.png" alt="sp_server_diagnostics_result_xemap" width="560" height="174" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap-1024x319.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap-300x94.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap-50x16.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/sp_server_diagnostics_result_xemap.png 1851w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this last result set, there are multiple data points that map back directly to the stored procedure. In addition to the direct mapping, this result demonstrates the additional domains of &#8220;AGS&#8221; and &#8220;LAST&#8221;. I don&#8217;t have any AGS created on this machine so no stats would be recorded for that. I don&#8217;t know what &#8220;LAST&#8221; represents. Then the sp_server_diagnostics_state maps directly to the &#8220;state&#8221; seen in the stored procedure.</p>
<p>Having this same information divulged via extended events doesn&#8217;t end here. The system_health session collects the sp_server_diagnostics_component_result event by default. This all ties together back to the &#8220;sp_server_diagnostics session&#8221; which appears to be the manifestation of the &#8220;repeat mode&#8221; of the sp_server_diagnostics extended stored procedure. The proc is continuously running and gathering data for the event to trap the information and subsequently send it along to the event session targets.</p>
<h3>hkenginexesession</h3>
<p>The internals of this session are the hardest to track down. This is an internal private session. The name of the session does reveal a fair amount of information about the session that can be used to make decent educated guesses at what is being done here. First this session is used for monitoring In-memory OLTP / hekaton / hk (for short) tables and natively compiled stored procedures.</p>
<p>Taking the knowledge that this is used to monitor the &#8220;hekaton&#8221; engine, one can also deduce that the possible list of events comes from the following (probably others involved too):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events.jpg"><img loading="lazy" class="alignnone wp-image-3305 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events-1024x830.jpg" alt="hekaton_events" width="560" height="454" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events-1024x830.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events-300x243.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events-50x41.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/hekaton_events.jpg 1593w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>A more complete list of events that seem to fit for this session can be retrieved via the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT name AS EventName
		, description AS EventDescription
	FROM sys.dm_xe_objects
	WHERE object_type = 'event'
		AND ( name LIKE '%xtp%'
				OR name LIKE '%hekat%'
				OR description LIKE '%hk%'
				OR description LIKE '%hekaton%'
				OR description LIKE '%native%'
				OR description LIKE '%memory%oltp%'
			)
	ORDER BY name;</pre><p>The final piece of interesting information is that this session appears to be tied to the following dll: hkengine.dll. This is a dll that is loaded in SQL Server and it does bear the same naming convention. Here is another query that will show if this dll is loaded:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
	FROM sys.dm_os_loaded_modules olm
	WHERE olm.name LIKE '%hke%';</pre><p>This session is only available as of SQL Server 2014.</p>
<h3>AlwaysOn_health</h3>
<p>The AlwaysOn_health session is very much like the system_health default session. This is a default session that can be scripted from within SQL Server Management Studio. Think of this session as a black box recorder for your Availability Groups. This session will capture events related to the state of the AG replica, if there is a state change, any errors that occur, and failovers that occur.</p>
<p>To get a grasp of what this particular session does (try and figure out a query to accomplish this before proceeding), one can run the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sese.name AS EventName, xo.description AS EventDescription
	FROM sys.server_event_session_events sese
		INNER JOIN sys.server_event_sessions ses
			ON sese.event_session_id = ses.event_session_id
		INNER JOIN sys.dm_xe_objects xo
			ON sese.name = xo.name
	WHERE ses.name = 'AlwaysOn_health'
		AND xo.object_type = 'event';</pre><p>And the results would be:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events.jpg"><img loading="lazy" class="alignnone wp-image-3304 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events-1024x241.jpg" alt="alwayson_events" width="560" height="132" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events-1024x241.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events-300x71.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events-50x12.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/alwayson_events.jpg 1884w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Bonus points if you recognized this could be done based on the foundations pieces laid out in previous articles.</p>
<p>This session became available as of SQL Server 2012.</p>
<p>The default sessions in SQL Server cover a lot of points of interest when looking to monitor a database environment. Between these sessions, this is quite a significant black box recorder for SQL Server. Despite the quantity of events that these sessions combine to monitor as your black box recorder, it doesn&#8217;t mean that you can&#8217;t add more events to monitor. That is the power of Extended Events. It is also important to remember that these sessions are <em>default</em> sessions. What do we like to do with most defaults? That&#8217;s right, we tweak it to be more specific to our own environments.</p>
<p>I hope you enjoyed the article, even without the dive into the default sessions of Azure SQL Database. Stay tuned because those sessions may be covered in some future article.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3295" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/29/default-sessions/">Default Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/29/default-sessions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Azure SQL Database</title>
		<link>https://jasonbrimhall.info/2015/10/28/azure-sql-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=azure-sql-database</link>
					<comments>https://jasonbrimhall.info/2015/10/28/azure-sql-database/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 28 Oct 2015 13:14:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3284</guid>

					<description><![CDATA[<p>What hasn't received any TLC is Extended Events from the Azure SQL Database perspective. You may be wondering why it matters since I just said that Extended Events is the same in an SQL Server in an Azure VM as it is on-premises. That is Azure and that is the cloud right?</p>
The post <a href="https://jasonbrimhall.info/2015/10/28/azure-sql-database/">Azure SQL Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>So far I have strictly focused on Extended Events for SQL Server installations. This means I have <a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/db_cloud_green.png"><img loading="lazy" class="wp-image-3285 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/db_cloud_green-300x238.png" alt="db_cloud_green" width="234" height="186" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/db_cloud_green-300x238.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/db_cloud_green-50x40.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/db_cloud_green.png 434w" sizes="(max-width: 234px) 85vw, 234px" /></a>been looking at Extended Events from the &#8220;physical&#8221; or on-premises perspective. Installing SQL Server into an Azure VM falls into this category as well.</p>
<p>What hasn&#8217;t received any TLC is Extended Events from the Azure SQL Database perspective. You may be wondering why it matters since I just said that Extended Events is the same in an SQL Server in an Azure VM as it is on-premises. That is Azure and that is the cloud right?</p>
<p>Well, not entirely. Azure SQL Database works quite a bit differently. Azure SQL Database introduces some things into Extended Events that basically turn your XEvent world upside down. Sort of. If you understand that Azure SQL Database is a contained database (in concept), then some of this world flipping I mentioned is merely a tilt and not terribly earth shattering. That said, it does require at least a little bit of attention. Today, I will merely introduce some of the differences and then leave the internals for a later time.</p>
<h2>Azure SQL Database</h2>
<h3>Metadata</h3>
<p>Azure SQL Database uses some of the same dynamic management views(DMVs) and catalog views as SQL Server. I covered those DMVs and catalog views in previous articles <a href="http://bit.ly/1Uu4QyY">here</a> and <a href="http://bit.ly/1XfzO27">here</a> &#8211; respectively. For the most part, Azure SQL Database uses a different set of views though. Some of the views of interest for querying metadata are listed in the following tables:</p>
<h4>Running Sessions</h4>
<table>
<thead>
<tr>
<td align="left" width="290"><strong>DMV</strong></td>
<td align="left"><strong>Description</strong></td>
</tr>
</thead>
<tbody>
<tr>
<td align="left">sys.dm_xe_database_session_event_actions</td>
<td align="left">Info about actions within active event sessions</td>
</tr>
<tr>
<td align="left">sys.dm_xe_database_session_events</td>
<td align="left">Info about events within active event sessions</td>
</tr>
<tr>
<td align="left">sys.dm_xe_database_session_object_columns</td>
<td align="left">Info about event payload for events in an event session</td>
</tr>
<tr>
<td align="left">sys.dm_xe_database_session_targets</td>
<td align="left">Info about targets within active event sessions</td>
</tr>
<tr>
<td align="left">sys.dm_xe_database_sessions</td>
<td align="left">Returns a row for each active database scoped event session.</td>
</tr>
</tbody>
</table>
<p>Looking at the names in the list they should be pretty familiar at this point. The real difference is that these are scoped to the database whereas SQL Server is not scoped in the same manner. This is an essential distinction due to the way Azure SQL Database works.</p>
<h4>Deployed Sessions</h4>
<table>
<thead>
<tr>
<td align="left" width="290"><strong>Catalog View</strong></td>
<td align="left"><strong>Description</strong></td>
</tr>
</thead>
<tbody>
<tr>
<td align="left">sys.database_event_session_actions</td>
<td align="left">Info about actions within deployed event sessions</td>
</tr>
<tr>
<td align="left">sys.database_event_session_events</td>
<td align="left">Info about events within deployed event sessions</td>
</tr>
<tr>
<td align="left">sys.database_event_session_fields</td>
<td align="left">Returns a row for each customize-able column that was explicitly set on events and targets.</td>
</tr>
<tr>
<td align="left">sys.database_event_session_targets</td>
<td align="left">Info about targets within deployed event sessions</td>
</tr>
<tr>
<td align="left">sys.database_event_sessions</td>
<td align="left">Returns a row for each event session in the SQL Database database.</td>
</tr>
</tbody>
</table>
<p>These particular catalog views should also seem somewhat familiar. The major difference in name being that they are scoped to the database instead of server just like the DMVs.</p>
<h4>XE Internals Metadata</h4>
<table>
<tbody>
<tr>
<td align="left" width="290">sys.dm_xe_map_values</td>
<td align="left">Returns mappings of internal keys to text</td>
</tr>
<tr>
<td align="left">sys.dm_xe_object_columns</td>
<td align="left">Metadata for object data definitions</td>
</tr>
<tr>
<td align="left">sys.dm_xe_objects</td>
<td align="left">Metadata for different available objects within XE Engine</td>
</tr>
<tr>
<td align="left">sys.dm_xe_packages</td>
<td align="left">Listing of packages registered within XE Engine</td>
</tr>
</tbody>
</table>
<p>And lastly, these are all the same between SQL Server and Azure SQL Database. If you have been following along with the series, these views really should come as no big surprise and there should be a base familiarity with them. That familiarity is part of the reasoning for skipping a deep dive at the moment.</p>
<h4>Storage</h4>
<p>Azure SQL Database still give the possibility of storing event data in multiple different types of targets. Not all standard public targets are available for user defined sessions. One can currently use the ring_buffer, event_counter, and event_file targets. This provides for two different memory type of targets and one file target. The file target does not come without a cost though. To use the file target does require access to an Azure Storage Container and will take some extra effort to properly configure.</p>
<h4>Default Sessions</h4>
<p>Azure SQL Database also comes with a set of default sessions automatically configured. Not all are running just like in SQL Server, but they are deployed. Even though several sessions are deployed by default, there is a limitation to how many can be running at a time (subject to change). The default sessions are (subject to change):</p>
<ul>
<li>azure_xe_activity_tracking</li>
<li>azure_xe_errors_warnings</li>
<li>azure_xe_object_ddl</li>
<li>azure_xe_post_query_detail</li>
<li>azure_xe_pre_query_detail</li>
<li>azure_xe_query</li>
<li>azure_xe_query_batch</li>
<li>azure_xe_query_detail</li>
<li>azure_xe_query_execution</li>
<li>azure_xe_query_waits</li>
<li>azure_xe_query_waits_detail</li>
<li>azure_xe_waits</li>
</ul>
<h4>Consistency</h4>
<p>Despite these differences, there is a fair amount of consistency. Discovery of objects and metadata still remains the same. Being able to query the metadata for running or deployed sessions is also in line with the previous articles I have written in this series. In short, despite the slim differences (subject to change) and the platform differences between SQL Server and Azure SQL Database, there are still consistencies and common building block practices that I have shown still apply.</p>
<h3>Scoping</h3>
<p>Even though there is a great amount of consistency throughout the extended events engine and between these two disparate platforms (SQL Server and Azure SQL Database), there is one glaring difference that must be discussed. I showed that the catalog views and DMVs are scoped to the database instead of server. Guess what that means for creating the actual session? You got it! An Extended Event Session is scoped/created at the database level rather than the server level. This is done easily as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE
    EVENT SESSION myAzureDBScopedXESession
    ON DATABASE
    ADD EVENT ...</pre><p>As I have said, I am not going to go deep into the details and inner working of Extended Events in Azure SQL Database at the moment. I will save those deeper dives for a later time. What I have done at this point is to introduce the basic differences and introduce the realm of XE in Azure SQL Database to you. Don&#8217;t be afraid to use Azure SQL Database based off a previous limitation around Extended Events. Things are changing in the cloud and they are changing at a rapid rate.</p>
<p>&nbsp;</p>
<p>I hope you enjoyed the article.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3284" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/28/azure-sql-database/">Azure SQL Database</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/28/azure-sql-database/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Exposure to Internals</title>
		<link>https://jasonbrimhall.info/2015/10/27/exposure-to-internals/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exposure-to-internals</link>
					<comments>https://jasonbrimhall.info/2015/10/27/exposure-to-internals/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 27 Oct 2015 13:00:14 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3276</guid>

					<description><![CDATA[<p>The premise of the article today is to get a little exposure to some of the internals that may cause a bit of curiosity for you. I will share a means to expose some of the settings/stages/steps of various internal processes. These are the sorts of things you may have heard about, but without Extended Events, you might have to dig harder and further to find them.</p>
The post <a href="https://jasonbrimhall.info/2015/10/27/exposure-to-internals/">Exposure to Internals</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/07/engine_indb.png"><img loading="lazy" class="wp-image-2788 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/07/engine_indb-258x300.png" alt="engine_indb" width="140" height="163" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/07/engine_indb-258x300.png 258w, https://jasonbrimhall.info/wp-content/uploads/2015/07/engine_indb-43x50.png 43w, https://jasonbrimhall.info/wp-content/uploads/2015/07/engine_indb.png 449w" sizes="(max-width: 140px) 85vw, 140px" /></a>For me, some of the most fun stuff with SQL Server is diving deep into the internals. Diving into the internals is not always an easy adventure. Sometimes, it requires a lot of trial and error sometimes. There are times where a dive into the internals can get me &#8220;into the weeds&#8221;, &#8220;down a rabbit hole&#8221; on a long windy path with no end in sight. Granted the end usually comes, but you get the idea.</p>
<p>That said, today I am not taking you on one of those journeys. The premise of the article today is to get a little exposure to some of the internals that may cause a bit of curiosity for you. I will share a means to expose some of the settings/stages/steps of various internal processes. These are the sorts of things you may have heard about, but without Extended Events, you might have to dig harder and further to find them.</p>
<h3>Exposure to Internals</h3>
<p>There are numerous events within the Extended Event engine that expose internals and internal operations. I will not be exploring the internals via actual events. That would be too easy! I want to share the internals available to you not via events, but rather other objects from the engine. Today, all of the internals will be exposed via the &#8220;custom&#8221; data types. More in-line with the official terminology is that these will be exposed via &#8220;Maps&#8221;.</p>
<p>The beauty of the maps is that these are free-floating maps. None of them are currently tied to an event. So trying to find an event that will help track these internals is just not going to happen. <em><strong>/* Disclaimer: This is only relevant to current versions. This is something that could change in future versions. */</strong></em></p>
<p>Knowing those pieces of information, the dive into the internals becomes far easier now. I know (based on prior articles in the series) that maps are exposed via sys.dm_xe_map_values. Since they are not tied to events, I also know that there are currently no fields using the maps within sys.dm_xe_object_columns. Now I want to look at all the possible internals that are tied to maps. This can be done via the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT xmv.name
	FROM sys.dm_xe_map_values xmv
	LEFT OUTER JOIN sys.dm_xe_object_columns xoc
		ON xmv.name = xoc.type_name
		AND xmv.object_package_guid = xoc.object_package_guid
	WHERE xoc.name IS NULL
	ORDER BY xmv.name;</pre><p>This will produce the following sample of results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps.png"><img loading="lazy" class="alignnone wp-image-3277 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps-628x1024.png" alt="internals_maps" width="560" height="913" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps-628x1024.png 628w, https://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps-184x300.png 184w, https://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps-31x50.png 31w, https://jasonbrimhall.info/wp-content/uploads/2015/10/internals_maps.png 687w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>That is just a sample of the internals maps available through the XEvent engine. That is pretty cool. Looking closer at the results, I have highlighted (in green) some really interesting and cool maps. Wow! I can look at the different components of the query_optimizer_tree_id. That seems like a worthwhile look! Let&#8217;s look closer at query_optimizer_tree_id now.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xmv.name, xmv.map_key, xmv.map_value, xo.description, xo.type_name
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,xp.name AS PackageName
		,xo.object_type
	FROM sys.dm_xe_map_values xmv
	LEFT OUTER JOIN sys.dm_xe_object_columns xoc
		ON xmv.name = xoc.type_name
		AND xmv.object_package_guid = xoc.object_package_guid
	INNER JOIN sys.dm_xe_objects xo
		ON xmv.object_package_guid = xo.package_guid
		AND xmv.name = xo.name
	INNER JOIN sys.dm_xe_packages xp
		ON xp.guid = xo.package_guid
	INNER JOIN sys.dm_os_loaded_modules olm
		ON xp.module_address = olm.base_address
	WHERE xoc.name IS NULL
		AND xmv.name = 'query_optimizer_tree_id'
	ORDER BY xmv.name, xmv.map_key;</pre><p>I added a few more pieces of information to this query so I can get a bigger picture of the query_optimizer_tree_id map. I want to know the over-arching map name, the package name, the source dll, and I want to know what this map does. The results are as follows:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/query_optimizer_map_details.png"><img loading="lazy" class="alignnone wp-image-3278 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/query_optimizer_map_details-1024x179.png" alt="query_optimizer_map_details" width="560" height="98" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/query_optimizer_map_details-1024x179.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/query_optimizer_map_details-300x52.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/query_optimizer_map_details-50x9.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>What a wealth of information into the internal workings of the query optimizer! I can see that the sqllang.dll is the source for the optimizer tree. I can see that this map reveals the different stages during optimization. And I can see that the Package is the sqlserver package in XEvents. This is fantastic! Of course, I may be a little geeky about it, but it is a cool way to get to know some of the internal operations of SQL Server.</p>
<p>What if I want to explore a different map? Well, I can pick one from the first query and then dive in and look just the same way I did for the query_optimizer_tree_id. In fact, let&#8217;s repeat that process with a different map, and with a slightly enhanced discovery query:</p><pre class="urvanov-syntax-highlighter-plain-tag">/* database_state */
DECLARE @map VARCHAR(128) = 'database_state' --'database_state' --null for all
SELECT xmv.name, xmv.map_key, xmv.map_value, xo.description, xo.type_name
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,xp.name AS PackageName
	FROM sys.dm_xe_map_values xmv
	LEFT OUTER JOIN sys.dm_xe_object_columns xoc
		ON xmv.name = xoc.type_name
		AND xmv.object_package_guid = xoc.object_package_guid
	INNER JOIN sys.dm_xe_objects xo
		ON xmv.object_package_guid = xo.package_guid
		AND xmv.name = xo.name
	INNER JOIN sys.dm_xe_packages xp
		ON xp.guid = xo.package_guid
	INNER JOIN sys.dm_os_loaded_modules olm
		ON xp.module_address = olm.base_address
	WHERE xoc.name IS NULL
		AND xmv.name = ISNULL(@map,xmv.name)
	ORDER BY xmv.name, xmv.map_key;</pre><p>And the results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details.png"><img loading="lazy" class="alignnone wp-image-3279 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details-1024x276.png" alt="database_state_map_details" width="560" height="151" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details-1024x276.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details-300x81.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details-50x13.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/database_state_map_details.png 1527w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Nothing really earth shattering there. It is just the database state after-all and it should be rather familiar to the data professional.</p>
<p>Some of the internals maps will definitely be far more interesting than others. And the interest level will definitely depend on the person browsing the data. For me, learning more about the optimizer and internals in general is a lot of fun. Consequently, I am drawn more to the maps that can give more information about the internal workings of the optimization tree or even the different operators (logical and physical) within a query plan.</p>
<p>This article demonstrated a quick means to explore various stages of SQL Server internal operations. Accessing this kind of information is just scratching the surface for internals and really just a scratch on the surface of Extended Events. There is a lot of power with the little bit of information that XEvents yields. Explore and enjoy!</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3276" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/27/exposure-to-internals/">Exposure to Internals</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/27/exposure-to-internals/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Short Circuit Events</title>
		<link>https://jasonbrimhall.info/2015/10/26/short-circuit-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=short-circuit-events</link>
					<comments>https://jasonbrimhall.info/2015/10/26/short-circuit-events/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 26 Oct 2015 11:42:10 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3258</guid>

					<description><![CDATA[<p>The predicate order is critical. Having the wrong order can result in not trapping the desired events. I cover the critical nature of predicates in the aforementioned article. At least in principle. Today, I want to reinforce the topic through the use of examples.</p>
The post <a href="https://jasonbrimhall.info/2015/10/26/short-circuit-events/">Short Circuit Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/shortcircuit.png"><img loading="lazy" class="wp-image-3262 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/shortcircuit-300x265.png" alt="shortcircuit" width="206" height="182" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/shortcircuit-300x265.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/shortcircuit-50x44.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/shortcircuit.png 500w" sizes="(max-width: 206px) 85vw, 206px" /></a>I introduced the importance about predicate order previously. I recommend either reading that article for the first time or reading it again if you have already read it. You can find that article &#8211; <a href="http://bit.ly/1MIGeDI">here</a>.</p>
<p>The predicate order is critical. Having the wrong order can result in not trapping the desired events. I cover the critical nature of predicates in the aforementioned article. At least in principle. Today, I want to reinforce the topic through the use of examples.</p>
<h3>Short Circuit Events</h3>
<p><em><strong>Housekeeping</strong>: For the examples, I will use two different Extended Event sessions. The only difference between the sessions will be the order of the predicates that I will use.</em></p>
<p><strong>Setting the stage</strong>: I have a specific set of queries that are executing within the Adventureworks2014 database. I want to capture just the second query to be executed from that database. Since I want to capture just the second query to be executed, I will be using the package0.counter predicate.</p>
<p>This is an extremely simple scenario for a reason. The simple scenario helps to simplify the creation of the session. And of course, it also makes it much easier to demonstrate the effects of the predicate order.</p>
<p>Before getting into the weeds with the session, here are the basic query statements that will be used across the trials.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* open two query windows - one for each database connection 
then run these statements in order - alternating between database connections
*/
/* Trial 1 */
SELECT 'Trial 1: count - first statement'
	FROM AdventureWorks2014.sys.databases
	WHERE name = 'AdventureWorks2014';
GO
SELECT 'Trial 1: count - second statement'
	FROM tempdb.sys.databases
	WHERE name = 'tempdb';
GO
SELECT 'Trial 1: count - third statement'
	FROM AdventureWorks2014.sys.databases
	WHERE name = 'AdventureWorks2014';
GO
SELECT 'Trial 1: count - fourth statement'
	FROM tempdb.sys.databases
	WHERE name = 'tempdb';
GO

SELECT 'Trial 1: db - first statement'
	FROM AdventureWorks2014.sys.databases
	WHERE name = 'AdventureWorks2014';
GO
SELECT 'Trial 1: db - second statement'
	FROM tempdb.sys.databases
	WHERE name = 'tempdb';
GO
SELECT 'Trial 1: db - third statement'
	FROM AdventureWorks2014.sys.databases
	WHERE name = 'AdventureWorks2014';
GO
SELECT 'Trial 1: db - fourth statement'
	FROM tempdb.sys.databases
	WHERE name = 'tempdb';
GO</pre><p>As you can see, I will be running the same set of queries multiple times with just the slightest of variation. I will run the first four for the first XEvent session I create which will have the counter listed first in the predicate. Then I will run the second four statements for the session configured with the database filter first in the predicate order.</p>
<p>Without further ado, here are the definitions of the two XEvent sessions:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'pred_ordercountfirst' )
	DROP EVENT SESSION pred_ordercountfirst 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

USE master
GO
CREATE EVENT SESSION pred_ordercountfirst ON SERVER
ADD EVENT sqlserver.sql_statement_completed
    (ACTION (sqlserver.sql_text)
    WHERE package0.counter = 2
		AND sqlserver.database_name = 'AdventureWorks2014')
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\pred_ordercountfirst.xel' )
WITH (MAX_DISPATCH_LATENCY = 1 SECONDS)

ALTER EVENT SESSION pred_ordercountfirst
ON SERVER
STATE = START;
GO

USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'pred_orderdbfirst' )
	DROP EVENT SESSION pred_orderdbfirst 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO
USE master
GO
CREATE EVENT SESSION pred_orderdbfirst ON SERVER
ADD EVENT sqlserver.sql_statement_completed
    (ACTION (sqlserver.sql_text)
    WHERE sqlserver.database_name = 'AdventureWorks2014'
		AND package0.counter = 2
		)
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\pred_orderdbfirst.xel' )
WITH (MAX_DISPATCH_LATENCY = 1 SECONDS)

ALTER EVENT SESSION pred_orderdbfirst
ON SERVER
STATE = START;
GO</pre><p>With these sessions, I will only have one turned on at a time. Running both at the same time can result in invalid results. The process is simple: from separate connections, alternate through the list of queries and then check the session data to find the result. The queries are written to help indicate which query window each should be run. For the results to be valid, I will be sticking to that pattern. In this test case, the pattern will alternate between two connections where one is connected to the tempdb database and the other is connected to the AdventureWorks2014 database.</p>
<p>Running through the trials for the pred_ordercountfirst session, I will receive the following results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata.jpg"><img loading="lazy" class="alignnone wp-image-3266 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata-1024x85.jpg" alt="pred_countfirst_targetdata" width="560" height="46" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata-1024x85.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata-300x25.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata-50x4.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_countfirst_targetdata.jpg 1746w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I have cycled through each of the four scripts with the pred_ordercountfirst session in the running state. Notice that I have no event_data? This is because no event has been trapped. When the counter reaches a value of two, the second predicate condition fires. The second query to have been executed was actually run from the tempdb database. Because the second condition fails the check, no data will be captured for this first session. Recapping each iteration would look like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/counterfirst_querytrapped.png"><img loading="lazy" class="alignnone wp-image-3267 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/counterfirst_querytrapped-1024x94.png" alt="counterfirst_querytrapped" width="560" height="51" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/counterfirst_querytrapped-1024x94.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counterfirst_querytrapped-300x28.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counterfirst_querytrapped-50x5.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Each query executed caused the counter value to increment as shown by the green box. In the red box is the second iteration which was performed against a connection to tempdb. And in the yellow box, I show that no statements have been trapped in this session.</p>
<p>Here is a query to help validate the session results.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.predicate
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, sese.predicate
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
					INNER JOIN sys.server_event_session_events sese
						ON ses.event_session_id = sese.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'pred_ordercountfirst'
					) cte1
				OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2

		;</pre><p>I have not included a means to parse into the session data because there is nothing to parse. That will change with the next trial. I will drop the pred_ordercountfirst and then create the pred_orderdbfirst session. Then I will run the trial in the same fashion as I did for the pred_ordercountfirst session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata.jpg"><img loading="lazy" class="alignnone wp-image-3268 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata-1024x59.jpg" alt="pred_dbfirst_targetdata" width="560" height="32" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata-1024x59.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata-300x17.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata-50x3.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>It&#8217;s a bit small, but the data is there. Looking down into the data a little closer, I will see the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata2.jpg"><img loading="lazy" class="alignnone wp-image-3269 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata2-1024x78.jpg" alt="pred_dbfirst_targetdata2" width="560" height="43" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata2-1024x78.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata2-300x23.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pred_dbfirst_targetdata2-50x4.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From the session data, I can see that the overall third query to execute was the query trapped by the session. This is the correct result based on the order of executions and the requirements defined in the beginning. See the big difference between the configurations of the predicates in these two sessions? Predicate order is important and critical to a proper running event session.</p>
<p>To recap the results by iteration, I have the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/counterdb_querytrapped.png"><img loading="lazy" class="alignnone wp-image-3270 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/counterdb_querytrapped-1024x92.png" alt="counterdb_querytrapped" width="560" height="50" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/counterdb_querytrapped-1024x92.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counterdb_querytrapped-300x27.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counterdb_querytrapped-50x4.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Similar to the previous session, I have used green to highlight the counter value after each iteration. Since the first query executed was against the Adventureworks2014 database, the counter value incremented to 1. In the next iteration, it remained at one because the source database was tempdb and <strong>not</strong> AdventureWorks2014. Finally, the counter incremented to two on the next iteration when the source database was AdventureWorks2014. At this point, since both criteria were met, an event was recorded and sent to the event_file target (recall the event processing steps shown <a href="http://bit.ly/1MIGeDI">here</a>).</p>
<p>To parse all of this data, I used the following statements:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([t2].[event_data] AS XML) AS event_data, t2.file_offset,t2.file_name, cte1.predicate
	INTO #xmlprocess
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue, sese.predicate
		FROM sys.server_event_sessions ses
		INNER JOIN sys.server_event_session_fields sesf
		ON ses.event_session_id = sesf.event_session_id
		INNER JOIN sys.server_event_session_events sese
		ON ses.event_session_id = sese.event_session_id
		WHERE sesf.name = 'filename'
			AND ses.name = 'pred_orderdbfirst'
					) cte1
	OUTER APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;
SELECT x.event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
, x.event_data.value('(event/action[@name="sql_text"]/value)[1]','varchar(max)') AS sql_text
		, x.file_offset,x.predicate--,x.file_name
	FROM #xmlprocess x</pre><p>In this article I have just shown how the configuration of predicates for each event will affect the events that are trapped. In TSQL both of these predicates would produce the same results. In Extended Events, the order of the predicates can cause a significant difference in the event that is captured and what is expected to be captured. Furthermore, this processing order can correlate to a difference in observer overhead since more (or less) events may be captured than what is expected. The more data that has to flow throw all levels of filters, the more impact that will be caused by the configuration of the event session and predicates.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3258" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/26/short-circuit-events/">Short Circuit Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/26/short-circuit-events/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Counting Events</title>
		<link>https://jasonbrimhall.info/2015/10/23/parsing-matched-events-2-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=parsing-matched-events-2-2</link>
					<comments>https://jasonbrimhall.info/2015/10/23/parsing-matched-events-2-2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 23 Oct 2015 12:03:45 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3248</guid>

					<description><![CDATA[<p>This article will show how to implement an XEvent Session that employs the use of the event_counter target that is used for counting events. IN addition, you will be shown how to parse the data and get some meaningful counts of event occurrences in your SQL Server Instances.</p>
The post <a href="https://jasonbrimhall.info/2015/10/23/parsing-matched-events-2-2/">Counting Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>After reading through the articles about the pair_matching target (<a href="http://bit.ly/1W3RjyQ">here</a>) and the article on <a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/counting.png"><img loading="lazy" class="size-full wp-image-3249 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/counting.png" alt="counting" width="268" height="200" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/counting.png 268w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counting-50x37.png 50w" sizes="(max-width: 268px) 85vw, 268px" /></a>the histogram target (<a href="http://bit.ly/1GjP7BF">here</a>), this one is going to seem very basic. To be honest, I would consider this to be basic even if it was discussed prior to the two just mentioned. This article will be diving into the shallow depths of the event_counter target.</p>
<p>There is no real surprise to what the function of this target is &#8211; to count. The configuration will be very basic in nature. Reading the target will be very basic in nature.</p>
<p>The real use here would be to count event occurrences at a step below the histogram target. Unlike the histogram, this target does not group events. It just counts. You may be asking why use this particular target. That would be a valid question.</p>
<p>Imagine that you just want to know how many times an event has fired but don&#8217;t want to add the full overhead of event collection. If an event fires frequently, you can get an idea as to the workload. In addition, you could determine a focus area for troubleshooting at some future point. That could come in handy!</p>
<h3>Counting Events</h3>
<p>Following the established pattern, before I proceed with trying to configure a session to use this target, I really need to know more about the target. I need to know what I can configure for this target. So, like in previous articles, I just need to query the metadata to find any configurable settings for the event_counter target. The following script will help me do that:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @includeprivate TINYINT = 1 --1 public only and 2 for all
		,@targetname VARCHAR(128) = 'event_counter' --null for all
SELECT xoc.object_name AS TargetName
		,xoc.name AS FieldName
		, xoc.capabilities_desc
		,xoc.description
		, xoc.column_value AS DefaultSetting
		, xoc.type_name AS DataType
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.package_guid = xoc.object_package_guid
			AND xo.name = xoc.object_name
	WHERE xo.object_type = 'target'
		AND (xo.capabilities IS NULL
			OR xo.capabilities &amp; 1 &lt;&gt; @includeprivate)
		AND ISNULL(@targetname, xo.name) = xo.name
	ORDER BY xoc.object_name DESC;</pre><p>From this query, I now know that I have absolutely nothing to configure that is specific to the target. This reinforces the basic nature of the target.</p>
<p>Now comes the hard part. To effectively use this target, I really should know just what I want to count. Once I get a list of events I want to count, then I need to throw those together into a session. With that in mind, I have the following session with a handful of events that I want to start counting:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'CountingSheep' )
	DROP EVENT SESSION CountingSheep 
    ON SERVER;
GO

CREATE EVENT SESSION [CountingSheep] ON SERVER 
ADD EVENT sqlserver.lock_deadlock(
    ACTION(sqlserver.database_name,sqlserver.plan_handle,sqlserver.sql_text)),
ADD EVENT sqlserver.sql_statement_starting(),
ADD EVENT sqlserver.Login (),
ADD EVENT sqlserver.Logout ()
ADD TARGET package0.event_counter
WITH (STARTUP_STATE=OFF);
GO

ALTER EVENT SESSION [CountingSheep]
ON SERVER
STATE = START;</pre><p>After creating that session and letting it run for a little bit in my sandbox, then I am ready to take a peek at the session data. The query to peek into the session data, at a basic level, is just like the query that has been used over the past few articles.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'CountingSheep'
		AND xt.target_name = N'event_counter'
		;</pre><p>And the results of that query would look something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata.png"><img loading="lazy" class="alignnone wp-image-3250 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata-1024x686.png" alt="event_targetdata" width="560" height="375" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata-1024x686.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata-300x201.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/event_targetdata.png 1221w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Similar to the simplicity in configuration for the target, the data is stored in a very simple manner. In the target, I will only see a count for the event if the event has fired during the session. Otherwise, the entire event node for the event in question will be missing and just the parent package of the event will exist in the data. Notice that there is a node for every package within the Extended Events engine. Most have no events in this session. Had an event for the package been in the session and not fired, I may see something like the following (which happens to be this same session just prior to a deadlock occurrence):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks.png"><img loading="lazy" class="alignnone wp-image-3251 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks-1024x745.png" alt="counter_nodeadlocks" width="560" height="407" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks-1024x745.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks-300x218.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks-50x36.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/counter_nodeadlocks.png 1063w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This is handy information and seems to make sense. If an event never fires, why have a node for the data for that event in the session. Sadly, the logic for the packages is a bit reversed. All packages are included regardless. That said, having a placeholder already there can make it a little more efficient for the firing event to be recorded into the target.</p>
<p>With a solid (maybe semi-solid) understanding of what the structure of the target data is, it is time to start parsing the target data into something a tad easier to read and understand.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	INTO #xmlpreprocess
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'CountingSheep'
		AND xt.target_name = N'event_counter'
		;

-- Query the XML variable to get the Target Data
SELECT pck.package_name, evt.event_name, evt.event_count
	FROM (
		SELECT event_data.value('(../@name)[1]', 'varchar(50)') AS package_name
			, event_data.value('(@name)[1]', 'varchar(50)') AS event_name
			, event_data.value('(@count)[1]', 'bigint') AS event_count
		FROM #xmlpreprocess x
		CROSS APPLY x.target_data.nodes('/CounterTarget/Packages/Package/Event') AS EvntData ( event_data )
	) evt
	RIGHT OUTER JOIN (
		SELECT DISTINCT pack_data.value('(@name)[1]', 'varchar(50)') AS package_name
		FROM #xmlpreprocess x
		CROSS APPLY x.target_data.nodes('//CounterTarget/Packages/Package') AS packData ( pack_data )
	) pck
		ON evt.package_name = pck.package_name
	ORDER BY evt.event_count DESC, evt.event_name, evt.package_name

GO</pre><p>This will give me the following results in my sandbox:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out.png"><img loading="lazy" class="alignnone wp-image-3252 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out-1024x582.png" alt="count_query_out" width="560" height="318" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out-1024x582.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out-300x171.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out-50x28.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/count_query_out.png 1347w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>As is shown in the results, I have results for each of the events specified in the Session. These are the same events and event counts seen in the XML, just in a more friendly format. Most packages have no data due to a lack of events from that package being included in the session.</p>
<p>For this particular server, the only thing that may be of interest is the deadlock occurrence. But since that was caused by a controlled experiment that forced the deadlock, I won&#8217;t worry about it. Had this been a production environment, the deadlock may need to be investigated.</p>
<p>Looking a little closer at the query to parse the session data, one could see that it seems rather kludgy. There is probably a better way of parsing the XML, but this was the method I could get to work with my lack of XML / Xquery ability. If you happen to know of a better way to get that data properly correlated from Xquery, I would welcome that in the comments.</p>
<p>In this article I have just shown how to use and configure the event_counter target. In addition, I explained how to get to the data trapped into this target. Lastly, I demonstrated how to find the pertinent information for the target configurations.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3248" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/23/parsing-matched-events-2-2/">Counting Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/23/parsing-matched-events-2-2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Histograms and Events</title>
		<link>https://jasonbrimhall.info/2015/10/22/histograms-and-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=histograms-and-events</link>
					<comments>https://jasonbrimhall.info/2015/10/22/histograms-and-events/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 22 Oct 2015 12:08:24 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3241</guid>

					<description><![CDATA[<p>In this article I show how to use and configure the histogram target. In addition, I explain how to get to the data trapped into this target. Lastly, I demonstrate how to find the pertinent information for the target configurations.</p>
The post <a href="https://jasonbrimhall.info/2015/10/22/histograms-and-events/">Histograms and Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram.png"><img loading="lazy" class="size-medium wp-image-3242 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram-300x180.png" alt="histogram" width="300" height="180" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram-300x180.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram.png 786w" sizes="(max-width: 300px) 85vw, 300px" /></a>The last few articles covered the pair_matching target and some uses and details that go along with it. For a recap, you can read <a href="http://bit.ly/1W3RjyQ">here</a>.</p>
<p>The pair_matching target was just one of the more advanced targets available for use via Extended Events. In this segment, I will be covering another of the more advanced targets &#8211; the histogram target.</p>
<p>The histogram target is a target that provides grouping of a specific event within the event session. This group can be configured to be on a data point within the payload of the event session or on an action that has been attached to the event. That said, careful consideration should be given to what the grouping configuration will be.</p>
<h3>Histograms and Events</h3>
<p>In principle, this is fine and well. As is often the case with Extended Events, it is often more clear to see how this works. The first step to seeing this in action is to figure out what the configurable options are for the histogram target.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @includeprivate TINYINT = 1 --1 public only and 2 for all
		,@targetname VARCHAR(128) = 'histogram' --null for all
SELECT xoc.object_name AS TargetName
		,xoc.name AS FieldName
		, xoc.capabilities_desc
		,xoc.description
		, xoc.column_value AS DefaultSetting
		, xoc.type_name AS DataType
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.package_guid = xoc.object_package_guid
			AND xo.name = xoc.object_name
	WHERE xo.object_type = 'target'
		AND (xo.capabilities IS NULL
			OR xo.capabilities &amp; 1 &lt;&gt; @includeprivate)
		AND ISNULL(@targetname, xo.name) = xo.name
	ORDER BY xoc.object_name DESC;</pre><p>From this query, that I have shown a few times now, I can see  the following results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs.png"><img loading="lazy" class="alignnone wp-image-3243 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs-1024x126.png" alt="histogram_configs" width="560" height="69" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs-1024x126.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs-300x37.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs-50x6.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_configs.png 1938w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The histogram target has four configurable options. Note that none of the configurations is mandatory and two have default values assigned. Even though none of the configurations is mandatory, I would say that the source is somewhat mandatory. This is the field (or action) on which to group the data. In addition, I would also say that the filtering_event_name is a mandatory field, unless there is only one event in the session. Even at that, I would recommend getting into the habit of setting a value for this configuration.</p>
<p>In addition to the lack of a mandatory configuration, I want to make particular note of the source_type configuration. This configuration has a default setting of 1. This value correlates to &#8220;action_name&#8221; as a grouping field type. Keep that value in mind for later recall. In the interim, I have a script that will create an XEvent Session to track deadlocks occurring on the instance. This will be used for the remainder of the demos.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [Deadlock] ON SERVER 
ADD EVENT sqlserver.lock_deadlock(
    ACTION(sqlserver.database_name,sqlserver.plan_handle,sqlserver.sql_text)),
ADD EVENT sqlserver.xml_deadlock_report 
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\Deadlock.xel'),
ADD TARGET package0.histogram
  ( SET filtering_event_name = 'sqlserver.lock_deadlock',
        source_type = 0, -- Event Column
        source = 'database_id')
WITH (STARTUP_STATE=OFF);
GO

ALTER EVENT SESSION [Deadlock]
ON SERVER
STATE = START;</pre><p>In this session, I have decided I want to trap occurrences of deadlocks to two different targets; the event_file target and the histogram target. On the histogram target, I have configured the filtering_event_name, source_type and source settings. Now, I want to create a second session that I will not start. This additional session will be strictly to show the differences between settings values.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [Deadlocksrc] ON SERVER 
ADD EVENT sqlserver.lock_deadlock(
    ACTION(sqlserver.database_name,sqlserver.plan_handle,sqlserver.sql_text)),
ADD EVENT sqlserver.xml_deadlock_report 
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\Deadlock.xel'),
ADD TARGET package0.histogram
  ( SET filtering_event_name = 'sqlserver.lock_deadlock',
        source = 'database_id')
WITH (STARTUP_STATE=OFF);
GO</pre><p>Now with both sessions deployed, I will query the sys.server_event_session_fields view to find what configuration settings are in effect for these particular sessions.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram.png"><img loading="lazy" class="alignnone wp-image-3244 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram-1024x471.png" alt="defaultconfigsettings_histogram" width="560" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram-1024x471.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram-300x138.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram-50x23.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/defaultconfigsettings_histogram.png 1037w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Despite the default value for source_type according to the metadata, it really seems there is no default value based on these results. Keep that in mind when building this target into a session. Much like the filtering_event_name, I recommend just setting the source_type to remove all doubt of the value being used for this configuration.</p>
<p>Now that that is understood, go back and clean up the Deadlocksrc session if you executed that script. I will just be using the Deadlock session from this point.</p>
<p>To ensure data has loaded into the target for the Deadlock session, I have created deadlocks a few times in a few different databases. It is important that the deadlocks have been created in different databases due to the configuration of the XEvent Session and the configuration of the histogram target in this session.</p>
<p>I have configured the grouping field to be database_id. In addition, it&#8217;s just not as much fun to show a single data point. This session is designed to help me understand which databases are hotspots for deadlocks. Then I can focus my attention on the hotspots and tune from there.</p>
<p>So how do I query the target data? It really is very much like the previous targets. I will once again start by querying the target with a very basic query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'Deadlock'
		AND xt.target_name = N'histogram'
		;</pre><p>Looking at just the XML, I will see a structure similar to the following (values will differ):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_xml.png"><img loading="lazy" class="alignnone wp-image-3245 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_xml.png" alt="histogram_xml" width="875" height="367" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_xml.png 875w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_xml-300x126.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_xml-50x21.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>I have highlighted a couple of areas of interest. In blue, I have highlighted the count. The count is maintained for each grouping . This brings me to the section highlighted in green. This is the value &#8211; or database_id that I specified in the &#8220;source&#8221; configuration for this target. Now all I need to do is query the target and get this data into something a little more friendly. Here is how I have done just that:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	INTO #xmlpreprocess
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'Deadlock'
		AND xt.target_name = N'histogram'
		;

SELECT hist.target_data.value('(value)[1]', 'bigint') AS DatabaseID
		, hist.target_data.value('(@count)[1]', 'bigint') AS DeadlockCount
	FROM #xmlpreprocess
		CROSS APPLY target_data.nodes('HistogramTarget/Slot') AS hist ( target_data );

SELECT d.name AS DBName, summary.DeadlockCount
	FROM (SELECT hist.target_data.value('(value)[1]', 'bigint') AS DatabaseID
			, hist.target_data.value('(@count)[1]', 'bigint') AS DeadlockCount
		FROM #xmlpreprocess
			CROSS APPLY target_data.nodes('HistogramTarget/Slot') AS hist ( target_data )
		) summary
	INNER JOIN sys.databases d
		ON d.database_id = summary.DatabaseID;</pre><p>I have a few options demonstrating the progression of steps for this particular query. First, as I have shown previously, I have dumped the target data into a temp table for improved performance. Then I query the temp table and parse the XML from there.</p>
<p>In the first shot at parsing the data, all I see is a database_id and a count. This is not very helpful unless the mapping of database id to name (or one queries the information manually). Thus the need for the second query where the data is joined to sys.databases to get this data directly in a single query.</p>
<p>For my particular setup, here are my results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_queryresults.jpg"><img loading="lazy" class="alignnone wp-image-3246 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_queryresults.jpg" alt="histogram_queryresults" width="540" height="160" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_queryresults.jpg 540w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_queryresults-300x89.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/histogram_queryresults-50x15.jpg 50w" sizes="(max-width: 540px) 85vw, 540px" /></a></p>
<p>There is an alternative to this method. Rather than group on the event field called database_id, I could group on the action called database_name. Then I would only need to query the session details. I will leave that choice to you to make.</p>
<p>Back to the results (as contrived as they may be), I can see that I have two databases that seem to be the sources of deadlocks on a pretty regular basis. Well, at least in comparison to the remaining 100 databases in my instance. Now, I can filter down the deadlocks I want to pay attention to by querying the event_file and filtering just for deadlocks that occur in either of these two databases. I could also create a session to trap deadlocks specifically for those particular databases rather than monitoring all databases. Again, this is one of those things that just gives me several options were there may be more than one correct choice.</p>
<p>In this article I have just shown how to use and configure the histogram target. In addition, I explained how to get to the data trapped into this target. Lastly, I demonstrated how to find the pertinent information for the target configurations.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3241" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/22/histograms-and-events/">Histograms and Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/22/histograms-and-events/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Parsing Matched Events</title>
		<link>https://jasonbrimhall.info/2015/10/21/parsing-matched-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=parsing-matched-events</link>
					<comments>https://jasonbrimhall.info/2015/10/21/parsing-matched-events/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 21 Oct 2015 11:50:36 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3225</guid>

					<description><![CDATA[<p>In this article I will be taking you into the world of the pair_matching target. The pair_matching target should connote that this target works on matching like events into a single pair. Very much like a pair of socks would contain two parts, one for each foot or side of the body, the pair_matching target creates pairs of events that go together.</p>
The post <a href="https://jasonbrimhall.info/2015/10/21/parsing-matched-events/">Parsing Matched Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="wp-image-3208 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-300x300.png" alt="yinyang_pair" width="180" height="180" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair.png 418w" sizes="(max-width: 180px) 85vw, 180px" />I just covered the topic of matching events from definition on down through highlighting a common use for this type of target. With that in mind, it is now time to dive into how to extract the data from the session.</p>
<p>If you need a recap of what exactly a pair_matching target is, or even how to configure it, you can read the article <a href="http://bit.ly/1LAS3GE">here</a>.</p>
<h3>Parsing Matched Events</h3>
<p>In fact, it is a good idea to revisit <a href="http://bit.ly/1LAS3GE">that article</a> and go over the topics presented. Of particular interest should be the script that shows how to find all of the configurable settings for the target.</p>
<p>The other really important take-away from that article is the demo script. That script is repeated here for ease of access.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'Timeout2' )
	DROP EVENT SESSION Timeout2 
    ON SERVER;
GO
CREATE EVENT SESSION [Timeout2] ON SERVER
ADD EVENT sqlserver.sql_statement_completed (
	ACTION ( sqlserver.database_name, sqlserver.nt_username,
	sqlserver.session_id, sqlserver.sql_text, sqlserver.tsql_stack ) ),
ADD EVENT sqlserver.sql_statement_starting (
	ACTION ( sqlserver.database_name, sqlserver.nt_username,
	sqlserver.session_id, sqlserver.sql_text, sqlserver.tsql_stack ) )
ADD TARGET package0.pair_matching (  SET begin_event = N'sqlserver.sql_statement_starting'
										, begin_matching_columns = 'offset,offset_end'
										, begin_matching_actions = N'sqlserver.session_id, sqlserver.tsql_stack'
										, end_event = N'sqlserver.sql_statement_completed'
										, end_matching_columns = 'offset,offset_end'
										, end_matching_actions = N'sqlserver.session_id, sqlserver.tsql_stack' )
WITH (  MAX_DISPATCH_LATENCY = 3 SECONDS
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = ON );
GO</pre><p>With that session running on the test server, I can run the following query to explore the structure of the target of the session data. Exploring the structure is a fruitful exercise because one can learn some interesting facts.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT name
		, target_name
		, CAST(target_data AS XML) AS TargetData
	FROM sys.dm_xe_sessions s
		INNER JOIN sys.dm_xe_session_targets t
			ON s.address = t.event_session_address
	WHERE s.name = 'Timeout2';</pre><p>The first thing I want to point out is at the end of each event node. There is an action (actually two of them) attached to the session that was not specified in either of the events added to this session. This is shown in the following image:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1.png"><img loading="lazy" class="alignnone wp-image-3230 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1-1024x621.png" alt="attach_activity1" width="560" height="340" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1-1024x621.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1-300x182.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/attach_activity1.png 1455w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The area of interest is highlighted in green. By enabling Track_causality on this target type, both of these private activities have been attached to all events in the session automatically. Disabling track_causality will remove both of these activities from the session. Of interesting note, is that in sessions with different target types, track_causality will only enable the attach_activity_id action for the session.</p>
<p>Looking back near the beginning of the session data, the following can be seen:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml.png"><img loading="lazy" class="alignnone wp-image-3231 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml-1024x590.png" alt="pair_match_xml" width="560" height="323" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml-1024x590.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml-300x173.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml-50x29.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_match_xml.png 1561w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The interesting difference between this target data structure and the ring_buffer (or even file_target) target is in the properties of the target. This target has a few extra data points called truncated, orphanCount, matchedCount, and droppedCount. These are basically target statistics to give a high level overview of what is happening with the session and how the target configurations may have affected the session data.</p>
<p>The next really big ticket item is that the data in this target will only show the event defined for the begin_event configuration setting. Since sql_statement_starting is the event defined as the begin_event in this particular session, it will be the only event to show up in the target. The events have been paired together where possible and the event of record will be the begin_event. One can surmise that this would be due to the potential for the end_event to never fire.</p>
<p>Being aware of the data structure within the pair_matching target is essential to parsing the data from the target. Fortunately, most of the structure is the same with the major differences being in the root node name and then the statistics available via that root node.</p>
<p>So, how does one query the session data? I will resort back to the following building block query for starters:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'Timeout2'
		AND xt.target_name = N'pair_matching'
		;</pre><p>Nothing fancy with this query and it should be fairly common place at this point. If I take that query to the next level and dump the target data into a temp table, I can query the target more quickly and avoid the cost of re-querying the target each time I wish to change between gathering stats and gathering event details. In the following example, I show just how to do this:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	INTO #xmlpreprocess
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'Timeout2'
		AND xt.target_name = N'pair_matching'
		;

SELECT 
    target_data.value('(PairingTarget/@orphanCount)[1]', 'int') AS orphanCount,
    target_data.value('(PairingTarget/@matchedCount)[1]', 'int') AS matchedCount,
    target_data.value('(PairingTarget/@droppedCount)[1]', 'int') AS memoryPressureDroppedCount,
	target_data.value('(PairingTarget/@truncated)[1]', 'int') AS memoryPressureDroppedCount
	FROM #xmlpreprocess</pre><p>In the second segment of that script, I have queried the properties of the target PairingTarget root node. By doing this, I can validate how well my session is performing. This will produce the following results in my test case:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats.png"><img loading="lazy" class="alignnone wp-image-3236 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats-1024x68.png" alt="pair_stats" width="560" height="37" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats-1024x68.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats-300x20.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats-50x3.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pair_stats.png 1427w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>If I start to see an increase in orphans, or if I see any at all, then I can query further into the session data to figure out what is happening.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_data.value('(@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(@package)[1]', 'varchar(50)') AS package_name
		, DATEADD(hh, DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP),
					event_data.value('(@timestamp)[1]', 'datetime2')) AS [timestamp]
		, event_data.value('(data[@name="source_database_id"]/value)[1]', 'int') AS [source_database_id]
		, event_data.value('(data[@name="object_id"]/value)[1]', 'int') AS [object_id]
		, event_data.value('(data[@name="object_type"]/value)[1]', 'varchar(60)') AS [object_type]
		, event_data.value('(data[@name="state"]/text)[1]', 'varchar(50)') AS [state]
		, event_data.value('(data[@name="offset"]/value)[1]', 'int') AS [offset]
		, event_data.value('(data[@name="offset_end"]/value)[1]', 'int') AS [offset_end]
		, event_data.value('(data[@name="nest_level"]/value)[1]', 'int') AS [nest_level]
		, CONVERT(XML,event_data.value('(action[@name="sql_text"]/value)[1]', 'varchar(max)')) AS sqlstatement
		, event_data.value('(action[@name="session_id"]/value)[1]', 'int') AS session_id
		, event_data.value('(action[@name="database_name"]/value)[1]', 'varchar(64)') AS DBName
		, event_data.value('(action[@name="nt_username"]/value)[1]', 'varchar(64)')AS nt_username
		, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@handle)[1]','varchar(max)') AS stackhandle
		, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@offsetStart)[1]','varchar(max)') AS stackoffset
		, event_data.value('(action[@name="tsql_stack"]/value/frames/frame/@offsetEnd)[1]','varchar(max)') AS stackoffsetend
		, event_data.value('(action[@name="attach_activity_id"]/value)[1]','varchar(50)') AS activity_id
	FROM #xmlpreprocess x
		CROSS APPLY x.target_data.nodes('PairingTarget/event') AS XEventData ( event_data )
	ORDER BY session_id
		, activity_id;
GO</pre><p>And looking at a snip of the results, I would see something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/output_snip_pair.png"><img loading="lazy" class="alignnone wp-image-3237 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/output_snip_pair-1024x94.png" alt="output_snip_pair" width="560" height="51" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/output_snip_pair-1024x94.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/output_snip_pair-300x28.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/output_snip_pair-50x5.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>From these results, I can see the query(ies) that seem to be having problems. I can also investigate the TSQL stack. An interesting note about the TSQL stack is that I can retrieve the beginning offset and the ending offset for the query(ies) involved. Since I am testing with the sql_statement* events, this is a bit of redundant data but it is there nonetheless and can be useful. In addition I can see which database is the source of the query timeouts and I can see the user/logon that executed the query. Both of these would be helpful in determining where to focus the attention and effort first. Who knows, maybe it is an end user that needs a little more training.</p>
<p>I have just shown how to parse the data a couple of different ways for the pair_matching target. With a little effort, this target can be configured to work very well and be a great asset in your troubleshooting efforts.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3225" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/21/parsing-matched-events/">Parsing Matched Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/21/parsing-matched-events/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Matching Events into Pairs</title>
		<link>https://jasonbrimhall.info/2015/10/20/matching-events-into-pairs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=matching-events-into-pairs</link>
					<comments>https://jasonbrimhall.info/2015/10/20/matching-events-into-pairs/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Oct 2015 12:09:17 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3206</guid>

					<description><![CDATA[<p>In this article I will be taking you into the world of the pair_matching target. The pair_matching target should connote that this target works on matching like events into a single pair. Very much like a pair of socks would contain two parts, one for each foot or side of the body, the pair_matching target creates pairs of events that go together.</p>
The post <a href="https://jasonbrimhall.info/2015/10/20/matching-events-into-pairs/">Matching Events into Pairs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the last article I showed how to discover all of the settings that are available to a particular Target. I also <img loading="lazy" class="wp-image-3208 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-300x300.png" alt="yinyang_pair" width="180" height="180" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/yinyang_pair.png 418w" sizes="(max-width: 180px) 85vw, 180px" />mentioned the reason for that being that I would be discussing some of the other Target types since I had already shown various concepts in regards to the ring_buffer and event_file targets.</p>
<p>In this article I will be taking you into the world of the pair_matching target. The pair_matching target should connote that this target works by matching like events into a single pair. Very much like a pair of socks would contain two parts, one for each foot or side of the body, the pair_matching target creates pairs of events that go together. These paired events would typically correlate to one half of the equation &#8211; or in more simple terms, they are pairs because they are opposites just like the left shoe is a match to the right shoe.</p>
<h3>Matching Events into Pairs</h3>
<p>What if I have more than one pair of shoes though? Well, that is part of the equation with this target. Just like I need some sort of indicator that helps me match my shoes properly into pairs, I need to have some sort of indicator with the events in SQL Server, that are firing, that can help me figure out how they are related and should be in the same pair.</p>
<p>The equation to figure out which events are pairs is made available through the implementation of settings. To properly configure the pair_matching target requires: first, an understanding of what the possible configuration settings are, and second, an understanding of what it is that is to be paired.</p>
<p>To figure out what the possible configuration settings are, I will adapt a query from the previous article and use it here:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @includeprivate TINYINT = 1 --1 public only and 2 for all
		,@targetname VARCHAR(128) = 'pair_matching' --null for all
SELECT xoc.object_name AS TargetName
		,xoc.name AS FieldName
		, xoc.capabilities_desc
		,xoc.description
		, xoc.column_value AS DefaultSetting
		, xoc.type_name AS DataType
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.package_guid = xoc.object_package_guid
			AND xo.name = xoc.object_name
	WHERE xo.object_type = 'target'
		AND (xo.capabilities IS NULL
			OR xo.capabilities &amp; 1 &lt;&gt; @includeprivate)
		AND ISNULL(@targetname, xo.name) = xo.name
	ORDER BY xoc.object_name DESC;</pre><p>This would produce the following results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings.jpg"><img loading="lazy" class="alignnone wp-image-3211 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings-1024x220.jpg" alt="pairmatch_targetsettings" width="560" height="120" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings-1024x220.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings-300x65.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings-50x11.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/pairmatch_targetsettings.jpg 1956w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The previous image are the results that I get for this Target in SQL Server 2014. I am going to start with the obvious question. It was so obvious that I marked the problem area with the seemingly suitable question marks. This is a pairing target, yet the begin_event is not a mandatory setting &#8211; at least not according to the metadata. At least the end_event is mandatory! That said, it should seem pretty basic that a begin_event is necessary as part of the equation. Otherwise, what would be matched to the end_event?</p>
<p>Of interest, to me,  in the results for the settings is the default settings values for the begin_event, end_event, respond_to_memory_pressure, and max_orphans settings. Despite the empty string for the begin_event, I believe it should also be NULL just like the end_event. It makes sense to me that the default value is NULL in this case because these should be defined in the session and should not have a default value.</p>
<p>The next setting of interest is the respond_to_memory_pressure setting. The default for this is false. This means that if there are sufficient unmatched events, it could cause memory pressure and potentially have an adverse effect. By enabling this setting, unpaired events could be removed from the buffer which could lead to a higher level of orphaned events.</p>
<p>Last up is the default setting for the max_orphans. This is another optimization that could be enabled to help reduce the memory effects of the session.  If this limit is reached, then unpaired events will start to be removed from the buffer in a FIFO fashion.</p>
<p>The remaining columns wouldn&#8217;t make sense to have default values. Nor does it make sense to be set to NULL since they are more or less optional. That said, the remaining configuration options are crucial to designing the formula to efficiently match the events. If a begin_matching_action<strong>s</strong> setting is added, then the end_matching_action<strong>s</strong> should also be set. I do, however, want to note right now that the names of these settings are plural. The reason for the setting name to be in plural form is that the configuration accepts a comma delimited list of columns or actions. Just remember to keep the columns and actions in the same order for both the begin and end configurations.</p>
<h3>In Action</h3>
<p>That was quite a mouthful there. Sometimes it is easier to show how this works with an example. To demonstrate, I want to work with what seems like the easiest example to fit the pair_matching model &#8211; query timeouts.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'Timeout2' )
	DROP EVENT SESSION Timeout2 
    ON SERVER;
GO
CREATE EVENT SESSION [Timeout2] ON SERVER
ADD EVENT sqlserver.sql_statement_completed (
	ACTION ( sqlserver.database_name, sqlserver.nt_username,
	sqlserver.session_id, sqlserver.sql_text, sqlserver.tsql_stack ) ),
ADD EVENT sqlserver.sql_statement_starting (
	ACTION ( sqlserver.database_name, sqlserver.nt_username,
	sqlserver.session_id, sqlserver.sql_text, sqlserver.tsql_stack ) )
ADD TARGET package0.pair_matching (  SET begin_event = N'sqlserver.sql_statement_starting'
										, begin_matching_columns = 'offset,offset_end'
										, begin_matching_actions = N'sqlserver.session_id, sqlserver.tsql_stack'
										, end_event = N'sqlserver.sql_statement_completed'
										, end_matching_columns = 'offset,offset_end'
										, end_matching_actions = N'sqlserver.session_id, sqlserver.tsql_stack' )
WITH (  MAX_DISPATCH_LATENCY = 3 SECONDS
		, TRACK_CAUSALITY = ON
		, STARTUP_STATE = ON );
GO</pre><p>Here, I have the same session with points of interest highlighted.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap.png"><img loading="lazy" class="alignnone wp-image-3215 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap-1024x504.png" alt="target_pairmap" width="560" height="276" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap-1024x504.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap-300x148.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap-50x25.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_pairmap.png 1712w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I have aligned the like begin and end statements together so it is easier to see that these settings accept a comma delimited list and the items are listed in the same order. And, of course, the *_matching_actions settings have actions listed that have been attached to each of the Events that are to be paired. The *_matching_columns map to payload data points within the begin and end events. If using this particular setting, the columns of interest should exist in both events being compared.</p>
<p>These settings, with the proper attention to detail, can lead to an efficient and useful Session to match events. When attempting to throw this kind of session together without a little thought and prep-work, one could end up with a poorly performing session and potentially memory pressure issues (remember this is a memory target type with all the bliss that comes with a memory target).</p>
<p>Speaking of memory, you will need to remember to tune in for the next article where I will explore how to parse the event data for this session.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3206" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/20/matching-events-into-pairs/">Matching Events into Pairs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/20/matching-events-into-pairs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Know Before You GO &#8211; Target Settings</title>
		<link>https://jasonbrimhall.info/2015/10/19/know-before-you-go-target-settings-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=know-before-you-go-target-settings-2</link>
					<comments>https://jasonbrimhall.info/2015/10/19/know-before-you-go-target-settings-2/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 19 Oct 2015 12:42:07 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3200</guid>

					<description><![CDATA[<p>When adding a Target to a session, a configurable setting may or may not be obviously available for use with the Target. In and of itself, this can be mildly frustrating if the wrong settings are tried with the wrong Target. More frustrating is that some settings are required. While the required setting may be logically deduced, it does not always work out that way.</p>
The post <a href="https://jasonbrimhall.info/2015/10/19/know-before-you-go-target-settings-2/">Know Before You GO – Target Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/targetdials.jpg"><img loading="lazy" class="wp-image-3201 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/targetdials-293x300.jpg" alt="targetdials" width="179" height="183" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/targetdials-293x300.jpg 293w, https://jasonbrimhall.info/wp-content/uploads/2015/10/targetdials-50x50.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/targetdials.jpg 400w" sizes="(max-width: 179px) 85vw, 179px" /></a>The last few articles have covered various topics for the event_file and ring_buffer target. The topics range from basic queries in how to extract the session data on up through best practices. The fun doesn&#8217;t end there!</p>
<p>I will be covering more on the different types of targets over the next several articles. Before diving into the remaining Targets, it would be very beneficial to take a look at yet another core concept. Rather, it is time to return to a core concept and look at it from a different angle.</p>
<p>I would like to revisit the base principle around the Set Operations or configurable fields (recall that some settings are stored in the *_fields object). The remaining targets have a handful of settings to configure. Some of these settings are required while others should be required.</p>
<h3>Know Before you GO Target Settings</h3>
<p>When adding a Target to a session, a configurable setting may or may not be obviously available for use with the Target. In and of itself, this can be mildly frustrating if the wrong settings are tried with the wrong Target. More frustrating is that some settings are required. While the required setting may be logically deduced, it does not always work out that way.</p>
<p>This frustration can be mitigated through the use of the GUI to create the session. This introduces its own set of problems as was discussed <a href="http://bit.ly/1iA7M0N">previously</a>. If the session is to be created through script, then the settings available to the Target won&#8217;t be presented in a nice friendly fashion like the GUI. So, what can one do?</p>
<p>The answer lies within the metadata for Extended Events. I have shown through several articles how to expose the metadata for working with Extended Events. Exposing the available settings for each of the Targets is not much different from the previous explorations into the metadata.</p>
<p>The first step is to recall that the Targets are objects within Extended Events. Building from that base, the metadata for the Target settings has to be stored somewhere. Clue in that the setting is stored as a Field (or Column) after the session is started, and I can safely presume that the settings would be exposed through the sys.dm_xe_object_columns DMV. With that in mind, my query would look like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @includeprivate TINYINT = 1 --1 public only and 2 for all
SELECT xoc.object_name AS TargetName
		,xoc.name AS FieldName
		, xoc.capabilities_desc
		,xoc.description
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.package_guid = xoc.object_package_guid
			AND xo.name = xoc.object_name
	WHERE xo.object_type = 'target'
		AND (xo.capabilities IS NULL
			OR xo.capabilities &amp; 1 &lt;&gt; @includeprivate)
	ORDER BY xoc.object_name;</pre><p>This would produce the following results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings.jpg"><img loading="lazy" class="alignnone wp-image-3202 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings-1024x499.jpg" alt="target_settings" width="560" height="273" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings-1024x499.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings-300x146.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings-50x24.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>A couple of notes on the results and the query are necessary now. By querying the metadata from script, a description of the setting can be exposed. This leads to a better understanding of the intent and purpose of the setting. Think about the occurrence_number field for a moment. Just going by the name, it would be difficult to understand what this setting actually does. As it turns out, it is a directive to the XE Engine to store only the specified number of event occurrences for each event. In addition to a better definition of the setting, I can expose which fields are mandatory. The data for the mandatory fields is contained within the capabilities_desc column.</p>
<p>While this is great and useful information, it does not resolve all of the hair tugging just yet. It could be presumed that since the setting exists it has (or might have) a default value. Especially taking into consideration that there are very few mandatory settings. The presumption on the defaults is quite accurate because there are default values for these settings. Looking through the DMV, there is no column that appears to be the source for these &#8220;defaults&#8221;. Unless of course you recall from prior articles that there is the column_value column which will hold the default value for these settings. With that, I can now adjust my query to also show me the default settings as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @includeprivate TINYINT = 1 --1 public only and 2 for all
SELECT xoc.object_name AS TargetName
		,xoc.name AS FieldName
		, xoc.capabilities_desc
		,xoc.description
		, xoc.column_value AS DefaultSetting
		, xoc.type_name AS DataType
	FROM sys.dm_xe_objects xo
		INNER JOIN sys.dm_xe_object_columns xoc
			ON xo.package_guid = xoc.object_package_guid
			AND xo.name = xoc.object_name
	WHERE xo.object_type = 'target'
		AND (xo.capabilities IS NULL
			OR xo.capabilities &amp; 1 &lt;&gt; @includeprivate)
	ORDER BY xoc.object_name;</pre><p>This will show me a result set very similar to the prior results. The main difference being that I am now including the default value. I want to highlight a couple of these defaults:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults.png"><img loading="lazy" class="alignnone wp-image-3203 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults-1024x93.png" alt="target_settings_defaults" width="560" height="51" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults-1024x93.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults-300x27.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults-50x5.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/target_settings_defaults.png 1974w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Anybody familiar with SQL Server defaults should know that a default value of 0 should equate to &#8220;unlimited&#8221;. If you decide to use the ring_buffer target and do not specify a value for max_memory, you have just given free rain to the XE Engine to use as much memory as physically possible on the server.</p>
<p>Leaving the max_memory setting at its default happens to be dangerous enough that it could cause undue memory pressure and, in extreme cases, cause SQL Server to grind to a halt. This underscores the need to understand what the configuration options are and what they represent. The default values may be fine for many workloads, but really should be evaluated just as should be done with all defaults within SQL Server.</p>
<p>As I mentioned, this is an important topic to discuss at this point prior to more discussions on the different Targets. I will use this type of query throughout the next few articles to help illustrate the settings for the Targets as well as discuss how to get to the target data.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3200" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/19/know-before-you-go-target-settings-2/">Know Before You GO – Target Settings</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/19/know-before-you-go-target-settings-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reading Session Data from Memory</title>
		<link>https://jasonbrimhall.info/2015/10/16/better-practices-for-reading-event_file-targets-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-practices-for-reading-event_file-targets-2</link>
					<comments>https://jasonbrimhall.info/2015/10/16/better-practices-for-reading-event_file-targets-2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 16 Oct 2015 12:07:50 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3188</guid>

					<description><![CDATA[<p>In this article, I introduce the topic of reading session data from memory along with some of the pitfalls and some words of caution.</p>
The post <a href="https://jasonbrimhall.info/2015/10/16/better-practices-for-reading-event_file-targets-2/">Reading Session Data from Memory</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the last few articles I took you through a progression of working with the event_file target from the most basic concepts on through the more advanced. While working with the event_file target, I showed that XML is central to working with the session data for that <img loading="lazy" class=" wp-image-3191 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/simple_ringbuffer-300x196.png" alt="simple_ringbuffer" width="236" height="154" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/simple_ringbuffer-300x196.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/simple_ringbuffer-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/simple_ringbuffer.png 586w" sizes="(max-width: 236px) 85vw, 236px" />target type. XML is not just a fundamental component of the event_file target, I have also shown that it is ingrained throughout Extended Events. That indoctrination includes the topic of this article &#8211; the ring_buffer target.</p>
<p>I took you on a bit of a journey while discussing the event_file target. The journey for the ring_buffer is going to be much shorter. A big part of the reason is that I have already laid a big part of the foundation due to the similarities with the event_file target. This is just another step in the progression and continues to build on principles already shown.</p>
<p>Before diving in to the session data, a quick glance at what the ring_buffer is would be helpful. The ring_buffer is a memory target. In addition, as the name implies, the ring_buffer can be overwritten due to the nature of the ring. Once the buffer fills, then the new events will have to go somewhere, and that means something gets purged or overwritten.</p>
<p>The next important note is that it is a <em>memory</em> target and that means it is volatile. If the session is not running, well then the target won&#8217;t be there. This means that the only way to read the data in the target is to parse it while the session is running. In addition, since it is volatile, if the server is bounced then the data in the target is purged.</p>
<p>These are also a few of the reasons contributing to a shorter journey about this particular target. When working with this type of target, great care needs to be taken to ensure the session data is scraped and that the target is configured with attention to detail.</p>
<h3>Reading Session Data from Memory</h3>
<p>Since the target is only available while the session is running, I will only be focusing on the DMVs where the metadata for running sessions resides. In this case, the key DMV will be sys.dm_xe_session_targets. From there, I can run a very similar query as was done for the event_file, with the exception that I do not need to rely on a function to get the session data.</p>
<p>Unlike the event_file target where a bit of XML held the information for the file name and path is exposed via the target_data column, the entirety of the session data will be exposed for the ring_buffer via that column. This means I can use a query such as the following to retrieve all of the session data.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS Target_Data
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'demosession'
		AND xt.target_name = N'ring_buffer';</pre><p>And now, much in the same fashion as the event_file target, I can throw that into a query to parse the session data into an easier to read format.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST ([target_data] AS XML) AS target_data
	INTO #xmlpreprocess
	FROM sys.dm_xe_session_targets AS xt
		INNER JOIN sys.dm_xe_sessions AS xs
			ON xs.address = xt.event_session_address
	WHERE xs.name = N'demosession'
		AND xt.target_name = N'ring_buffer'
		;

SELECT event_data.value('(@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		,event_data.value('(data[@name="collect_database_name"]/value)[1]','bit') AS collect_database_name
		,event_data.value('(data[@name="database_id"]/value)[1]','int') AS database_id
		,event_data.value('(data[@name="object_id"]/value)[1]','int') AS object_id
		,event_data.value('(data[@name="index_id"]/value)[1]','int') AS index_id
		,event_data.value('(data[@name="job_id"]/value)[1]','int') AS job_id
		,event_data.value('(data[@name="job_type"]/value)[1]','varchar(max)') AS job_type
		,event_data.value('(data[@name="status"]/value)[1]','varchar(max)') AS status
		,event_data.value('(data[@name="duration"]/value)[1]','int') AS duration
		,event_data.value('(data[@name="retries"]/value)[1]','int') AS retries
		,event_data.value('(data[@name="success"]/value)[1]','bit') AS success
		,event_data.value('(data[@name="last_error"]/value)[1]','int') AS last_error
		,event_data.value('(data[@name="count"]/value)[1]','int') AS EventCount
		,event_data.value('(data[@name="statistics_list"]/value)[1]','varchar(max)') AS statistics_list
		,event_data.value('(data[@name="database_name"]/value)[1]','varchar(max)') AS database_name
	FROM #xmlpreprocess AS evts
	CROSS APPLY target_data.nodes('//RingBufferTarget/event') AS XEventData(event_data)
	ORDER BY [TIMESTAMP];

DROP TABLE #xmlpreprocess;</pre><p>As you can see, I went straight to the more optimal means of parsing the data. I chose to dump the session data into a temp table first and then from there I can more efficiently parse the XML into a more friendly format. Notice that I did need to use one more trick to parse the XML. I implemented the APPLY operator in order to break down  the session data into the various event nodes.</p>
<p><img loading="lazy" class="size-medium wp-image-3192 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/ringbufferwconsumer-300x169.png" alt="ringbufferwconsumer" width="300" height="169" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/ringbufferwconsumer-300x169.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/ringbufferwconsumer-50x28.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/ringbufferwconsumer.png 753w" sizes="(max-width: 300px) 85vw, 300px" />I want to return to the behavior of the ring_buffer in order to help underscore the potential for missing any events that may have been trapped.</p>
<p>I mentioned that the target is volatile due to the nature of it being a memory target. What I did not mention was that unless there is a consumer to fetch the events from the session, it is highly probable that the events will be missed.</p>
<p>This goes hand in hand with the circular nature and volatility of the target. In order to effectively use the target, you have to watch it and retrieve the events from it on a regular basis. Otherwise, it would be as if the events were never recorded.</p>
<p>I have shown in this article how to read session data from memory. I have also pointed out some of the less risky pitfalls of this particular target. Similar to the event_file, one will need to become familiar with how to parse the data with XML.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3188" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/16/better-practices-for-reading-event_file-targets-2/">Reading Session Data from Memory</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/16/better-practices-for-reading-event_file-targets-2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Better Practices for Reading Event_file Targets</title>
		<link>https://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=better-practices-for-reading-event_file-targets</link>
					<comments>https://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 15 Oct 2015 12:41:58 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3169</guid>

					<description><![CDATA[<p>In this article, I am going to address some better practices for Reading Event_file targets attached to an XEvent Session.</p>
The post <a href="https://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/">Better Practices for Reading Event_file Targets</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I have demonstrated over the past couple of articles the <a href="http://bit.ly/1G2QiVX">basics</a> involved with reading the<br />
event_file target along with a more <a href="http://bit.ly/1NcsAGs">advanced</a> technique.</p>
<p><img loading="lazy" class="wp-image-3183 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/db_xesession_xml-300x272.jpg" alt="db_xesession_xml" width="192" height="174" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/db_xesession_xml-300x272.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/db_xesession_xml-50x45.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/db_xesession_xml.jpg 320w" sizes="(max-width: 192px) 85vw, 192px" />In each of those articles I outlined some problems that could be encountered. Some of those pitfalls might include another DBA moving the location of the files and not documenting the change (the documentation still needs to be done but it takes a few extra moments to figure out the new location and can be frustrating) or potentially that the session is no longer active (this can be bothersome and cause a bit of hair loss). Both are legitimate concerns and can be solved, it just takes a little more planning up front to prevent the problems.</p>
<p>In this article, I am going to address some better practices for Reading Event_file targets attached to an XEvent Session. These better practices include how to retrieve the data file and directory dynamically regardless of the running state of the session. In addition to that, I will show a method to help parse the data more quickly.</p>
<h3>Dynamically Read event_file Data</h3>
<p>Similar to the prior article, I will take the basic example provided previously and use it as a starting point.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM sys.fn_xe_file_target_read_file('C:DatabaseXEDemoSession*.xel',NULL,NULL,NULL) t2</pre><p>Now that I have the basics in place, I need to find a different means to find the filepath based on the name of the session that does not require looking at just the running session metadata. For this, the filename is not as obvious as you may think. Logic may dictate that the data should be in the metadata for the session target, or sys.server_event_session_targets, but that isn&#8217;t the case. You may recall that I had mentioned that in a prior article in this series. The source of this data happens to be found in the sys.server_event_session_fields view. Since this is an EAV model, it also means that I have to more or less look for some value in the &#8220;name&#8221; filed that indicates it is the target file path. With that in mind, I can then create a query such as the following to get my first building block in place.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT sesf.value
	FROM sys.server_event_sessions ses
		INNER JOIN sys.server_event_session_fields sesf
			ON ses.event_session_id = sesf.event_session_id
	WHERE sesf.name = 'filename'
		AND ses.name = 'demosession'</pre><p>The results of this method are pretty clear and simple. I have a file and path directly without the need to parse any XML as was necessary with the method shown that involves querying the running session metadata. Since the data is coming from an EAV model, the value column is defined as a sql_variant data type so I need to convert it. Additionally, I need to add a little trickery to my query to help it find the actual files on disk.</p>
<p>Notice in the results that the original filename is returned as the value. This does not include any of the additional information that is appended to each file in the target. Because of this, a quick REPLACE can be used to insert a wildcard into the filename. This is shown in the next example:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'demosession'
					) cte1
				CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2</pre><p>This is now returning the same sort of results as should be expected for any data in the target for the session. All that is left to do now is tie that back into a query that will parse the XML from the target file(s).</p><pre class="urvanov-syntax-highlighter-plain-tag">/* deployed or running session */
SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		,event_data.value('(event/data[@name="collect_database_name"]/value)[1]','bit') AS collect_database_name
		,event_data.value('(event/data[@name="database_id"]/value)[1]','int') AS database_id
		,event_data.value('(event/data[@name="object_id"]/value)[1]','int') AS object_id
		,event_data.value('(event/data[@name="index_id"]/value)[1]','int') AS index_id
		,event_data.value('(event/data[@name="job_id"]/value)[1]','int') AS job_id
		,event_data.value('(event/data[@name="job_type"]/value)[1]','varchar(max)') AS job_type
		,event_data.value('(event/data[@name="status"]/value)[1]','varchar(max)') AS status
		,event_data.value('(event/data[@name="duration"]/value)[1]','int') AS duration
		,event_data.value('(event/data[@name="retries"]/value)[1]','int') AS retries
		,event_data.value('(event/data[@name="success"]/value)[1]','bit') AS success
		,event_data.value('(event/data[@name="last_error"]/value)[1]','int') AS last_error
		,event_data.value('(event/data[@name="count"]/value)[1]','int') AS EventCount
		,event_data.value('(event/data[@name="statistics_list"]/value)[1]','varchar(max)') AS statistics_list
		,event_data.value('(event/data[@name="database_name"]/value)[1]','varchar(max)') AS database_name
	FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data
	FROM ( SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'demosession'
					) cte1
				CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
			) AS evts ( event_data )
	ORDER BY [TIMESTAMP];</pre><p>Great! I now no longer need to know exactly the path for the session in order to query the data in it. In addition, it doesn&#8217;t matter if the session is running or just merely deployed. This adds the additional benefit that I can run the session to trap the data I hope to get, then stop the session when I think I may have it. Once done, I can evaluate the data and not have the extra overhead of the session running while I look into what has been captured.</p>
<p>This brings us to the next better practice to use when working with the session data. If there are a lot of events in the target to parse, then it can be painfully slow to retrieve the data to evaluate. There needs to be a means to doing it faster.</p>
<h3>Faster Session Parsing</h3>
<p>This is a really easy fix. The recommendation to help speed things along to read the session data is to first dump the data into some sort of table storage. That table can either be a temp table or a permanent staging table. The decision is up to you! For my example, I will just use a temp table.</p>
<p>This is how I would do it:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT t2.event_data AS event_data
		INTO #eventdata
		FROM (SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'demosession'
					) cte1
				CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;</pre><p>This will convert the event_data field into NVARCHAR in the temp table. This means I will need to CONVERT it back to XML in order to parse it. And then to get to that data for my parsing query, I just add it back in as shown in the next example:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
	INTO #xmlpreprocess
	FROM (SELECT REPLACE(CONVERT(NVARCHAR(128),sesf.value),'.xel','*.xel') AS targetvalue
				FROM sys.server_event_sessions ses
					INNER JOIN sys.server_event_session_fields sesf
						ON ses.event_session_id = sesf.event_session_id
				WHERE sesf.name = 'filename'
					AND ses.name = 'demosession'
					) cte1
				CROSS APPLY sys.fn_xe_file_target_read_file(cte1.targetvalue,	NULL, NULL, NULL) t2
		;
--EXECUTE sys.sp_help 'tempdb.dbo.#xmlpreprocess'

SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		,event_data.value('(event/data[@name="collect_database_name"]/value)[1]','bit') AS collect_database_name
		,event_data.value('(event/data[@name="database_id"]/value)[1]','int') AS database_id
		,event_data.value('(event/data[@name="object_id"]/value)[1]','int') AS object_id
		,event_data.value('(event/data[@name="index_id"]/value)[1]','int') AS index_id
		,event_data.value('(event/data[@name="job_id"]/value)[1]','int') AS job_id
		,event_data.value('(event/data[@name="job_type"]/value)[1]','varchar(max)') AS job_type
		,event_data.value('(event/data[@name="status"]/value)[1]','varchar(max)') AS status
		,event_data.value('(event/data[@name="duration"]/value)[1]','int') AS duration
		,event_data.value('(event/data[@name="retries"]/value)[1]','int') AS retries
		,event_data.value('(event/data[@name="success"]/value)[1]','bit') AS success
		,event_data.value('(event/data[@name="last_error"]/value)[1]','int') AS last_error
		,event_data.value('(event/data[@name="count"]/value)[1]','int') AS EventCount
		,event_data.value('(event/data[@name="statistics_list"]/value)[1]','varchar(max)') AS statistics_list
		,event_data.value('(event/data[@name="database_name"]/value)[1]','varchar(max)') AS database_name
	FROM #xmlpreprocess AS evts
	ORDER BY [TIMESTAMP];

DROP TABLE #xmlpreprocess;</pre><p>I have left the sp_help in the example as a quick means to go back and verify that the event_data is truly NVARCHAR, should you choose to do so.</p>
<p>Adding this little step of dumping the data into a table first helps improve the queries to parse the event data by a factor of 3 and sometimes more.</p>
<p>I have shown in this article how to parse session data more efficiently. I have also shown how to ensure the correct file and path can be used every time to get the session data by using just the session name. These tips will help ensure a more pleasant experience when trying to parse the event data from a session.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3169" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/">Better Practices for Reading Event_file Targets</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/15/better-practices-for-reading-event_file-targets/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Dynamically Read event_file Data</title>
		<link>https://jasonbrimhall.info/2015/10/14/dynamically-read-event_file-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dynamically-read-event_file-data</link>
					<comments>https://jasonbrimhall.info/2015/10/14/dynamically-read-event_file-data/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 14 Oct 2015 12:21:54 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3159</guid>

					<description><![CDATA[<p>There needs to be a more efficient means of grabbing the file without having to know the location. Knowing the session name should be adequate enough to parse the payload data from the target. This is exactly what I am going to show in this article - retrieving the file and path based strictly on the name of the session.</p>
The post <a href="https://jasonbrimhall.info/2015/10/14/dynamically-read-event_file-data/">Dynamically Read event_file Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box.png"><img loading="lazy" class="wp-image-3150 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-300x200.png" alt="xe_filetarget_box" width="249" height="166" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-300x200.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box.png 672w" sizes="(max-width: 249px) 85vw, 249px" /></a>In the previous article I covered the <a href="http://bit.ly/1G2QiVX">basics on extracting the payload for the events in a session from the event_file target</a>. That article was a basic introduction.</p>
<p>In this article I want to take that basic knowledge and take it one step further. Being able to extract the data is fine and well. Being able to just do that task at the basic level is hardly sufficient, nor is it very efficient. I&#8217;ll explain that part in a little bit.</p>
<p>Pulling the data from the event_file target in the most basic of manners requires that one know the directory where the files are placed and the names of the files for the session. Granted, one should know this information if they are the one to have created the session. What if you didn&#8217;t create the session? What if you inherited the server with a bunch of sessions already deployed? Worse yet is the case of the magically changing file or location for the session (you know, somebody changed it and didn&#8217;t document the change).</p>
<p>There needs to be a more efficient means of grabbing the file without having to know the location. Knowing the session name should be adequate enough to parse the payload data from the target. This is exactly what I am going to show in this article &#8211; retrieving the file and path based strictly on the name of the session.</p>
<h3>Dynamically Read event_file Data</h3>
<p>I will take the basic example provided previously and use it as a starting point.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM sys.fn_xe_file_target_read_file('C:DatabaseXEDemoSession*.xel',NULL,NULL,NULL) t2</pre><p>Now that I have the basics in place, I need to see how I can get the path of the file based on the name of the session. Looking in sys.dm_xe_session_targets, a column called target_data is revealed. On closer inspection, it is apparent that this column contains xml data and part of that data involves the location of the event_file. With the first clue out of the way, I can build a query such as the following to help build my file path dynamically.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT target_data = CONVERT(XML, target_data)
	FROM sys.dm_xe_session_targets t
		INNER JOIN sys.dm_xe_sessions s
			ON t.event_session_address = s.address
	WHERE t.target_name = 'event_file'
		AND s.name = 'demosession'</pre><p>Clicking on the &#8220;hyperlink&#8221; XML in the target_data column will give me a result such as this:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;EventFileTarget truncated="0"&gt;
  &lt;Buffers logged="0" dropped="0" /&gt;
  &lt;File name="C:\Database\XE\DemoSession_0_130892666554200000.xel" /&gt;
&lt;/EventFileTarget&gt;</pre><p>This is good stuff so far. Now I need to be able to tie that into the previous &#8220;base&#8221; type query. This can be done beautifully thanks to the APPLY operator. Here is an example of that:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
	FROM ( SELECT target_data = CONVERT(XML, target_data)
				FROM sys.dm_xe_session_targets t
					INNER JOIN sys.dm_xe_sessions s
						ON t.event_session_address = s.address
				WHERE t.target_name = 'event_file'
					AND s.name = 'demosession'
			) cte1
	CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget )
	CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name',
		'varchar(1000)'),
		NULL, NULL, NULL) t2</pre><p>Knowing that I need to follow the path <strong>//EventFileTarget/File</strong>, I can take advantage of parsing the XML via the APPLY operator and then pass the node data to the next APPLY which is where I am calling the fn_xe_file_target_read_file function.</p>
<p>Running the query will yield a row for each event in the session should there be any events that have occurred since the session was last started.</p>
<p>Now that I have two stages of this thing built, it the next step is ridiculously easy. All that I have to do now is bring in the columns that I want to query from this session.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* running session */
SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		,event_data.value('(event/data[@name="collect_database_name"]/value)[1]','bit') AS collect_database_name
		,event_data.value('(event/data[@name="database_id"]/value)[1]','int') AS database_id
		,event_data.value('(event/data[@name="object_id"]/value)[1]','int') AS object_id
		,event_data.value('(event/data[@name="index_id"]/value)[1]','int') AS index_id
		,event_data.value('(event/data[@name="job_id"]/value)[1]','int') AS job_id
		,event_data.value('(event/data[@name="job_type"]/value)[1]','varchar(max)') AS job_type
		,event_data.value('(event/data[@name="status"]/value)[1]','varchar(max)') AS status
		,event_data.value('(event/data[@name="duration"]/value)[1]','int') AS duration
		,event_data.value('(event/data[@name="retries"]/value)[1]','int') AS retries
		,event_data.value('(event/data[@name="success"]/value)[1]','bit') AS success
		,event_data.value('(event/data[@name="last_error"]/value)[1]','int') AS last_error
		,event_data.value('(event/data[@name="count"]/value)[1]','int') AS EventCount
		,event_data.value('(event/data[@name="statistics_list"]/value)[1]','varchar(max)') AS statistics_list
		,event_data.value('(event/data[@name="database_name"]/value)[1]','varchar(max)') AS database_name
	FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM ( SELECT target_data = CONVERT(XML, target_data)
							FROM sys.dm_xe_session_targets t
								INNER JOIN sys.dm_xe_sessions s
									ON t.event_session_address = s.address
							WHERE t.target_name = 'event_file'
								AND s.name = 'demosession'
						) cte1
					CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget )
					CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name',
																'varchar(1000)'),
																NULL, NULL, NULL) t2
			) AS evts ( event_data )
	ORDER BY [TIMESTAMP];</pre><p>Great! I now no longer need to know exactly the path for the session in order to query the data in it. Despite that, I really should figure out what that path is and make sure I have it documented. I now want to draw attention to the comment made at the beginning of the last script. This particular script will only work when the session is running. Don&#8217;t despair, I will cover how to build this dynamically for any session that is not currently running. That will be covered in the next article where I discuss &#8220;Better Practices&#8221; for reading event_file data.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3159" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/14/dynamically-read-event_file-data/">Dynamically Read event_file Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/14/dynamically-read-event_file-data/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Intro to Reading Event_File Target Data</title>
		<link>https://jasonbrimhall.info/2015/10/13/intro-to-reading-event_file-target-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=intro-to-reading-event_file-target-data</link>
					<comments>https://jasonbrimhall.info/2015/10/13/intro-to-reading-event_file-target-data/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 13 Oct 2015 12:21:02 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3148</guid>

					<description><![CDATA[<p>The event_file target is an asynchronous consumer for Extended Events. This target stores the received payload in a proprietary binary format. Because of this, one needs to use the sys.fn_xe_file_target_read_file function. This article will discuss this function and show how to use it in its simplest form.</p>
The post <a href="https://jasonbrimhall.info/2015/10/13/intro-to-reading-event_file-target-data/">Intro to Reading Event_File Target Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box.png"><img loading="lazy" class="wp-image-3150 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-300x200.png" alt="xe_filetarget_box" width="249" height="166" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-300x200.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box-50x33.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/xe_filetarget_box.png 672w" sizes="(max-width: 249px) 85vw, 249px" /></a>Having covered the metadata for a deployed session from just about every angle (yes there is more on metadata that could be discussed, has not yet been discussed, and that I am not planning on covering at this time), it is high-time to start figuring out how to query the payload that is desired to be trapped by the session that was deployed.</p>
<p>Early on in this series, I introduced the <a href="http://bit.ly/1XfzO27">catalog views</a>, <a href="http://bit.ly/1Uu4QyY">DMVs</a> and the <a href="http://bit.ly/1KOU85a">supporting cast</a> for Extended Events. In those articles introducing the supporting cast and views for XEvents, there is a critical player in this arena that was intentionally neglected. That player is the function that helps one to read the payload data that was captured via the session definition. That function is sys.fn_xe_file_target_read_file.</p>
<h3>Functions and Files &#8211; an intro to Reading Event_File Target Data</h3>
<p>The event_file target is an asynchronous consumer for Extended Events. This target stores the received payload in a proprietary binary format. Because of this, one needs to use the sys.fn_xe_file_target_read_file function. Using the function will then convert the data into a somewhat usable and more friendly format called XML.</p>
<p>With the session data being in a more human friendly form, a little bit more work needs to be done for that data to be really helpful to the data professional. To be able to get the results into a format more conducive to the consumption of most data professionals, one must use XQuery. This article is just going to focus on getting the data out of the event_file target and into the XML format. Working with the XML is a topic for another time.</p>
<p>The sys.fn_xe_file_target_read_file function takes a few parameters. The most important of these parameters are the first two parameters. And even then, that only applies to SQL Server 2008 and R2. Since SQL Server 2012, one really only needs to focus on the first parameter &#8211; path. That said, the file_offset can be an extremely useful field, especially under the circumstances where the session data is to be &#8220;warehoused&#8221; or a monitoring and alerting solution is to be built from Extended Events.</p>
<p>The path parameter is used to specify the on-disk path to the trace file that has been created. Not just the trace file, but all of the trace files associated to the session. A single file name (with path) can be specified here. Or a more common use would be to add a wildcard to the file name (with path) so all files could be included. If a wildcard is not used, then the initial_file_name parameter is pretty useless since only one file will be read anyway. If the wildcard is used, then the initial_file_name parameter can be used to determine the starting point for reading the session data.</p>
<p>The second parameter is mdpath and is only applicable to SQL Server 2008 and R2. This is to specify the path of the metadata file that would have been created along with the event file as a part of the session in those versions of SQL Server. If SQL Server 2012 is being used, then this parameter is unnecessary.</p>
<p>The initial_offset parameter helps instruct the function what to ignore and what to process when reading in the session data from the target. If storing all session data into a table (basically warehousing the data), this is an extremely helpful parameter. The use of this parameter would help the import process only import <strong>new</strong> data from the target. It would be a nightmare to import the same <em>monitoring</em> data every time the load process ran.</p>
<p>Using the same demosession session that I have used throughout the series, here is a basic example of how to retrieve that session data.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM sys.fn_xe_file_target_read_file('C:\Database\XE\DemoSession*.xel',NULL,NULL,NULL) t2</pre><p>In this example, I am just pulling the session data straight back without any manipulation. I have CONVERTED the event_data to XML only as an exercise to make it easier to evaluate. If I did not convert the event_data, it would return an XML string in NVARCHAR format.</p>
<p>If I needed to be able to explore the data in a more friendly format, then I need to shred the XML such as I have done in the following example:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		,event_data.value('(event/data[@name="collect_database_name"]/value)[1]','bit') AS collect_database_name
		,event_data.value('(event/data[@name="database_id"]/value)[1]','int') AS database_id
		,event_data.value('(event/data[@name="object_id"]/value)[1]','int') AS object_id
		,event_data.value('(event/data[@name="index_id"]/value)[1]','int') AS index_id
		,event_data.value('(event/data[@name="job_id"]/value)[1]','int') AS job_id
		,event_data.value('(event/data[@name="job_type"]/value)[1]','varchar(max)') AS job_type
		,event_data.value('(event/data[@name="status"]/value)[1]','varchar(max)') AS status
		,event_data.value('(event/data[@name="duration"]/value)[1]','int') AS duration
		,event_data.value('(event/data[@name="retries"]/value)[1]','int') AS retries
		,event_data.value('(event/data[@name="success"]/value)[1]','bit') AS success
		,event_data.value('(event/data[@name="last_error"]/value)[1]','int') AS last_error
		,event_data.value('(event/data[@name="count"]/value)[1]','int') AS EventCount
		,event_data.value('(event/data[@name="statistics_list"]/value)[1]','varchar(max)') AS statistics_list
		,event_data.value('(event/data[@name="database_name"]/value)[1]','varchar(max)') AS database_name
	FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM sys.fn_xe_file_target_read_file('C:\Database\XE\DemoSession*.xel',NULL,NULL,NULL) t2
			) AS evts ( event_data )
	ORDER BY [TIMESTAMP];</pre><p>Using the function in each of these ways will work consistently and reliably. One major drawback is the need to know what the filepath is for the session in question. Even if the filepath was known at one time and saved in a script (such as the previous examples), it is not far-fetched to have another person to change the filepath and not notify anybody or update any of the scripts.</p>
<p>In the next article, I show a more robust means to access this target data from the files.</p>
<p>This has been another article in the 60 Days of XE series. If you have missed any of the articles, or just want a refresher, <a href="http://bit.ly/XE60Days">check out the TOC</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3148" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/13/intro-to-reading-event_file-target-data/">Intro to Reading Event_File Target Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/13/intro-to-reading-event_file-target-data/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Backup Deployed Sessions</title>
		<link>https://jasonbrimhall.info/2015/10/05/backing-up-sessions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=backing-up-sessions</link>
					<comments>https://jasonbrimhall.info/2015/10/05/backing-up-sessions/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Oct 2015 12:09:00 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3076</guid>

					<description><![CDATA[<p>Having just completed several segments on the metadata for deployed sessions, it is time to bring all of that information together and see how it can be used - by showing how to backup deployed sessions.</p>
The post <a href="https://jasonbrimhall.info/2015/10/05/backing-up-sessions/">Backup Deployed Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>There is a wealth of information within Extended Events. Throughout this series, I have been working on exposing that wealth of information. A good bit of this information happens to be the metadata for Extended Events, and another bit of this information is tied <img loading="lazy" class=" wp-image-3079 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/crane-300x273.png" alt="crane" width="253" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/crane-300x273.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/crane-50x46.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/crane.png 614w" sizes="(max-width: 253px) 85vw, 253px" />to the metadata for deployed Sessions. To dive into what I have done so far with this plenitude of information, you can <a href="http://bit.ly/XE60Days">review the series here</a>.</p>
<p>What is the point in covering all of this information? I like to call it building blocks. Take a concept little by little and build upon it, while working toward a more comprehensive understanding as well as to hopefully be able to use it for a bigger product.</p>
<p>Having just completed several segments on the metadata for deployed sessions, it is time to bring all of that information together and see how it can be used.</p>
<h3>Bringing it Together</h3>
<p>Having a solid foundation and understanding of what the metadata is and where it is really helps in creating scripts that can be useful in the day to day management of deployed Extended Event Sessions. For me, the ability to recreate a deployed session, without the use of the GUI is pretty essential. Contributing to the need to be able to do this via script and not a GUI is that (without a<a href="https://extendedeventmanager.codeplex.com/" class="broken_link"> third party product</a>) there is no GUI in SQL Server 2008.</p>
<p>To demonstrate how to create a script to serve as a backup of a deployed session, I will first return to the &#8220;demosession&#8221; script that I have used throughout this series.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [demosession2] ON SERVER
ADD EVENT sqlserver.auto_stats ( 
	SET collect_database_name = ( 1 )			--fields
	ACTION (
			  package0.event_sequence		--actions
			, sqlos.cpu_id
			, sqlserver.database_id
			, sqlserver.database_name 
			)
	WHERE ( [database_name] = N'AdventureWorks2014' )	--events
	)
ADD TARGET package0.event_file 
	( SET filename = N'demosession'				--fields
		, max_file_size = ( 50 )			--fields
		, max_rollover_files = ( 6 )			--fields
			),
ADD TARGET package0.ring_buffer
		(SET max_events_limit=(666)			--fields
				,max_memory=(65536) --fields --max buffer size
				,occurrence_number=(3)		--fields
			)
WITH ( EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS	--session
		, MAX_DISPATCH_LATENCY = 5 SECONDS		--session
		, MAX_EVENT_SIZE = 2 MB				--session
		, MEMORY_PARTITION_MODE = PER_NODE		--session
		, TRACK_CAUSALITY = ON				--session
		, STARTUP_STATE = ON				--session
	);
GO</pre><p>And if I color-code this script as I have done previously:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views.png"><img loading="lazy" class="alignnone wp-image-3082 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views-1024x930.png" alt="session_colorcode_views" width="560" height="509" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views-1024x930.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views-300x273.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views-50x45.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/session_colorcode_views.png 1343w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this image, I have separated out the major components by color. The segments that pertain to the session creation and the settings for that session are in grey. Then the target information is in red and so on. I added my notes (to help indicate where the components can be found in metadata) and colored them purple. The wrinkle here is in the SET operations since that is a component that crosses boundaries of the core concepts.</p>
<p>Taking this breakdown, and a serious desire to be able to recreate any session that has been deployed (without the GOOEY), and I have been able to create the following script that will do just that &#8211; backup deployed sessions.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET NOCOUNT ON;

DECLARE @statement VARCHAR(MAX)
	,@statement1 VARCHAR(MAX)
	,@statement2 VARCHAR(MAX)
	,@sessionname VARCHAR(128) = 'system_health'
/* order of events scripted is different 
default order of creation is different than if scripted from the gui
the gui scripts by alpha order of package then event
while original creation has order by event_id only
*/
	,@eventorder VARCHAR(64) = 'original'; --'original' for order based on original script, --'ssms' for order based on ssms gui scripter 

SELECT @statement = 'CREATE EVENT SESSION [' + ses.name +'] ON SERVER
	' 
	FROM sys.server_event_sessions ses
	WHERE ses.name = @sessionname;

WITH presel AS (
SELECT ses.name AS SessionName
		, sese.event_id
		, sese.package
		, 'ADD EVENT ' + sese.package +'.' + sese.name + ' (' AS EventName
		, CASE WHEN ISNULL(sese.predicate,'') = '' THEN ')' ELSE 'WHERE ' + sese.predicate + ' )' END AS SQLPredicate
		, CASE WHEN ISNULL(sesf.name,'') = '' THEN '' ELSE 'SET ' + sesf.name + ' = ( ' + CAST(sesf.value AS VARCHAR(10)) + ' )' END AS SETOperation
	FROM sys.server_event_sessions ses
		INNER JOIN sys.server_event_session_events sese
			ON ses.event_session_id = sese.event_session_id
		LEFT OUTER JOIN sys.server_event_session_fields sesf
			ON sese.event_session_id = sesf.event_session_id
			AND sese.event_id = sesf.object_id
	WHERE ses.name = @sessionname
), actpresel AS (SELECT ses.name AS SessionName, sesa.event_session_id, sesa.event_id, sesa.package + '.' + sesa.name AS ActPack
		FROM sys.server_event_session_events sese
		INNER JOIN sys.server_event_session_actions sesa
			ON sese.event_session_id = sesa.event_session_id
			AND sese.event_id = sesa.event_id
		INNER JOIN sys.server_event_sessions ses
			ON sesa.event_session_id = ses.event_session_id
	WHERE ses.name = @sessionname)
, pstuff AS (SELECT p.SessionName, p.event_id,'ACTION ( 
				' + STUFF((SELECT ', ' + pin.ActPack + '
				'
				FROM actpresel pin
				WHERE pin.SessionName = p.SessionName
					AND pin.event_id = p.event_id
			FOR XML PATH(''),TYPE).value('.','varchar(max)') , 1, 2, '') + '
			)' AS ActionPack
		FROM actpresel p
		GROUP BY p.SessionName, p.event_id
		)

SELECT @statement1 = @statement + STUFF(
	(SELECT ', ' + CAST(p.EventName + '
		' + p.SETOperation + '
		' + CASE WHEN ISNULL(ps.ActionPack,'') = '' THEN '' ELSE ps.ActionPack END + '
		' + p.SQLPredicate + '
' AS VARCHAR(MAX) ) AS EventStatement
	FROM presel p 
		LEFT OUTER JOIN pstuff ps
			ON p.SessionName = ps.SessionName
			AND p.event_id = ps.event_id
	ORDER BY p.event_id 
	--ORDER BY p.package, p.EventName 
	FOR XML PATH(''),TYPE).value('.', 'varchar(max)'), 1, 2, '')
	,@statement2 = @statement + STUFF(
	(SELECT ', ' + CAST(p.EventName + '
		' + p.SETOperation + '
		' + CASE WHEN ISNULL(ps.ActionPack,'') = '' THEN '' ELSE ps.ActionPack END + '
		' + p.SQLPredicate + '
' AS VARCHAR(MAX) ) AS EventStatement
	FROM presel p 
		LEFT OUTER JOIN pstuff ps
			ON p.SessionName = ps.SessionName
			AND p.event_id = ps.event_id
	ORDER BY p.package, p.EventName 
	FOR XML PATH(''),TYPE).value('.', 'varchar(max)'), 1, 2, '')

IF @eventorder = 'original'
	BEGIN
		SET @statement = @statement1
	END
IF @eventorder = 'ssms'
	BEGIN
		SET @statement = @statement2
	END

SELECT @statement = @statement + STUFF((SELECT ', ' +  '
ADD TARGET ' + sest.package + '.' + sest.name + '
			(SET ' + ca.setop + ' )
'
	FROM sys.server_event_sessions ses
		INNER JOIN sys.server_event_session_targets sest
			ON ses.event_session_id = sest.event_session_id
		CROSS APPLY (SELECT STUFF((SELECT ', ' + CAST(sesf.name AS VARCHAR(128)) + ' = ' + CASE WHEN ISNUMERIC(CAST(sesf.value AS VARCHAR(128))) = 1 
							THEN '( ' + CAST(sesf.value AS VARCHAR(128)) + ' )
							'
							ELSE 'N''' + CAST(sesf.value AS VARCHAR(128)) + '''
						' END AS setop
				FROM sys.server_event_session_fields sesf
					INNER JOIN sys.server_event_sessions sesi
						ON sesi.event_session_id = sesf.event_session_id
					INNER JOIN sys.server_event_session_targets sesti
						ON sesf.object_id = sesti.target_id
						AND sesi.event_session_id = sesti.event_session_id
				WHERE sest.target_id = sesti.target_id
					AND sest.event_session_id = sesti.event_session_id
					FOR XML PATH(''),TYPE).value('.','varchar(max)') , 1, 2, '') ) AS ca(setop)

	WHERE ses.name = @sessionname
			FOR XML PATH(''),TYPE).value('.','varchar(max)') , 1, 2, '') 
		;

SELECT @statement = @statement + 
CAST('WITH ( MAX_MEMORY = ' + CAST(ses.max_memory AS VARCHAR(20)) +' KB
		,EVENT_RETENTION_MODE = ' + ses.event_retention_mode_desc +'
		, MAX_DISPATCH_LATENCY = ' + CAST(ses.max_dispatch_latency/1000 AS VARCHAR(20)) +' SECONDS
		, MAX_EVENT_SIZE = ' + CAST(ses.max_event_size AS VARCHAR(20))+ ' KB
		, MEMORY_PARTITION_MODE = '+ ses.memory_partition_mode_desc +'
		, TRACK_CAUSALITY = ' + CASE ses.track_causality WHEN 1 THEN 'ON' ELSE 'OFF' END +'
		, STARTUP_STATE = ' + CASE ses.startup_state WHEN 1 THEN 'ON' ELSE 'OFF' END +'
	);' AS VARCHAR(1024)) 
	FROM sys.server_event_sessions ses
	WHERE ses.name = @sessionname;

PRINT @statement;</pre><p>I have tested this script back through SQL Server 2008 and up through SQL Server 2014. The script has been tested against complex sessions as well as simple sessions (e.g. the &#8220;demosession&#8221; session I have been using throughout the series).</p>
<p>While testing, I did run into an interesting anomaly so I had to add a little bit of awkwardness to the script. When comparing the original script for &#8220;system_health&#8221; (that can be found in the u_tables.sql script in the Install folder), to what was produced while scripting sessions from the GUI, I noticed that my script was recreating the session in the same fashion that the original script was doing it. But this did not match what the GUI did.</p>
<p>When scripting from SSMS (the GUI), the events in the session are ordered by Package and then by Event name. My script, originally, was ordering the events by Event_id which is the same as can be found in the u_tables.sql script. Due to this, I added a parameter to allow for the different sort methods. This also underscores that when a session is deployed, the order of Events in that first script is the order the Events will be created within the metadata.</p>
<p>I decided to output the results of the script via a print statement. This permits me a chance to see the entire script and review it. Then, I can copy to a new window and execute or I can save the script.</p>
<p>With this script, I can quickly do what is an essential function of a DBA, I can perform targeted backups of my deployed sessions. Another way of viewing it is that I can reverse engineer (without the GOOEY) any <em>user definable session</em> that is deployed to the server.</p>
<p>This is just one of many articles in this series. In this article, I demonstrated how to backup a deployed session and create a script for recovery purposes of a targeted session. To find more useful information about extended events, you can <strong><a href="http://bit.ly/XE60Days">get caught up here</a></strong>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3076" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/05/backing-up-sessions/">Backup Deployed Sessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/05/backing-up-sessions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SET Operations and Metadata</title>
		<link>https://jasonbrimhall.info/2015/10/02/set-operations-and-metadata/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=set-operations-and-metadata</link>
					<comments>https://jasonbrimhall.info/2015/10/02/set-operations-and-metadata/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 02 Oct 2015 12:47:42 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3065</guid>

					<description><![CDATA[<p>SET operations in extended events are the extra configurations that can be made to various components. As an example, a target can be configured with certain properties via the use of a SET operation when creating the Extended Event Session. The best way to see the SET Options and Metadata, is by seeing it in action.</p>
The post <a href="https://jasonbrimhall.info/2015/10/02/set-operations-and-metadata/">SET Operations and Metadata</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Having covered the core concepts of deployed session metadata (events, actions, targets, predicates), there is one more topic to cover. This is more of a subset of those concepts in that this applies to more than one of the core concepts, but it isn&#8217;t really a stand-alone topic. This is the sub-topic of SET operations. This also happens to be the topic I was referring to when I covered the metadata of session events and targets.</p>
<p>SET operations in extended events are the extra configurations that can be made to various components. As an example, a target can be configured with certain properties via the use of a SET operation when creating the Extended Event Session. The best way to see this is by seeing it in action.</p>
<h3>SET Operations and Metadata</h3>
<p>It is time, once again, to break out that tried and true example script that I have been using throughout the past several articles.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [demosession] ON SERVER
ADD EVENT sqlserver.auto_stats ( 

	SET collect_database_name = ( 1 )		--Event Fields Screen

	ACTION (
			  package0.event_sequence					--Actions Screen
			, sqlos.cpu_id
			, sqlserver.database_id
			, sqlserver.database_name 
			)

	WHERE ( [database_name] = N'AdventureWorks2014' ) --Predicates Screen

	)

ADD TARGET package0.event_file 
		( SET filename = N'demosession'		--Data Storage Screen
			, max_file_size = ( 50 )	--Data Storage Screen
			, max_rollover_files = ( 6 )	--Data Storage Screen
			),
ADD TARGET package0.ring_buffer
		(SET max_events_limit=(666)		--Data Storage Screen
				,max_memory=(65536)	--Data Storage Screen
				,occurrence_number=(3)	--Data Storage Screen
			)

WITH ( EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS	--Advanced Screen
		, MAX_DISPATCH_LATENCY = 5 SECONDS	--Advanced Screen
		, MAX_EVENT_SIZE = 2048 KB		--Advanced Screen
		, MEMORY_PARTITION_MODE = PER_NODE	--Advanced Screen
		, TRACK_CAUSALITY = ON			--Opening Screen
		, STARTUP_STATE = ON			--Opening Screen
	);
GO</pre><p>If I follow the same pattern as has been done in previous articles, I could eliminate everything from the script that is not a set operation. Instead, I will just highlight those SET operations with the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode.png"><img loading="lazy" class="alignnone wp-image-3071 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode-1024x939.png" alt="set_operations_colorcode" width="560" height="514" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode-1024x939.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode-300x275.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode-50x46.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/set_operations_colorcode.png 1344w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Keeping with the same color-coding that has been used in the previous articles, I have added just a few highlights. Highlighted in purple, are all of the SET operations for this particular session creation script. In the case of the Targets, these set operations are properties of the Target. In the case of the Event SET operation, this happens to be a &#8220;customizable&#8221; type within the Event payload.</p>
<p>Now that we know what these SET operations can be, and where they might exist, how does one access this information? It was seen in the article about the deployed Event metadata and also the article about deployed Target metadata, that this data is not visible within those views. This is where the entity attribute value data model comes back into play within Extended Events. To expose this metadata, one needs to query the sys.server_event_session_fields system catalog view.</p>
<p>Querying the sys.server_event_session_fields view directly will produce some interesting information. While interesting, it is less than complete. Sure, if you query the view, you can see various attributes and the value of those attributes. Unfortunately, the picture is just not complete.</p>
<p>For instance, if you query this view, you will see that there is a name, value, session id, and even an object id. The object id is not entirely descriptive as to what exactly it is (and neither is the documentation). However, one could make the quick presumption based on some of the attribute names and arrive at a conclusion that the object id maps to the id field of the other metadata views (e.g. event_id and target_id). Working with this information, a more clear picture can be painted via the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ses.name AS SessionName
		, sesf.name AS FieldName
		, sesf.value AS FieldValue
		, CASE	WHEN ISNULL(sese.event_session_id, '') &lt;&gt; '' 
				THEN 'Event'
				WHEN ISNULL(sest.event_session_id, '') &lt;&gt; '' 
				THEN 'Target'
			END AS ObjectType
		, sese.name AS EventName
		, sest.name AS TargetType
	FROM sys.server_event_session_fields sesf
		INNER JOIN sys.server_event_sessions ses
			ON ses.event_session_id = sesf.event_session_id
		LEFT OUTER JOIN sys.server_event_session_events sese
			ON sesf.object_id = sese.event_id
			AND ses.event_session_id = sese.event_session_id
		LEFT OUTER JOIN sys.server_event_session_targets sest
			ON sesf.object_id = sest.target_id
			AND ses.event_session_id = sest.event_session_id
	WHERE ses.name = 'demosession';</pre><p>This query joins back to the event metadata and target metadata based on the object_id. If there is a SET operation for the Event or the Target, then this query will return those results. You may be wondering why I am only looking at the sys.server_event_session_target and _event views. As it happens, the core component of Actions does not have a set operation. As for the Predicate core component, recall that the Predicate is stored as a property of the Event.</p>
<p>Looking at the results of that query for the &#8220;demosession&#8221; session, I would see this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output.jpg"><img loading="lazy" class="alignnone wp-image-3072 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output-1024x263.jpg" alt="setops_output" width="560" height="144" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output-1024x263.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output-300x77.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output-50x13.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/10/setops_output.jpg 1376w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Comparing these results to the script, I can easily see how the properties start to map and see that the presumptions that I made were accurate. Now I can see all of the <strong>critical</strong> information that is affiliated to the creation of a Target for an Event Session.</p>
<p>An important note about one value, in particular, needs to be made. The filename property only has the name of the file in this particular case. If I had specified more than just a filename, and decided to include a specific filepath for instance, then the path and filename would be the value for this property. But since I only provided a name for the file without a path at session creation, the file was created in the default path and the engine will look in that default path automatically if a path is not created (when looking to query the file for example).</p>
<p>To this point, I have now covered every facet of how to retrieve the metadata for a deployed Session. I have demonstrated how to retrieve everything from the Target to the Event to the Predicate and all the way down to the SET operations and specific Session level settings. With all of this information, I will show what can be done with it in the next article.</p>
<p>With all that has been covered (and the length of this series) on the topic of Extended Events, it is easy to have missed an article in the series, or to even need a quick recap of one of the topics. If this is the case, then feel free to peruse the <a href="http://bit.ly/XE60Days">table of contents &#8211; here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3065" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/02/set-operations-and-metadata/">SET Operations and Metadata</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/02/set-operations-and-metadata/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Session Target Metadata</title>
		<link>https://jasonbrimhall.info/2015/10/01/session-target-metadata/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=session-target-metadata</link>
					<comments>https://jasonbrimhall.info/2015/10/01/session-target-metadata/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 01 Oct 2015 12:04:28 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3059</guid>

					<description><![CDATA[<p>In the case of the final core component, Targets, the exploration into the metadata can be a little awkward. At least at first. Read on to see how to explore the deployed session target metadata at a preliminary level.</p>
The post <a href="https://jasonbrimhall.info/2015/10/01/session-target-metadata/">Session Target Metadata</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/target_metadata.png"><img loading="lazy" class="size-medium wp-image-3060 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/target_metadata-300x262.png" alt="target_metadata" width="300" height="262" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/target_metadata-300x262.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target_metadata-50x44.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target_metadata.png 725w" sizes="(max-width: 300px) 85vw, 300px" /></a>With the ability to find the metadata for deployed session, events and actions firmly under the belt, the natural progression would lead one to find the metadata for the target(s) attached to a session.</p>
<p>Exploring the metadata for the core components of Extended Events Sessions can be an extremely fruitful undertaking. In the case of exploring the Event metadata for deployed sessions, one can also quickly discover the predicate for that event.</p>
<p>In the case of the final core component, Targets, the exploration into the metadata can be a little awkward. At least at first.</p>
<h3>Session Target Metadata</h3>
<p>Once again, I will refer immediately back to the example code I have used throughout these dives into the metadata internals.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [demosession] ON SERVER
ADD EVENT sqlserver.auto_stats ( 

	SET collect_database_name = ( 1 )		--Event Fields Screen

	ACTION (
			  package0.event_sequence	--Actions Screen
			, sqlos.cpu_id
			, sqlserver.database_id
			, sqlserver.database_name 
			)

	WHERE ( [database_name] = N'AdventureWorks2014' )--Predicates Screen

	)

ADD TARGET package0.event_file 
		( SET filename = N'demosession'		--Data Storage Screen
			, max_file_size = ( 50 )	--Data Storage Screen
			, max_rollover_files = ( 6 )--Data Storage Screen
			),
ADD TARGET package0.ring_buffer
		(SET max_events_limit=(666)		--Data Storage Screen
				,max_memory=(65536)	--Data Storage Screen
				,occurrence_number=(3)	--Data Storage Screen
			)

WITH ( EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS	--Advanced Screen
		, MAX_DISPATCH_LATENCY = 5 SECONDS				--Advanced Screen
		, MAX_EVENT_SIZE = 2048 KB		--Advanced Screen
		, MEMORY_PARTITION_MODE = PER_NODE	--Advanced Screen
		, TRACK_CAUSALITY = ON			--Opening Screen
		, STARTUP_STATE = ON			--Opening Screen
	);
GO</pre><p>And now, with a little less noise and just a focus on the targets of the session.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* just the targets */
CREATE EVENT SESSION [demosession] ON SERVER
...

ADD TARGET package0.event_file 
		( SET filename = N'demosession'		--Data Storage Screen
			, max_file_size = ( 50 )	--Data Storage Screen
			, max_rollover_files = ( 6 )	--Data Storage Screen
			),
ADD TARGET package0.ring_buffer
		(SET max_events_limit=(666)		--Data Storage Screen
				,max_memory=(65536)	--Data Storage Screen
				,occurrence_number=(3)	--Data Storage Screen
			)

...
GO</pre><p>In this condensed version of the code, all that is present (of interest) is the code necessary to create two targets for this session as it gets deployed. Quite similar to how one can explore the metadata of the session, events, and actions, one merely needs to query the catalog view for the targets &#8211; sys.server_event_session_targets. Or so it would seem. Let&#8217;s start with the base query once again.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ses.name AS SessionName,sest.name AS Targettype, sest.target_id, sest.package, sest.module
	FROM sys.server_event_session_targets sest
		INNER JOIN sys.server_event_sessions ses
			ON sest.event_session_id = ses.event_session_id
	WHERE ses.name = 'demosession';</pre><p>For the &#8220;demosession&#8221; session that has been deployed, I will receive the following results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results.jpg"><img loading="lazy" class="alignnone wp-image-3061 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results-1024x201.jpg" alt="sessiontargets_results" width="560" height="110" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results-1024x201.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results-300x59.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results-50x10.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/sessiontargets_results.jpg 1495w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Take note of the name column from sys.server_event_session_targets. In my query, I have renamed it to Targettype. If this is compared back to the original script, it becomes apparent that the target type or name of the target type is what is used in this particular view. These results represent essentially the entirety of the catalog view (minus the event_session_id column which I used to join back to sys.server_event_sessions in order to filter by session name).</p>
<p>Unlike the metadata for the session, events and actions, the target metadata view is less useful. That is, by itself. Sure I can find out the types of targets attached to the session. But this view directly does not give me the pertinent information such as the file name when a file target is used. With that said, the information is available and I will be covering that in the next article.</p>
<p>As for further use out of this particular view, there is still some metadata to be gained. Let&#8217;s dive just a bit more.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ses.name AS SessionName,sest.name AS Targettype, sest.target_id, sest.package
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
	FROM sys.server_event_session_targets sest
		INNER JOIN sys.server_event_sessions ses
			ON sest.event_session_id = ses.event_session_id
		INNER JOIN sys.dm_xe_objects xo
			ON xo.name = sest.name
			AND xo.object_type = 'target'
		INNER JOIN sys.dm_xe_packages xp
			ON xp.module_guid = sest.module
			AND xp.name = sest.package
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address
	WHERE ses.name = 'demosession';</pre><p>For now, this is still pretty basic information. As I said just a moment ago, the more fruitful information is not readily available direct from this view. The exploration of reaching that information will be revealed in the next article.</p>
<p>It is important to discuss this particular view to try and help prevent a bit of frustration. I would personally think that the view should expose the pertinent metadata for the session. This is one case where extra steps need to be taken and an exploration into a different view will be required &#8211; a view that does not necessarily equate to Target.</p>
<p>In this short tutorial, I covered a quick means to view the target types that are deployed for a specific session. This is just one of a long series of articles on Extended Events. Explore the <a href="http://bit.ly/XE60Days">other articles here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3059" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/10/01/session-target-metadata/">Session Target Metadata</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/10/01/session-target-metadata/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The Extended Event GUI</title>
		<link>https://jasonbrimhall.info/2015/09/25/the-extended-event-gui/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-extended-event-gui</link>
					<comments>https://jasonbrimhall.info/2015/09/25/the-extended-event-gui/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 25 Sep 2015 12:29:31 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3018</guid>

					<description><![CDATA[<p>The Extended Events GUI provides a visual access to the Extended Events engine that can help to better understand the XEvents Engine and how a Session is built.</p>
The post <a href="https://jasonbrimhall.info/2015/09/25/the-extended-event-gui/">The Extended Event GUI</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the previous article in this series I shared the basics around <a href="http://bit.ly/1iy9srM">assembling an XEvent session</a>. The method used in that article was via TSQL script. In this article, I will introduce the Extended Events GUI. While I prefer to use TSQL to create and manage my sessions, the GUI can help to visually better understand some of these concepts.</p>
<p>If you are a bit behind in the series, here is <a href="http://bit.ly/XE60Days">the table of contents</a> so you can get caught up again. Now is as good a time as any to catch up on the series. right?</p>
<p>As I was saying, I prefer to use TSQL to create my XEvent Sessions. The biggest reason being that a script can be saved and used to easily recreate the session on multiple servers. The next big reason is that the script can also explain exactly what is being done to create the session. With the Extended Event GUI, extra steps need to be taken to ensure the session will be created as desired (albeit small steps but extra nonetheless). The third big reason I prefer to use a script is that the GUI was not available until SQL Server 2012.</p>
<h2>The GUI</h2>
<p>Gaining access to the Extended Events GUI is rather easy to do from within SSMS. Simply expand the Management Node and then the Extended Events node. Once there, right click &#8220;Sessions&#8221; and select &#8220;New Session&#8230;&#8221; or &#8220;New Session Wizard&#8221; from the context menu. Here is a nice visual on that with the following image.</p>
<p><img loading="lazy" class="size-medium wp-image-3019 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/gettoXEgui-251x300.png" alt="gettoXEgui" width="251" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/gettoXEgui-251x300.png 251w, https://jasonbrimhall.info/wp-content/uploads/2015/09/gettoXEgui-42x50.png 42w, https://jasonbrimhall.info/wp-content/uploads/2015/09/gettoXEgui.png 478w" sizes="(max-width: 251px) 85vw, 251px" /></p>
<p>The option I will focus on is the &#8220;New Session&#8230;&#8221; option. I would hope that the Wizard is avoided if the GUI must be used to create sessions. Once &#8220;New Session&#8230;&#8221; is selected, the following screen will be presented to you:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui.png"><img loading="lazy" class="alignnone wp-image-3022 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui-1024x716.png" alt="session_gui" width="560" height="392" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui-1024x716.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui-300x210.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_gui.png 1839w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this image, I have color coded some of the sections of this screen to match the previous article and the components previously discussed. From this screen, one will not be able to see all of the components that compose an Extended Event Session. To reach the remaining components, a little more digging is necessary.</p>
<p>Also of importance is to note that a warning will pop up on this screen that after giving the session a name, the minimum requirements to create an XEvent Session have not been met. The minimum requirements being that a name and event be supplied to the session. Nothing said about the remaining components. This is a small niggle for me in that, while technically an Action and a predicate are optional, a target really should be defined (more on that in a bit). I also recommend that predicates be used because of the benefit to performance and event collection they can provide.</p>
<p>After giving the session a name, it is required to click &#8220;Events&#8221; highlighted in that orange-ish color in the previous image. This will bring up the next screen:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui.png"><img loading="lazy" class="alignnone wp-image-3023 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui-1024x722.png" alt="events_gui" width="560" height="395" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui-1024x722.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/events_gui.png 1832w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This screen will present you with many options / events that can be used in the session. In this example I have chosen the auto_stats event. By double-clicking the event or single-clicking then clicking the arrows between panes, the event will be selected and populate the right hand pane. Though hard to tell from this image, after the event is selected, the OK button becomes enabled and the session creation can be concluded here. I recommend not clicking that OK button &#8211; ever.</p>
<p>At this point, find the &#8220;Configure&#8221; button in the top right of the screen. This will bring us to the additional components that have been hidden from view to this point.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui.png"><img loading="lazy" class="alignnone wp-image-3024 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui-1024x718.png" alt="actions_gui" width="560" height="393" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui-1024x718.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui-300x210.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/actions_gui.png 1831w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>On the new screen, we can see the Actions and Predicates &#8211; color coded for ease of tying these components together as was done previously. A note on the Actions tab is that they are called &#8220;Global Fields&#8221; here with &#8220;Actions&#8221; in parenthesis. These actions can be viewed as &#8220;fields&#8221; that can be applied globally to many events.</p>
<p>After perusing the list of Actions, next up is Predicates/Filters. Clicking that tab will produce a screen like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui.png"><img loading="lazy" class="alignnone wp-image-3025 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui-1024x720.png" alt="predicates_gui" width="560" height="394" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui-1024x720.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/predicates_gui.png 1842w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Here I can select from any of the fields attached to the event payload or the Actions seen on the previous screen. This gives me the chance to configure multiple filters for this event to meet my specific requirements.</p>
<p>Next up is the Event Fields tab. This is the event payload.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/payload.png"><img loading="lazy" class="alignnone wp-image-3026 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/payload-1024x720.png" alt="payload" width="560" height="394" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/payload-1024x720.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/payload-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/payload-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/payload.png 1831w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this image I have circled an interesting item in the payload. This item has a checkbox. This means the item is one of those boolean data types that is &#8220;customizable&#8221;. When I select this item, it performs a &#8220;SET&#8221; operation within the creation of the Event Session. I will speak more to that in a moment.</p>
<p>Let&#8217;s now turn our attention to the next screen &#8211; Data Storage.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui.png"><img loading="lazy" class="alignnone wp-image-3027 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui-1024x720.png" alt="targets_gui" width="560" height="394" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui-1024x720.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/targets_gui.png 1833w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>When I open this screen, I will have multiple options in the type menu. For this example, I have only selected the event_file target. Once selected, there will be target specific options that populate the bottom section of the screen. In this case, I need to give the target file a name. I can supply a path or just a name. If I supply just the name, then the target will be created in the default &#8220;log&#8221; directory for the instance. If no target is specified, then a default target will be used. This is the event_stream target aka &#8220;Asynchronous live stream target.&#8221; I recommend specifying a target so the data can be stored and evaluated at a later time.</p>
<p>And now I will conclude with the Advanced options. While these are optional settings with defaults in place for them, I recommend at least taking a look to understand what options are available.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui.png"><img loading="lazy" class="alignnone wp-image-3028 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui-1024x721.png" alt="configs_gui" width="560" height="394" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui-1024x721.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui-300x211.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui-50x35.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/configs_gui.png 1832w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I won&#8217;t explain these options just yet. This is just for reference and introductory purposes. After looking at this screen, click &#8220;Script&#8221; and then Cancel. As I mentioned previously, I prefer to use scripts instead of the GUI. If the GUI is necessary, then script the session and evaluate the script. This is the &#8220;minor&#8221; additional step mentioned earlier.</p>
<p>Now looking at a sample script generated from the GUI:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode.png"><img loading="lazy" class="alignnone wp-image-3029 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode-1024x987.png" alt="script_session_colorcode" width="560" height="540" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode-1024x987.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode-300x289.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode-50x48.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/script_session_colorcode.png 1306w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this script, I added an additional target, and multiple Actions over what was shown in the images for this demo. Apart from that, the rest remains the same. I color coded each segment of the script to not only map to the components of an Extended Event Session, but also to the color coded screens in the examples. In addition, I added notes about some of the &#8220;SET&#8221; operations and on which screens those can be found.</p>
<p>I have just shown how to configure a single event within an Event Session. It is important to mention that the configuration screen (with actions and predicates) needs to be done separately for each of the events within the session. This is reinforced by the script where it shows the Predicate and Actions are directly attached to the Event. This makes using the GUI a bit repetitive and slow if deploying several Events within a Session.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3018" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/25/the-extended-event-gui/">The Extended Event GUI</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/25/the-extended-event-gui/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Assembling a Session</title>
		<link>https://jasonbrimhall.info/2015/09/24/assembling-a-session/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=assembling-a-session</link>
					<comments>https://jasonbrimhall.info/2015/09/24/assembling-a-session/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 24 Sep 2015 12:19:39 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2991</guid>

					<description><![CDATA[<p>With the core concepts in place as a good foundation to Extended Events, we start pushing these things together to help with assembling a session in Extended Events.</p>
The post <a href="https://jasonbrimhall.info/2015/09/24/assembling-a-session/">Assembling a Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/emptysession_puzzle.png"><img loading="lazy" class="wp-image-2992 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/emptysession_puzzle.png" alt="emptysession_puzzle" width="170" height="119" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/emptysession_puzzle.png 273w, https://jasonbrimhall.info/wp-content/uploads/2015/09/emptysession_puzzle-50x35.png 50w" sizes="(max-width: 170px) 85vw, 170px" /></a>Up to this point, I have taken a lot of time to discuss the various components of Extended Events. There is good reason for that. The components I have discussed are essential pieces of Extended Events and are critical to building useful sessions.</p>
<p>Previously, I only touched lightly on the topic of the concept of Event Sessions. In talking about the Sessions, I introduced means to see which sessions have been <a href="http://bit.ly/1XfzO27">deployed</a>, and which sessions are in a <a href="http://bit.ly/1Uu4QyY">running </a>state on the instance. But I have yet to explore the details of what a session is. It is now time to start diving into the details of what constructs a session.</p>
<h3>Assembling a Session</h3>
<table border="0">
<tbody>
<tr>
<td style="vertical-align: middle;"><img loading="lazy" class="wp-image-2994 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/event_puzzle-300x180.png" alt="event_puzzle" width="161" height="130" />The first critical component of a session is the Event. I have covered the topic of what an Event is (<a href="http://bit.ly/1NjPjBk">here</a>), as well as a deeper explanation into the payload of an Event (<a href="http://bit.ly/1K1F2Yg">here</a>). In short, the Event is an occurrence of something that interests you &#8211; the observer.</td>
</tr>
<tr>
<td style="vertical-align: middle;">
<p><img loading="lazy" class="wp-image-2995 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/predicate_puzzle-300x232.png" alt="predicate_puzzle" width="168" height="130" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/predicate_puzzle-300x232.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/predicate_puzzle-50x39.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/predicate_puzzle.png 304w" sizes="(max-width: 168px) 85vw, 168px" /><span style="font-family: inherit; font-size: inherit; line-height: 1.5;">The next component is the filtering mechanism known as predicates. I have covered this topic with the introductions into </span><a style="font-family: inherit; font-size: inherit; line-height: 1.5;" href="http://bit.ly/1KvDy5I">source predicates</a><span style="font-family: inherit; font-size: inherit; line-height: 1.5;">, </span><a style="font-family: inherit; font-size: inherit; line-height: 1.5;" href="http://bit.ly/1YyQp1n">comparison predicates</a><span style="font-family: inherit; font-size: inherit; line-height: 1.5;">, and predicate order.</span></p>
<p>Recall that after an event is collected, the next phase in the process is to evaluate the predicate(s). The predicate is a fairly significant component and should be duly considered when creating a session.</td>
</tr>
<tr>
<td>
<p><img loading="lazy" class="wp-image-2996 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/action_puzzle-300x180.png" alt="action_puzzle" width="177" height="106" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/action_puzzle-300x180.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/action_puzzle-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/action_puzzle.png 346w" sizes="(max-width: 177px) 85vw, 177px" />The third component that I have previously introduced is that of the &#8220;Action&#8221;. An Action is an extra piece of data in the stream that is attached to the event payload.</p>
<p>The application of Action data to the session payload is the third step in the process. You can read more about Actions from <a href="http://bit.ly/1F0b2x1">here</a>.</td>
</tr>
<tr>
<td>
<p><img loading="lazy" class="wp-image-2993 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/target_puzzle-300x231.png" alt="target_puzzle" width="170" height="131" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/target_puzzle-300x231.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target_puzzle-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target_puzzle.png 303w" sizes="(max-width: 170px) 85vw, 170px" />The last critical component that I have discussed to this point is the Target.</p>
<p>A Target is the consumer of the event session data. It is crucial to direct the payload of the session to a consumer to be reviewed at a future time.</p>
<p>I introduced the need for the consumer when I introduced Targets &#8211; <a href="http://bit.ly/1JbFDCW">here</a>.</td>
</tr>
</tbody>
</table>
<div></div>
<p>&nbsp;</p>
<p><img loading="lazy" class="size-medium wp-image-2998 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/3dmen_puzzle-300x237.png" alt="3dmen_puzzle" width="300" height="237" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/3dmen_puzzle-300x237.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/3dmen_puzzle-50x40.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/3dmen_puzzle.png 742w" sizes="(max-width: 300px) 85vw, 300px" />When we start to push these components together, one has the makings of an Event Session that can be used to trace and trap the events that are of interest to whatever issue may be important at the moment. Let&#8217;s see how this looks in the code.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION buildmysession ON SERVER
ADD EVENT sqlserver.sql_statement_completed ( 
	ACTION ( sqlserver.sql_text )
	WHERE (sqlserver.database_name = 'AdventureWorks2014'
			--overloaded form of package0.equal_i_sql_unicode_string(database_name,'AdventureWorks2014')
			--pred_compare or comparator predicate
			AND package0.counter = 2 --pred_source or state data
			) 
	)
ADD TARGET package0.ring_buffer, --memory target
ADD TARGET package0.event_file (  SET filename = N'C:\Database\XE\pred_order6.xel' ) --file target
WITH ( MAX_DISPATCH_LATENCY = 1 SECONDS );</pre><p>In this session, I have determined that I want to trap the sql_text action on the second occurrence of a sql_statement_completed event in the AdventureWorks2014 database. When, this event occurs, I want the data to be consumed by both a memory target and by a file target. Notice that I have used multiple predicates and multiple targets.</p>
<p>Alternatively, let&#8217;s look at the script this way:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded.png"><img loading="lazy" class="alignnone wp-image-3010 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded-1024x453.png" alt="session_code_puzzlecoded" width="560" height="248" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded-1024x453.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded-300x133.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded-50x22.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_code_puzzlecoded.png 1690w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this previous image, I have taken the code sample previously listed and color coded each <img loading="lazy" class="size-medium wp-image-2997 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/session_puzzle-300x182.png" alt="session_puzzle" width="300" height="182" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/session_puzzle-300x182.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_puzzle-50x30.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/session_puzzle.png 650w" sizes="(max-width: 300px) 85vw, 300px" />of the critical components of an Event Session. Besides the color outlines, one could easily remark that the code looks pretty similar to other methods to create objects within SQL Server. When I create an Event Session, I use the standard DML syntax used when creating, altering, or dropping other objects like tables and procedures.</p>
<p>In my example, I have color coded each of the code segments to match the appropriate puzzle piece. For instance, the predicate is green. Notice that I used two types of predicates and even left a note about how I used the overloaded method for the pred_compare predicate type instead of the comparator object. Also of note here is that should I decide to send the session payload to multiple targets, that is well within reason as demonstrated here.</p>
<p>With the core concepts in place, building an Extended Event Session does become a fair bit easier.</p>
<p>To get a recap on this series, continue <a href="http://bit.ly/XE60Days">reading here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2991" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/24/assembling-a-session/">Assembling a Session</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/24/assembling-a-session/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Freecon &#8211; Oct 27 in Seattle</title>
		<link>https://jasonbrimhall.info/2015/09/23/freecon-oct-27-in-seattle/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=freecon-oct-27-in-seattle</link>
					<comments>https://jasonbrimhall.info/2015/09/23/freecon-oct-27-in-seattle/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 23 Sep 2015 20:41:52 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=3013</guid>

					<description><![CDATA[<p>It is well known that there is a wealth of information within Extended Events. One can tap plenty of information about performance issues, errors, or general interest type stuff by setting up an XEvent Session and trapping some (hopefully) useful information.</p>
The post <a href="https://jasonbrimhall.info/2015/09/23/freecon-oct-27-in-seattle/">Freecon – Oct 27 in Seattle</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Just over a week ago I announced that SQL Solutions Group was getting ready to host a day of training, FREECON if you will, in Seattle as a prelude to the PASS Summit of 2015. You can <a href="http://bit.ly/1Kl8m99">read all about that here</a>, with <a href="http://bit.ly/SSGSummit15">registration being here</a>.</p>
<p>While I really do hope to see the room fill with people looking to get some fantastic training, I also want to note that this training is not a part of the Summit. Though I hope it is viewed as an effort to enhance the learning made available during the week of Summit and to give the attendees more options.</p>
<p>An option is only really any good if some sort of detail can be attained about the option. While, I did publicize that the event was going to happen with a brief introduction into the the topics to be covered, one may be left wondering what really will be covered during the day.</p>
<p>Today, I hope to help make the SSG Freecon option a better option  by including a little detail into what it is that I will be presenting during my session on Extended Events.</p>
<h3>Extended Events</h3>
<p>This should come as a huge surprise given the <a href="http://bit.ly/XE60Days">60 Days of XEvents</a> series that I am currently publishing. While I am publishing a lot of information about Extended Events in this series, this Freecon session will cover the methodology that I, as a consultant, would use to troubleshoot various issues when a client seeks my help.</p>
<p>It is well known that there is a wealth of information within Extended Events. One can tap plenty of information about performance issues, errors, or general interest type stuff by setting up an XEvent Session and trapping some (hopefully) useful information.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap.jpg"><img loading="lazy" class="size-medium wp-image-3014 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap-300x206.jpg" alt="roadmap" width="300" height="206" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap-300x206.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap-1024x703.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap-50x34.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/roadmap.jpg 1374w" sizes="(max-width: 300px) 85vw, 300px" /></a>During this session at the FreeCon, I want to help show how I would use Extended Events as a consultant to help find the pertinent information that will bring to light the problems the client is having.</p>
<p>How can I use Extended Events as a consultant to perform a health check on your server? That information will be covered throughout this session.</p>
<p>How can I determine where precisely the backup failed (and when) and be able to procure more information to determine if it was caused by some other event on the network? This is the type of information included in the methodology that I plan to share.</p>
<p>Think of this session as a condensed road-map to XE Success.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=3013" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/23/freecon-oct-27-in-seattle/">Freecon – Oct 27 in Seattle</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/23/freecon-oct-27-in-seattle/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Comparison Predicates and Event Data</title>
		<link>https://jasonbrimhall.info/2015/09/22/comparison-predicates-and-event-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=comparison-predicates-and-event-data</link>
					<comments>https://jasonbrimhall.info/2015/09/22/comparison-predicates-and-event-data/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 22 Sep 2015 12:30:16 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2963</guid>

					<description><![CDATA[<p>Predicates are a significant component within the Extended Events Engine. This article discusses one of the pieces of the puzzle of predicates - comparison operators - also known as pred_compare.</p>
The post <a href="https://jasonbrimhall.info/2015/09/22/comparison-predicates-and-event-data/">Comparison Predicates and Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the previous installment, I began covering the topic of predicates. In that article I demonstrated that there are multiple types of predicates. There are two objects that fall into the predicate category and then there are data comparison predicates (those that are not objects).</p>
<p>The two objects are pred_compare and pred_source. With pred_source having been covered in that first part, I will now cover the pred_compare object as well as the standard predicate that is not an object.</p>
<p>In that previous installment, I associated predicate to a filter. I also mentioned that a predicate in Extended Events is a means to short circuit event evaluation. I want to underscore the importance of that feature.</p>
<p>If you imagine a complex conveyor belt system as if it were the Extended Event engine, you might see something like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor.png"><img loading="lazy" class="size-medium wp-image-2967 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor-300x172.png" alt="pred_conveyor" width="300" height="172" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor-300x172.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor-50x29.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor.png 550w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>Packages roll along the conveyor system and will reach various check-points. At each check-point, a bar code is scanned and the package is moved merrily along its way.</p>
<p>There can be many paths for a package as it rolls along from start to finish within a network of conveyor belts.</p>
<p>Now, focus on the scanner as I have done with the next image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor.png"><img loading="lazy" class="size-medium wp-image-2966 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor_zoom-300x172.png" alt="pred_conveyor_zoom" width="300" height="172" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor_zoom-300x172.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor_zoom-50x29.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_conveyor_zoom.png 550w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>This scanner is the filtering mechanism. If the bar code of the package meets the requirements to be rerouted along a different belt, this scanner will be able to make that happen. The package will be scanned, meet the redirect requirements, and then the scanner flips a mechanical switch to redirect the package.</p>
<p>This is not too different from Extended Events. When the payload of the event (package) meets the predicate (scanner) requirements, the payload is sent down a path to a pre-defined target. If it doesn&#8217;t meet those requirements, the event just passes by as if nothing happened (other than being scanned).</p>
<p>Now consider the predecessor (e.g. the method employed by Profiler/SQL Trace). The filter mechanism routed everything to the same spot and then attempted to apply the filter after the collection was made. The new filter process, employed by Extended Events, is many times more efficient and less impacting than the method employed by Profiler and SQL Trace.</p>
<h3>Compare</h3>
<p>Much like the object name says, this type of predicate represents the different types of comparison operators that can be performed within a predicate. The pred_compare type can be written in multiple ways. The easier approach for most would be to continue writing a predicate in the same fashion as for a standard TSQL query. In other words, these predicate objects are overloaded with the standard operators that could be used within a typical TSQL WHERE clause.</p>
<p>Let&#8217;s look at how to view some of these predicates:</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Comparison Predicates
SELECT p.name AS package_name
		, o.name AS predcomp_name
		, o.description
	FROM sys.dm_xe_objects AS o
		JOIN sys.dm_xe_packages AS p
			ON o.package_guid = p.guid
	WHERE ( p.capabilities IS NULL
			OR p.capabilities &amp; 1 = 0
			)
		AND ( o.capabilities IS NULL
				OR o.capabilities &amp; 1 = 0
			)
		AND o.object_type = 'pred_compare';</pre><p>Exploring through this list of predicates, one will see 77 different compare predicates. Here is an abridged example of that list.</p>
<table width="230">
<tbody>
<tr>
<td width="230">less_than_i_sql_ansi_string</td>
</tr>
<tr>
<td>less_than_equal_i_sql_ansi_string</td>
</tr>
<tr>
<td>greater_than_i_sql_ansi_string</td>
</tr>
<tr>
<td>greater_than_equal_i_sql_ansi_string</td>
</tr>
<tr>
<td>like_i_sql_unicode_string</td>
</tr>
<tr>
<td>like_i_sql_ansi_string</td>
</tr>
<tr>
<td>equal_uint64</td>
</tr>
</tbody>
</table>
<p>Reading through the list, one could quickly figure out that the less_than* and greater_than* comparators would map to the &lt; and &gt; operators respectively. Despite the easy mapping to the overloaded counterparts of the operators, the way to use these is slightly different than with good old TSQL syntax. One needs to think more programmatically to utilize these types of objects.</p>
<p>Suppose I wanted to use one of these objects when trying to find all of the stored procedures taking more than 500 milliseconds. I would need to write my predicate like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">ADD EVENT sp_statement_completed
(WHERE package0.greater_than_max_int64(duration, 500000)</pre><p>The alternative (and more common approach) would be:</p><pre class="urvanov-syntax-highlighter-plain-tag">ADD EVENT sp_statement_completed
(WHERE duration &gt; 500000)</pre><p>Now suppose that I go ahead and use the easy syntax (TSQL syntax) to create a predicate on the sp_statement_completed event and deployed that session to a server. The event engine will take that overloaded syntax and do a translation for me. The syntax that it will produce would be of the following nature:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate.png"><img loading="lazy" class="alignnone wp-image-2971 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate-1024x289.png" alt="pred_translate" width="560" height="158" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate-1024x289.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate-300x85.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate-50x14.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/pred_translate.png 1536w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In this particular example, I chose to have two predicates. The two are a bit different, and the deeper explanation will be discussed in the future. The simple explanation for the difference is that one is based on an Action and the other is based on an event. Looking at the predicate within the green box, one will see that the sp_statement_completed event has a predicate on it that uses the greater_than_uint64. Then the field that is being compared is added within this XML. The last piece of this leaf node is the value. I decided to go for 25 seconds of run-time instead of 500 ms. (Note the values here are in microseconds and not milliseconds.)</p>
<p>All of that is generated from the predicate I wrote as &#8220;duration &gt; 25000000&#8221; when creating the event. Whether using the more familiar TSQL syntax of the XE syntax to build your compare predicates, it will be translated and stored in an XML format using the actual pred_compare objects. Keep this in mind when building predicates.</p>
<p>Earlier, I stated there are two types of predicates to discuss in this segment. The examples I just showed are an illustration of those two types of predicates. Call it standard TSQL syntax vs. the XE syntax for the comparison operators within a predicate. That&#8217;s really what it boils down to.</p>
<h3>Considerations</h3>
<p>While on the topic of predicates within Extended Events, there is a limitation set on the size of the predicate that should be brought into consideration. This limitation is 3000 characters. Because of this limitation, it is highly recommended to use the standard TSQL syntax where possible (granted a 3000 character predicate is rather large). The pred_compare objects are a bit lengthy in name when compared to the symbol equivalents and could consume predicate space rather quickly.</p>
<p>Predicates is a pretty important topic. And due to the importance of the topic, I will be discussing this topic again in the future.</p>
<p>To recap on the entire series, please see the &#8220;<a href="http://bit.ly/XE60Days">Table of Contents</a>&#8220;.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2963" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/22/comparison-predicates-and-event-data/">Comparison Predicates and Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/22/comparison-predicates-and-event-data/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Storing Event Data</title>
		<link>https://jasonbrimhall.info/2015/09/16/storing-event-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=storing-event-data</link>
					<comments>https://jasonbrimhall.info/2015/09/16/storing-event-data/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 16 Sep 2015 14:20:03 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2921</guid>

					<description><![CDATA[<p>Among the several core concepts of Extended Events is the concept of storing event payloads / data.</p>
The post <a href="https://jasonbrimhall.info/2015/09/16/storing-event-data/">Storing Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Among the several core concepts of Extended Events is the concept of storing event payloads / data. When an event fires, it would not be far-fetched to want to be able to review that data at some time after the fact. How often are you sitting there watching the system just waiting for an error or event to occur? Hopefully, you aren&#8217;t just staring at the monitor waiting for it to happen.</p>
<p>A thought comes to mind for this kind of monitoring &#8211; &#8220;a watched kettle never boils.&#8221;<img loading="lazy" class="wp-image-2923 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/target-300x300.png" alt="target" width="232" height="232" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/target-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/target-50x50.png 50w" sizes="(max-width: 232px) 85vw, 232px" /> And while that is not entirely true, the intent is close. It seems that while you are watching for an event to occur, it just doesn&#8217;t happen. Or at least, it waits to happen at the precise moment you blink and consequently you miss it.</p>
<p>Being able to store the session data is essential to a good monitoring solution. Within Extended Events, this storage comes via the concept of targets. Recall (<a href="http://bit.ly/1FvxOHW">from the Objects Article</a>) that a target is the destination of the payload and thus is a consumer of the event payloads.</p>
<h3>Targets</h3>
<p>Microsoft has provided several consumers for us to use when creating Extended Event Sessions. In addition to the targets readily available to use when creating a session, there are a few that are &#8220;hidden&#8221; targets and are reserved for internal use. Private or public, we will take a quick peek at targets as a whole, but we will spend most of our time looking at what is available to us as a consumer.</p>
<p>So what kind of event consumers / targets can one implement to direct output from a Session? Let&#8217;s see:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT xo.name AS TargetName
		,xo.description AS TargetDescription
		,xo.capabilities_desc 
	FROM sys.dm_xe_objects xo
	WHERE xo.object_type = 'target'
		AND (xo.capabilities &amp; 1 = 0
			OR xo.capabilities IS NULL);</pre><p>This will produce the following results (well, if you are using SQL Server 2008 or R2, your results will vary):</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets.png"><img loading="lazy" class="alignnone wp-image-2927 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets-1024x210.png" alt="xe_public_targets" width="560" height="115" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets-1024x210.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets-300x61.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets-50x10.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_public_targets.png 1547w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This provides an array of options with some nice opportunities to do different things with EXtended Events. One can either direct the event payload to memory, to a file, to a counter object, or try to match the event with another event. These are some good options. However, if you are using SQL Server 2008, your results would have been different. Let&#8217;s compare and contrast real quick.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare.png"><img loading="lazy" class="alignnone wp-image-2928 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare-1024x259.png" alt="xe_target_compare" width="560" height="142" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare-1024x259.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare-300x76.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare-50x13.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xe_target_compare.png 1611w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>While, the same general targets are available, they are implemented differently across the versions of SQL Server. This is important to remember when trying to recreate an Extended Event Session on SQL Server 2008R2 that was designed on SQL Server 2012, and was set to output to an event_file target. Trying to recreate that session can result in a loss of hair due to the difference in target names between versions.</p>
<p>I mentioned earlier that there are some targets that are &#8220;private&#8221; and basically not configurable for an event session. What are these targets? That part is easy enough to figure out. Let&#8217;s adapt the previous script just a bit.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT xo.name AS TargetName
		,xo.description AS TargetDescription
		,xo.capabilities_desc 
	FROM sys.dm_xe_objects xo
	WHERE xo.object_type = 'target'
		AND (xo.capabilities &amp; 1 = 1);</pre><p>And here is the list of those private targets:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2019/07/xe_private_targets.png"><img loading="lazy" class="alignnone wp-image-2929 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2019/07/xe_private_targets.png" alt="xe_private_targets" width="560" height="150" /></a></p>
<p>&nbsp;</p>
<p>For those that are Profiler junkies and love to watch events stream in &#8220;live&#8221;, Extended Events has just the target to do that. The event_stream &#8220;private&#8221; target, attached to the event session by default and not configurable, will allow one to watch events as the trigger. By now, you have likely also noted that there are a bunch of targets listed with the term &#8220;audit&#8221; in the name. I will dive into this more in the future, and at that time it will become more apparent why it is not directly configurable through the creation of a user defined Extended Event session.</p>
<p>Stay tuned for future articles where I will go into the use of these various targets and how to attach them to a Session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2921" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/16/storing-event-data/">Storing Event Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/16/storing-event-data/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events and Fixed Schemas</title>
		<link>https://jasonbrimhall.info/2015/09/14/extended-events-and-fixed-schemas/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-events-and-fixed-schemas</link>
					<comments>https://jasonbrimhall.info/2015/09/14/extended-events-and-fixed-schemas/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 14 Sep 2015 13:22:17 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2906</guid>

					<description><![CDATA[<p>Working with databases, XML, and many software applications, it is not uncommon to deal with fixed schemas. In the database world, it is fairly fundamental to have some sort of schema. The schema represents the typing of the bit-strings that are being stored or presented. One might even call it the template.</p>
The post <a href="https://jasonbrimhall.info/2015/09/14/extended-events-and-fixed-schemas/">Extended Events and Fixed Schemas</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Working with databases, XML, and many software applications, it is not uncommon to deal with fixed schemas. In the database world, it is fairly fundamental to have some sort of schema. The schema represents the typing of the bit-strings that are being stored or presented. One might even call it the template.</p>
<p>With the fundamental nature of schemas within a database, it should come as no surprise that Extended Events also has a means to expose the schema of many of the components that can be found within the XE engine. To access the stored schemas, one would use the DMV, sys.dm_xe_object_columns.</p>
<p>This DMV exposes the fixed schema that is available for the object/component for the different data groups. If you recall from the previous article, there are three data classifications (readonly, customizable, and data) that could be present for a particular object.</p>
<p>Not all objects have a fixed-schema that will be exposed through this DMV. In fact, the types of objects that will be exposed are the target, map and event object types. When considering the different components, this stands to reason since many objects infer a single point of data and not necessarily a schema (we will be discussing those other components in the near future).</p>
<h3>Schemas</h3>
<p>The exploration of the schemas tied to the different objects is pretty straight forward. Let&#8217;s begin with the most basic version. I will not focus much on what is exposed in the DMV since this is basically the schema and that concept should be fairly straight forward to most DBAs. For instance, a schema will contain a basic model of the the columns and data types and relationships. The schemas in XEvents is very similar.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT oc.object_name AS ObjectName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
	FROM sys.dm_xe_object_columns oc
	WHERE oc.column_type &lt;&gt; 'readonly'
	ORDER BY ObjectName,column_name;
GO</pre><p>This being a basic query to look at the schemas of the components available in extended events, it should be plain to see that nothing is being excluded from the results. This means we could be seeing the schema for both events and targets. Recall that there are only three types of objects which have stored schemas.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT xo.object_type AS XEComponentWithSchma
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_objects xo
			ON xo.name = oc.object_name
			AND xo.package_guid = oc.object_package_guid;
GO</pre><p>&nbsp;</p>
<p>Note here that I have referenced back to the sys.dm_xe_objects DMV, This is done to ensure I can get the object types. That piece of info needs to come from the xe_objects DMV. This DMV will be used throughout the remaining examples too.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/xecomponents_wschema.png"><img loading="lazy" class="alignnone size-medium wp-image-2910" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/xecomponents_wschema-300x138.png" alt="xecomponents_wschema" width="300" height="138" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/xecomponents_wschema-300x138.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xecomponents_wschema-50x23.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/xecomponents_wschema.png 416w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>Let&#8217;s complicate things just a little bit. If I try a little more complex query and want to eliminate the target and event schemas as shown in the following, I will get an interesting result.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT oc.object_name AS ObjectName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,xo.object_type
		--,xo.description AS ObjDescription
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_objects xo
			ON xo.name = oc.object_name
			AND xo.package_guid = oc.object_package_guid
	WHERE oc.column_type &lt;&gt; 'readonly'
		AND oc.object_name NOT IN (
			SELECT name
				FROM sys.dm_xe_objects xo
				WHERE xo.object_type = 'event'
					OR xo.object_type = 'target')
	ORDER BY ObjectName,column_name
GO</pre><p>This will return no results. Now, there should be something returned since I should see some map schemas. Yet, this query returns nothing. As it happens, there are maps that share the same name as some of the events.</p>
<p>I can see that little piece of fun by altering my query to the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT oc.object_name AS ObjectName
		,xo.object_type
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_objects xo
			ON xo.name = oc.object_name
			AND xo.package_guid = oc.object_package_guid
	WHERE oc.column_type &lt;&gt; 'readonly'
		AND xo.object_type = 'map'
		AND oc.object_name IN (
			SELECT name
				FROM sys.dm_xe_objects xo
				WHERE xo.object_type = 'event')
	ORDER BY ObjectName
GO</pre><p>And the results:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/dupxe_maps_names.png"><img loading="lazy" class="alignnone wp-image-2911" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/dupxe_maps_names-300x75.png" alt="dupxe_maps_names" width="500" height="126" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/dupxe_maps_names-300x75.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/dupxe_maps_names-50x13.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/dupxe_maps_names.png 701w" sizes="(max-width: 500px) 85vw, 500px" /></a></p>
<p>This is good information to know if one of these events that shared a name with a map was needed for a specific monitoring solution being explored. It is easy enough to code around, but it can be just a bit of a nuisance if the name duplication remained unknown.</p>
<p>Taking this information into account, I can now query the schemas more precisely and get a good feel for what kind of schema is going to be available for the component.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @objtype VARCHAR(128) = 'map' --'map','target','event', null for all
	,@datatype VARCHAR(32) = NULL --'data','readonly','customizable'
	,@excludetype VARCHAR(32) = 'readonly' --'data','readonly','customizable', 'ALL' if no exclusions

SELECT oc.object_name AS ObjectName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,xo.object_type
	FROM sys.dm_xe_object_columns oc
		INNER JOIN sys.dm_xe_objects xo
			ON xo.name = oc.object_name
			AND xo.package_guid = oc.object_package_guid
	WHERE oc.column_type = ISNULL(@datatype,oc.column_type) 
		AND xo.object_type = ISNULL(@objtype,xo.object_type)
		AND oc.column_type &lt;&gt; @excludetype
	ORDER BY ObjectName,column_name
GO</pre><p>With this type of query, I can now query the schemas in a better way. I can look at all of the data groups, or a specific data group. I can also look for a specific object type / component. This type of query will become an essential building block as we get into trying to figure out which object will best fit the needs of the problem being investigated or the trace desired to be created.</p>
<p>Stay tuned for more articles as we prepare to discuss actions, targets and data types.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2906" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/14/extended-events-and-fixed-schemas/">Extended Events and Fixed Schemas</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/14/extended-events-and-fixed-schemas/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events &#8211; Event Anatomy</title>
		<link>https://jasonbrimhall.info/2015/09/11/extended-events-event-anatomy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-events-event-anatomy</link>
					<comments>https://jasonbrimhall.info/2015/09/11/extended-events-event-anatomy/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 11 Sep 2015 11:47:06 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2889</guid>

					<description><![CDATA[<p>As a follow-up to the introduction to what an Event is, it makes sense to discuss the components of an event. What makes up an event? What is the payload of the event? What is a payload?</p>
The post <a href="https://jasonbrimhall.info/2015/09/11/extended-events-event-anatomy/">Extended Events – Event Anatomy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>So far in these brief discussions about Extended Events, I have covered several core concepts including a basic introduction into what an Event is within Extended Events. For a recap on those articles, you can <a href="http://bit.ly/1KCP5WY">read this</a>.</p>
<p>As a follow-up to the introduction to what an Event is, it makes sense to discuss the components of an event. What makes up an event? What is the payload of the event? What is a payload?</p>
<h3><img loading="lazy" class="size-medium wp-image-2894 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/b2_payload-300x143.jpg" alt="b2_payload" width="300" height="143" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/b2_payload-300x143.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/b2_payload-50x24.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/b2_payload.jpg 325w" sizes="(max-width: 300px) 85vw, 300px" />Payload</h3>
<p>The payload, is the stuff that is to be delivered somewhere. The payload can be rather extensive and broad like one may see in the armament configuration of a B-2 (as we see in the image to the right).</p>
<p>Or the payload can be more streamline and compact as one might see in a rocket used to deliver a satellite.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/satellitedelivery.png"><img loading="lazy" class="wp-image-2897 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/satellitedelivery-300x269.png" alt="satellitedelivery" width="240" height="215" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/satellitedelivery-300x269.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/satellitedelivery-50x45.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/satellitedelivery.png 341w" sizes="(max-width: 240px) 85vw, 240px" /></a></p>
<p>As seen in this image depicting a typical delivery mechanism for satellites to be delivered beyond the Earth&#8217;s atmosphere, the payload can be very specific and &#8220;targeted&#8221;.</p>
<p>With these payloads, we see that some common payloads range from one point of interest to hundreds of points of interest.</p>
<p>When working with computers (and not a physical delivery mechanism), a payload can work in much the same way. The item to be delivered can be focused and small in quantity or it can be broad and large in quantity.</p>
<p>A common use of payload in the computer world is with a virus or malware. Virii have a payload that is delivered to the new host to attempt to infect it. This is not too far different from the payload of Extended Events &#8211; excepting that XEvent payloads do not infect new hosts.</p>
<p>The payload of an XE Event is the data that was captured at the time the event (point of interest) was fired. The data of an Event can be broken into three classes or groups. More specifically, the columns that define the data can be broken into two different types with two divisions in the second type.</p>
<p>The first is the readonly data of the event. These columns are much like the metadata of the event containing data such as the channel and keyword. This data is used for ETW integration.</p>
<p>The second type of columns is the data that is captured when an event fires in the engine. Within this group, there are customizable data points as well as state data points. The data that is customizable is to the point of enabling the capture of that data point or disabling the capture of that specific data point.</p>
<p>These different types do not apply to all events. The customizable data may be present in some events. Don&#8217;t be surprised if you come across an event that does not contain a customizable data point.</p>
<p>We can look at some of this via the following example. Note that while this example touches the sys.dm_xe_object_columns DMV, I will not go into great detail about this just yet.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = 'sp_statement_completed'
	,@ReadFlag VARCHAR(64) = 'ALL' --readonly' --ALL if all columntypes are desired
 
SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,ca.map_value AS SearchKeyword
	FROM sys.dm_xe_object_columns oc
		CROSS APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = oc.object_name) ca
	WHERE oc.object_name = @EventName
		AND oc.column_type &lt;&gt; @ReadFlag
	;</pre><p>This will return the following results in SQL Server 2014:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/event_anatomy.png"><img loading="lazy" class="alignnone wp-image-2899 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/event_anatomy-1024x222.png" alt="event_anatomy" width="560" height="121" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/event_anatomy-1024x222.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/event_anatomy-300x65.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/event_anatomy-50x11.png 50w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In the attached image, I have color coded each of the different types of data. In the results, it is also shown that the customizable data points are boolean in nature. They are either enabled or disabled for the capture of that data point. And lastly, we can see the &#8220;metadata&#8221; or &#8220;event header&#8221; type of information in the readonly type of data. Of these data points within the payload, the most interesting will consistently be found in the &#8220;customizable&#8221; and &#8220;data&#8221; classifications.</p>
<p>The information presented on this payload will prove more helpful as we continue on this series. Stay tuned for the next article when we start taking a look at the Columns in greater detail.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2889" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/11/extended-events-event-anatomy/">Extended Events – Event Anatomy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/11/extended-events-event-anatomy/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events Categories</title>
		<link>https://jasonbrimhall.info/2015/09/09/extended-events-categories/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-events-categories</link>
					<comments>https://jasonbrimhall.info/2015/09/09/extended-events-categories/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 09 Sep 2015 11:42:50 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2877</guid>

					<description><![CDATA[<p>Packages have a couple of descriptors (or classifiers) that can be useful to help figure out what events contained within that package might be related to other events.</p>
The post <a href="https://jasonbrimhall.info/2015/09/09/extended-events-categories/">Extended Events Categories</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I recently delved into a brief explanation of Packages as they correlate to Extended Events. In that article, I left a couple of things un-said about packages &#8211; leaving them for this article.</p>
<p>Packages have a couple of descriptors (or classifiers) that can be useful to help figure out what events contained within that package might be related to other events. This would be particularly helpful in putting together a session to troubleshoot a specific issues.</p>
<p>The classifiers within packages are called keywords and channels.</p>
<h3>Channels</h3>
<p>A channel in Extended Events can be very closely defined just the same as a radio station or a TV channel. The channel indicates a stream of interest or in other words it identifies the audience of interest to the event.</p>
<table>
<tbody>
<tr>
<th width="100">Term</th>
<th>Definition</th>
</tr>
<tr>
<td>Admin</td>
<td>Events that are targeted to the administrators and support. These events indicate a problem with a solution that an administrator can act on. These events typically have a message associated with them telling the consumer what to do to resolve the problem.</td>
</tr>
<tr>
<td>Operational</td>
<td>Events that are used for analyzing and diagnosing a problem. One may use these to trigger tasks based on the occurrence. Think Administrator when considering who the consumer might be.</td>
</tr>
<tr>
<td>Analytic</td>
<td>Use these in performance investigations. These are high volume type of events. Think of anybody working to resolve performance issues as the consumers of these types of events.</td>
</tr>
<tr>
<td>Debug</td>
<td>Debug events are used solely by developers to diagnose a problem for debugging. Think CSS when dealing with these.</td>
</tr>
</tbody>
</table>
<p>Depending on the day or the issue, your interest point may be in a different Channel. Keep that in mind as we progress through event classification.</p>
<p>You can find these channels within the XEvent metadata by performing a query similar to the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT v.map_value AS Channel
	FROM sys.dm_xe_object_columns c
		INNER JOIN sys.dm_xe_map_values v
			ON c.type_name = v.name
			AND c.column_value = CAST(v.map_key AS NVARCHAR)
	WHERE c.name = 'channel';</pre><p></p>
<h3>Keywords</h3>
<p>The term &#8220;keywords&#8221; should invoke a common meaning for most people. If you perform internet searches, you should be familiar with what a keyword would be in &#8220;Google&#8221; or &#8220;Bing.&#8221;  It is a search phrase that would yield a group of results that are related to the term that describes the problem you are researching.</p>
<p>Within Extended Events, the Keyword is a fine-grained classification of the events. When used in conjunction with the Channel, it becomes more refined and as a result a better classification of the events being sought.</p>
<p>To discover these keywords, one could execute the following query:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT map_value AS Keyword
	FROM sys.dm_xe_map_values mv
	WHERE mv.name = 'keyword_map'
	ORDER BY mv.map_value;</pre><p>Within SQL Server 2014, that will yield 53 <em>unique</em> keywords. That doesn&#8217;t tell the entire story though. Notice the emphasis on <em>unique</em>. A keyword may exist in more than one package and be applicable to more than one Channel.</p>
<p>To see this a little more clearly, we could do something like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT map_value AS Keyword
		, xp.name AS Package
	FROM sys.dm_xe_map_values mv
		INNER JOIN sys.dm_xe_packages xp
			ON mv.object_package_guid = xp.guid
	WHERE mv.name = 'keyword_map'
	ORDER BY  mv.map_value,xp.name;</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_xe.png"><img loading="lazy" class="alignnone size-medium wp-image-2879" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_xe-197x300.png" alt="keyword_xe" width="197" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_xe-197x300.png 197w, https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_xe-33x50.png 33w, https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_xe.png 484w" sizes="(max-width: 197px) 85vw, 197px" /></a></p>
<p>Notice the highlighted results? We see that query_store (even in SQL Server 2014) has a few results as a keyword. There is even what appears to be a duplication within the sqlserver package for that keyword. Well, if we explore that a bit further and add the Channel, we should see more clarity.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DISTINCT ke.KeyWord AS Keyword
		, xp.name AS Package
		,ch.Channel AS Channel
	FROM sys.dm_xe_packages xp
		INNER JOIN (SELECT oc.object_package_guid, v.map_value AS Channel
							,xo.name AS EventName
						FROM sys.dm_xe_object_columns oc
							INNER JOIN sys.dm_xe_map_values v
								ON oc.type_name = v.name
								AND oc.column_value = CONVERT(NVARCHAR,v.map_key)
							INNER JOIN sys.dm_xe_objects xo
								ON oc.object_package_guid = xo.package_guid
								AND oc.object_name = xo.name
						WHERE oc.name = 'channel'
							AND xo.object_type = 'event'
					) ch
			ON ch.object_package_guid = xp.guid
		INNER JOIN (SELECT xoc.object_package_guid, mv.map_value AS KeyWord
							,xo.name AS EventName
						FROM sys.dm_xe_map_values mv
							INNER JOIN sys.dm_xe_object_columns xoc
								ON xoc.type_name = mv.name
								AND xoc.column_value = CONVERT(NVARCHAR,mv.map_key)
								AND xoc.type_package_guid = mv.object_package_guid
							INNER JOIN sys.dm_xe_objects xo
								ON xo.package_guid = xoc.object_package_guid
								AND xo.name = xoc.object_name
						WHERE mv.name = 'keyword_map'
							AND xo.object_type = 'event'
					) ke
			ON ke.object_package_guid = xp.guid
			AND ch.EventName = ke.EventName
	ORDER BY  ke.KeyWord,xp.name;</pre><p>This would reveal to us the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_channel_xe.png"><img loading="lazy" class="alignnone size-medium wp-image-2880" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_channel_xe-300x157.png" alt="keyword_channel_xe" width="300" height="157" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_channel_xe-300x157.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_channel_xe-50x26.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/keyword_channel_xe.png 667w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>Taking note of the highlighted rows again, one can see that the query_store keyword affects multiple Channels along with the multiple packages. This will be useful after we start to learn more about events. Once we do that, we can learn to correlate the events to these channels and keywords.</p>
<p>There are many useful keywords coupled with the four channels. We can see through various queries that the keywords are reused between packages and channels. These keywords and channels offer a granularity in helping to search for events and group events into common themes.</p>
<p>Other than the usefulness in searching for like events, why do we have this kind of granularity? Well, as it turns out, this was done to have Extended Events follow the same setup seen in <a href="https://support.microsoft.com/en-us/kb/2593157">Event Tracing for Windows (ETW)</a>. This also allows an integration between Extended Events in SQL Server and the tools available for ETW. Think of it as one step in an effort to bring sysadmins, developers and DBAs to a standard means of monitoring and tracing on the Windows platform. You want to be able to work efficiently with the sysadmins and developers, right?</p>
<p>Stay tuned for the next article where I will discuss events.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2877" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/09/extended-events-categories/">Extended Events Categories</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/09/extended-events-categories/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Learning Extended Events in 60 Days</title>
		<link>https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=learning-extended-events-in-60-days</link>
					<comments>https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Sep 2015 21:10:32 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2892</guid>

					<description><![CDATA[<p>Want to Learn Extended Events over the course of your lunch break for a couple of months? This is the Table of Contents for learning Extended Events over the course of 60 days.</p>
The post <a href="https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Learning Extended Events in 60 Days</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This post will serve as the landing page for a series I am calling 60 Days of Extended Events. The purpose of these posts will be to help somebody progress through the Extended <img loading="lazy" class="size-medium wp-image-3033 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/XEisFuture-300x227.png" alt="XEisFuture" width="300" height="227" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/XEisFuture-300x227.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/XEisFuture-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/XEisFuture.png 966w" sizes="(max-width: 300px) 85vw, 300px" />Events Concepts and become more proficient at implementing and using them.</p>
<p><del>The 60 days of XE will be a two month series running from September 1, 2015 through October 30, 2015. The posts will go live only on weekdays. So while it is 60 calendar days, it will end up being somewhere in the neighborhood of 45 articles.</del></p>
<p>These are the  types of articles designed to take 5 to 15 minutes to learn a concept and move on with the work day. The articles are designed to build on previous concepts.</p>
<p>As the posts go live, I will return and update this page with the article title and link.</p>
<h3>XE Table of Contents</h3>
<ol>
<li><a href="http://bit.ly/1ig9HYJ">Shredding the Actions attached to an Extended Event</a> &#8211; 01 September 2015</li>
<li><a href="http://bit.ly/1XfzO27">How to View the Metadata for Deployed Extended Event Sessions</a> &#8211; 02 September 2015</li>
<li><a href="http://bit.ly/1Uu4QyY">How to View the Metadata for Running Extended Event Sessions</a> &#8211; 03 September 2015</li>
<li><a href="http://bit.ly/1KOU85a">Some Supporting Objects of Extended Events</a> &#8211; 04 September 2015</li>
<li><a href="http://bit.ly/1Nl6Vy9">Packages as they Relate to Extended Events</a> &#8211; 07 September 2015</li>
<li><a href="http://bit.ly/1FvxOHW">What is an Object in Extended Events?</a> &#8211; 08 September 2015</li>
<li><a href="http://bit.ly/1KDJrUP">Categorization within Extended Events</a> &#8211; 09 September 2015</li>
<li><a href="http://bit.ly/1NjPjBk">Introduction to Events within Extended Events</a> &#8211; 10 September 2015</li>
<li><a href="http://bit.ly/1K1F2Yg">The Anatomy of an Event</a> &#8211; 11 September 2015</li>
<li><a href="http://bit.ly/1KlHvOy">Extended Events and Fixed Schemas</a> &#8211; 14 September 2015</li>
<li><a href="http://bit.ly/1F0b2x1">Actions in Extended Events</a> &#8211; 15 September 2015</li>
<li><a href="http://bit.ly/1JbFDCW">Storing/Consuming Event Payloads</a> &#8211; 16 September 2015</li>
<li><a href="http://bit.ly/1Mea13Z">Data Types for your Event Payloads</a> &#8211; 17 September 2015</li>
<li><a href="http://bit.ly/1FkDI3D">Custom Data / Maps / Lookup Tables for your Event Payloads</a> &#8211; 18 September 2015</li>
<li><a href="http://bit.ly/1KvDy5I">Predicates and Event Data</a> &#8211; 21 September 2015</li>
<li><a href="http://bit.ly/1YyQp1n">Comparison Predicates</a> &#8211; 22 September 2015</li>
<li><a href="http://bit.ly/1MIGeDI">Predicate Order is Critical</a> &#8211; 23 September 2015</li>
<li><a href="http://bit.ly/1iy9srM">Putting it all together into a Session</a> &#8211; 24 September 2015</li>
<li><a href="http://bit.ly/1iA7M0N">Extended Events GUI</a> &#8211; 25 September 2015</li>
<li><a href="http://bit.ly/1MAKfXV">Deployed Session Settings &#8211; Metadata</a> &#8211; 28 September 2015</li>
<li><a href="http://bit.ly/1VkKcqF">Deployed Session Metadata for Events</a> &#8211; 29 September 2015</li>
<li><a href="http://bit.ly/1KRqXdi">Deployed Session Metadata for Actions</a> &#8211; 30 September 2015</li>
<li><a href="http://bit.ly/1FKl3yD">Deployed Session Metadata for Targets</a> &#8211; 01 October 2015</li>
<li><a href="http://bit.ly/1YTTSIb">Set Operations and Metadata</a> &#8211; 02 October 2015</li>
<li><a href="http://bit.ly/1Ohjefn">Backup Deployed Sessions</a> &#8211; 05 October 2015</li>
<li><a href="http://bit.ly/1LvhE9x">Extended Event Management Power Tools</a> &#8211; 06 October 2015</li>
<li><a href="http://bit.ly/1jNKo0M">XEvent Metadata via PoSH</a> &#8211; 07 October 2015</li>
<li><a href="http://bit.ly/1NpxtPi">Action and Predicate Metadata with PowerShell</a> &#8211; 08 October 2015</li>
<li><a href="http://bit.ly/1LDuOkN">Target Metadata with PowerShell</a> &#8211; 09 October 2015</li>
<li><a href="http://bit.ly/1jYINp3">Simplified Session Backups</a> &#8211; 12 October 2015</li>
<li><a href="http://bit.ly/1G2QiVX">Intro to Reading Event_file Data</a> &#8211; 13 October 2015</li>
<li><a href="http://bit.ly/1NcsAGs">Dynamically Read event_file Data</a> &#8211; 14 October 2015</li>
<li><a href="http://bit.ly/1Qwycff">Better Practices for Reading Event_file Targets</a>   &#8211; 15 October 2015</li>
<li><a href="http://bit.ly/1k9Ca3n">Jumping into the ring_buffer</a> &#8211; 16 October 2015</li>
<li><a href="http://bit.ly/1jx1Abb">Know before you Go &#8211; Target Settings</a> &#8211; 19 October 2015</li>
<li><a href="http://bit.ly/1LAS3GE">Matching Events into Pairs</a> &#8211; 20 October 2015</li>
<li><a href="http://bit.ly/1W3RjyQ">Parsing Matched Events</a> &#8211; 21 October 2015</li>
<li><a href="http://bit.ly/1R49PG9">Using and Reading the Histogram</a> &#8211; 22 October 2015</li>
<li><a href="http://bit.ly/1PL3aCg">Bean Counting and Events</a> &#8211; 23 October 2015</li>
<li><a href="http://bit.ly/1PPvtzm">Seeing Short-Circuiting at Work</a> &#8211; 26 October 2015</li>
<li><a href="http://bit.ly/1GG2HPC">Intro to Internals Via XEvents</a> &#8211; 27 October 2015</li>
<li><a href="http://bit.ly/1PUdeJ3">Azure SQL DB and XE</a> &#8211; 28 October 2015</li>
<li><a href="http://bit.ly/1GMfikp">Default Sessions</a> &#8211; 29 October 2015</li>
<li><a href="http://bit.ly/1Ri5DTo">Tricks and Treats with XE</a> &#8211; 30 October 2015 (Happy Halloween)</li>
</ol>
<p><em><strong>At the end of this two month series, there is still just too much to cover. Since I have plenty more in my queue, I have decided to extend the series into overtime. I have no guarantees on how many more posts I will add to the series from here, but I will continue to add more into the series until the queue is depleted.</strong></em></p>
<ol>
<li><a href="http://bit.ly/1NQBYjr">Log Files from Different Sources</a> &#8211; 30 December 2015</li>
<li><a href="http://bit.ly/1P1ZFDs">Customize The XEvent Log Display</a> &#8211; 31 December 2015</li>
<li><a href="http://bit.ly/1R1I4RS">Filtering Logged Data</a> &#8211; 01 January 2016</li>
<li><a href="http://bit.ly/1NXXNxR">Hidden GUI Gems</a> &#8211; 02 January 2016</li>
<li><a href="http://bit.ly/22I4PhN">A Day in the Stream</a> &#8211; 04 January 2016</li>
<li><a href="http://bit.ly/1VHv0Al">Waiting, is it a Bad Thing?</a> &#8211; 04 January 2016</li>
<li><a href="http://bit.ly/1ZdCTTQ">Alter Event Session</a> &#8211; 07 January 2016</li>
<li><a href="http://bit.ly/2arQWit">Extended Event Help Queries</a> &#8211; 19 July 2016</li>
<li><a href="http://bit.ly/29WYHRk">Query to Find the Right Event</a> &#8211; 21 July 2016</li>
<li><a href="http://bit.ly/2aL3PVu">Better Method to Parse Session XML Data</a> &#8211; 01 August 2016</li>
<li><a href="http://bit.ly/2b0xKuy">Using XEvents to Audit Queries</a> &#8211; 08 August 2016</li>
<li><a href="http://bit.ly/2c6jLpl">Finding the Right Path</a> &#8211; 24 August 2016</li>
<li><a href="http://bit.ly/2byXc6X">Deprecated Features via XEvents</a> &#8211; 30 August 2016</li>
<li><a href="http://bit.ly/2CNtw3Z">Index Maintenance Operations</a> &#8211; 20 December 2017</li>
<li><a href="http://bit.ly/2BkPBGC">Feature: XE Profiler</a> &#8211; 22 December 2017</li>
<li><a href="http://bit.ly/2Byoxnl">XE Permissions</a> &#8211; 25 December 2017</li>
<li><a href="http://bit.ly/2zD3BK7">XE System Messages</a> &#8211; 27 December 2017</li>
<li><a href="http://bit.ly/2BPdzde">Correlate Trace and XE Events</a> &#8211; 28 December 2017</li>
<li><a href="http://bit.ly/2q3OpWO">An Introduction to Templates</a> &#8211; 30 December 2017</li>
<li><a href="http://bit.ly/1ET6yYN">Enterprise Thinking with Default Sessions</a> &#8211; 9 September 2015</li>
<li><a href="http://bit.ly/2EtTSK2">Correlate SQL Trace and Actions</a> &#8211; 1 January 2018</li>
<li><a href="http://bit.ly/2qbdZcC">Dynamics AX Event Session</a> &#8211; 2 January 2018</li>
<li><a href="http://bit.ly/2qnl2PM">Sharepoint Diagnostics and XE</a> &#8211; 3 January 2018</li>
<li><a href="http://bit.ly/2r9F7cx">Checking the Health of your CLR</a> &#8211; 16 January 2018</li>
<li><a href="http://bit.ly/2Fti0zB">Profiler for Extended Events: Quick Settings</a> &#8211; 5 March 2018</li>
<li><a href="http://bit.ly/2p25KMh">Extended Events File Initialization Failure</a> &#8211; 9 March 2018</li>
<li><a href="http://bit.ly/2FpLz6u">Monitor Database Offline Events</a> &#8211; 15 November 2018</li>
<li><a href="http://bit.ly/2FKp5NN">How to Translate Event Duration</a> &#8211; 20 November 2018</li>
<li><a href="https://jasonbrimhall.info/2018/11/21/azure-data-studio-and-xevents/">Azure Data Studio and XEvents</a> &#8211; 21 November 2018</li>
<li><a href="http://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/">Ghost Cleanup in SQL</a> &#8211; 28 October 2014</li>
<li><a href="https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">Audit Database File Size Changes (v1)</a> &#8211; 26 November 2014</li>
<li><a href="http://jasonbrimhall.info/2018/11/27/auditing-when-database-files-change/">Database File Size Changes</a> &#8211; 27 November 2018</li>
<li><a href="http://jasonbrimhall.info/2015/04/07/audit-who-dropped-the-database/">Where did the Database Go?</a> &#8211; 7 April 2015</li>
<li><a href="http://jasonbrimhall.info/2018/12/06/capture-the-flag-the-trace-flag/">Track Trace Flag Changes</a> &#8211; 6 December 2018</li>
<li><a href="http://jasonbrimhall.info/2018/12/10/the-mystery-of-missing-backup-files/">Missing Backup Files (a story)</a> &#8211; 10 December 2018</li>
<li><a href="http://jasonbrimhall.info/2016/04/12/awesome-sql-server-feature/">Using XE to Solve a Synonym Issue</a> &#8211; 12 April 2016</li>
<li><a href="http://bit.ly/2EPqVLG">Quick and Easy XE for Azure DB</a> &#8211; 24 December 2018</li>
<li><a href="http://bit.ly/2ELiQaf">How to: XEvents as Profiler</a> &#8211; 25 December 2018</li>
<li><a href="http://bit.ly/2EPMYlt">Upgrading From SQL Server Profiler</a> &#8211; 26 December 2018</li>
<li><a href="http://bit.ly/2ERIXwY">How to: File Target use in Extended Events</a> &#8211; 27 December 2018</li>
<li><a href="http://bit.ly/2EQRZdP">SQL Servers Black Box Recorder &#8211; Def Trace</a> &#8211; 28 December 2018</li>
<li><a href="http://jasonbrimhall.info/2018/12/29/sql-servers-black-box-recorder-system_health/" class="broken_link">SQL Servers Black Box Recorder &#8211; system_health</a> &#8211; 29 December 2018</li>
<li><a href="http://jasonbrimhall.info/2018/12/30/sqls-black-box-recorder-sp_server_diagnostics/">SQLs Black Box Recorder &#8211; sp_server_diagnostics</a> &#8211; 30 December 2018</li>
<li><a href="http://jasonbrimhall.info/2018/12/31/finding-installed-event-sessions/">Finding Installed Event Sessions</a> &#8211; 31 December 2018</li>
<li><a href="http://jasonbrimhall.info/2019/01/01/finding-application-session-settings/">Finding Application Session Settings</a> &#8211; 1 January 2019</li>
<li><a href="http://jasonbrimhall.info/2019/01/02/checking-your-memory-with-xe/">Checking Your Memory with XE</a> &#8211; 2 January 2019</li>
<li><a href="http://bit.ly/2Fa1uUP">Event Tracing for Windows Target</a> &#8211; 3 January 2019</li>
<li><a href="http://bit.ly/2F6sfdw">Automatic Tuning Monitoring and Diagnostics</a> &#8211; 4 January 2019</li>
<li><a href="http://jasonbrimhall.info/2019/01/05/short-circuiting-your-session/">Short Circuiting Your Session</a> &#8211; 5 January 2019</li>
<li><a href="http://bit.ly/2FwrYkc">Audit SQL Agent Jobs</a> &#8211; 17 January 2019</li>
<li><a href="http://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/">Execution Plans in Extended Events</a> &#8211; 17 June 2015</li>
<li><a href="http://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">XEvents and the Data Collector</a> &#8211; 21 December 2012</li>
<li><a href="http://bit.ly/1hlvISR">Retention of XE Session Data in a Table</a> &#8211; 3 Jan 2014</li>
<li><a href="http://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/">Reading Extended Event File Session Data</a> &#8211; 21 June 2015</li>
<li><a href="http://bit.ly/1A45NZy">Trapping Online Index Operations</a> &#8211; 29 Jan 2015</li>
<li><a href="http://bit.ly/XEMissingDB">Audit who Dropped the Database</a> &#8211; 7 April 2015</li>
<li><a href="http://bit.ly/XEDatatype">Extended Events and Data Types</a> &#8211; 14 April 2015</li>
<li><a href="http://bit.ly/XETreehugger">Energy Savings and Extended Events</a> &#8211; 10 June 2015</li>
<li><a href="http://bit.ly/XEAuditDBDrop12">Database Drops in SQL 2012</a> &#8211; 1 July 2015</li>
<li><a href="http://bit.ly/newxe2016">New Extended Events for 2016</a> &#8211; 6 July 2015</li>
<li><a href="http://bit.ly/1KP9hnU">Database Settings Changes</a> &#8211; 8 July 2015</li>
<li><a href="http://bit.ly/1MIJ2wN">Extended Events Removed from 2016</a> &#8211; 22 July 2015</li>
<li><a href="http://bit.ly/1Jvy9uM">Shredding XML in XEvents</a> &#8211; 26 August 2015</li>
<li><a href="http://bit.ly/2FuvuZO">An Experiment with Deadlocks</a> &#8211; 25 March 2019</li>
<li><a href="http://bit.ly/2G1iuuX">Database Recovery Monitoring with XE</a> &#8211; 10 April 2019</li>
<li><a href="http://bit.ly/2QdoPbl">Event Log File Paths</a> &#8211; 20 May 2019</li>
<li><a href="http://bit.ly/2QiRqw5">Mass Backup All Sessions</a> &#8211; 22 May 2019</li>
<li><a href="http://jasonbrimhall.info/2019/06/05/implicit-conversion-insights-with-xe/" class="broken_link">Implicit Conversion Insights with XE</a> &#8211; 05 June 2019</li>
<li><a href="http://bit.ly/2IoDblQ">Top 5 Methods to Easily Open Event Log Files</a> &#8211; 07 June 2019</li>
<li><a href="http://bit.ly/2IDdRZr">Get the Source of PREEMPTIVE_OS_PIPEOPS Waits</a> &#8211; 13 June 2019</li>
<li><a href="https://jasonbrimhall.info/2019/06/25/database-file-changes/">Audit DB File Sizes</a> (Reboot) &#8211; 25 June 2019</li>
<li><a href="https://jasonbrimhall.info/2019/07/03/is-that-database-in-use/">Database In Use</a> &#8211; 3 July 2019</li>
<li><a href="https://jasonbrimhall.info/2019/07/09/event-files-on-linux/">Event Files on Linux</a> &#8211; 9 July 2019</li>
<li><a href="https://jasonbrimhall.info/2019/07/17/life-support-2008-audit-logons/">Server 2008 – Audit Logons</a> &#8211; 17 July 2019</li>
<li><a href="https://jasonbrimhall.info/2020/01/03/creative-extended-event-sessions/">Creative Extended Event Sessions</a> &#8211; 3 January 2020</li>
<li><a href="https://jasonbrimhall.info/2020/01/04/creative-xe-sessions-funky-data/">Creative XE Sessions &#8211; Funky Data</a> &#8211; 4 January 2020</li>
<li><a href="https://jasonbrimhall.info/2019/12/27/easy-audit-index-changes/">Easy Audit Index Changes</a>  &#8211; 27 December 2019</li>
<li><a href="https://jasonbrimhall.info/2020/01/10/powershell-to-backup-xe-session/">PowerShell to Backup XE Session</a> &#8211; 10 Jan 2020</li>
<li><a href="https://jasonbrimhall.info/2020/03/11/window-shopping-the-query-store-with-xevents/">Window Shopping the Query Store with XEvents</a> &#8211; 11 Mar 2020</li>
<li><a href="https://jasonbrimhall.info/2020/03/12/collation-conflict-with-extended-events/">Collation Conflict with Extended Events</a> &#8211; 12 Mar 2020</li>
<li><a href="https://jasonbrimhall.info/2020/04/20/audit-logons-with-extended-events/">Audit Logons with Extended Events</a> &#8211; 20 April 2020</li>
<li>TBA</li>
</ol>
<p>Some rather advanced uses and topic concerning Extended Invents. These are a little more time consuming.</p>
<ol>
<li>TDE &#8211; TBA</li>
<li>Encryption &#8211; TBA</li>
<li>TLS &#8211; TBA</li>
<li>NUMA / Schedulers &#8211; TBA</li>
<li>TBA &#8211; TBA</li>
</ol>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2892" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">Learning Extended Events in 60 Days</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events Packages</title>
		<link>https://jasonbrimhall.info/2015/09/07/extended-events-packages/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extended-events-packages</link>
					<comments>https://jasonbrimhall.info/2015/09/07/extended-events-packages/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 07 Sep 2015 11:51:03 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2858</guid>

					<description><![CDATA[<p>The first core building block to the data that builds Extended Events is the concept around packages.</p>
The post <a href="https://jasonbrimhall.info/2015/09/07/extended-events-packages/">Extended Events Packages</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today, I continue on with exploring some of the metadata concerning Extended Events. To date, I have explored various aspects of session metadata whether the session is running or stopped. Today, I want to take a step back and look at the framework that helps give us this tool.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/database_postage.png"><img loading="lazy" class="wp-image-2860 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/database_postage-283x300.png" alt="database_postage" width="159" height="169" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/database_postage-283x300.png 283w, https://jasonbrimhall.info/wp-content/uploads/2015/09/database_postage-47x50.png 47w, https://jasonbrimhall.info/wp-content/uploads/2015/09/database_postage.png 424w" sizes="(max-width: 159px) 85vw, 159px" /></a>The first core building block to the data that builds Extended Events is the concept around packages.</p>
<p>When I think of package, I like to think of a container that gives me access to one or more smaller items. It is just like a parcel that may be shipped to you via your favorite courier. Only this is obviously something electronic and could potentially contain much much more than any traditional parcel would contain.</p>
<p>Microsoft exposes the packages that contain all of the components of extended events via the DMV sys.dm_xe_packages. Combine this DMV with another DMV not specific to Extended Events and we can see which DLL on the file-system exposes that particular package and grants us access to various components of Extended events. That second DMV is sys.dm_os_loaded_modules.</p>
<h2>Packages</h2>
<p>Knowing the source of the Extended Event object is useful in some cases. Being able to pull out the pertinent information isn&#8217;t terribly difficult either. I can run a query like the following and get just about everything I might want to know about the package (well maybe not if I want to know the memory address as well, but that is an easy fix).</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT xp.name AS PackageName
		,xp.description AS PackageDesc
		,xp.capabilities_desc
		,REVERSE(LEFT(REVERSE(olm.name),CHARINDEX('\',REVERSE(olm.name))-1)) AS DLLName
		,olm.file_version
		,xp.module_guid
	FROM sys.dm_xe_packages xp
		INNER JOIN sys.dm_os_loaded_modules olm
			ON xp.module_address = olm.base_address;</pre><p>Running that on a SQL Server 2014 instance, I will see results like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe.png"><img loading="lazy" class="alignnone wp-image-2862 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe-1024x305.png" alt="packages_xe" width="560" height="167" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe-1024x305.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe-300x89.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/packages_xe.png 1922w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>Looking at my results, there is one that is highlighted &#8211; package0. This package is basically like the utility drawer &#8211; it contains most of everything that you will need to (or maybe want to) use with extended events. At least that is the definition of the package. It is supposed to contain all of the data maps, data types, operators, actions, and targets.</p>
<p>There is another very interesting package that is visible with this particular query. That is the SecAudit package. This package is used by SQL Audits. The contents of the package are accessed automatically when creating audits and audit specifications. That is a topic for a different discussion.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2858" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/07/extended-events-packages/">Extended Events Packages</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/07/extended-events-packages/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>XEvent Session Supporting Cast</title>
		<link>https://jasonbrimhall.info/2015/09/04/xevent-session-supporting-cast/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xevent-session-supporting-cast</link>
					<comments>https://jasonbrimhall.info/2015/09/04/xevent-session-supporting-cast/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 04 Sep 2015 11:57:39 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2846</guid>

					<description><![CDATA[<p>Beyond the metadata in the the catalog views and DMVs, there are a few more objects that come in handy when dealing with Extended Events. I call these the supporting cast.</p>
The post <a href="https://jasonbrimhall.info/2015/09/04/xevent-session-supporting-cast/">XEvent Session Supporting Cast</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>So far, in this series, I have discussed the means to view the metadata associated with Extended Events. I also demonstrated some quick and simple means to retrieve some metadata via the <a href="http://bit.ly/1XfzO27">catalog views</a> and <a href="http://bit.ly/1Uu4QyY">DMVs</a>.</p>
<p>Beyond the metadata in the the catalog views and DMVs, there are a few more objects that come in handy when dealing with Extended Events. I call these the supporting cast. This cast would come in the form of yet another DMV and a couple of tables. Granted this is not the end of the tools that can be used when dealing with Extended Events, the remaining tools would be classified differently and are going to be saved for another time.</p>
<h2>Supporting Cast</h2>
<h3>Tables</h3>
<p>First up in the supporting cast role would be the group of tables. These are not your ordinary tables. These tables could be your best friend as you work to convert yourself away from server side traces and profiler traces. These tables contain conversion (and therefor static) data to help translate from server trace events to extended event events (yes it is extended event events &#8211; sounds redundant but that is what it is).</p>
<p>The tables you will come to love are:</p>
<table>
<tbody>
<tr>
<th width="200">Name</th>
<th>Description</th>
</tr>
<tr>
<td>trace_xe_event_map</td>
<td>One row per Extended Events event that is mapped to a SQL Trace event class.</td>
</tr>
<tr>
<td>trace_xe_action_map</td>
<td>One row per Extended Events action that is mapped to a SQL Trace column ID.</td>
</tr>
</tbody>
</table>
<p>And, as you might have imagined, the quick and easy way to view what tables might be related to extended events is fairly straight forward as well.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT SCHEMA_NAME(o.schema_id) AS SchemaName, o.name 
	FROM sys.all_objects o
	WHERE o.is_ms_shipped = 1
		AND o.type = 'u'
		AND o.name LIKE '%xe%';</pre><p>If I query the trace_xe_event_map table, I will see the mapping between 138 trace event ids to the extended event events along with the package through which that event is exposed for extended events. Don&#8217;t worry about packages just yet, I will discuss that at a later time. If I do the same thing for the action_map table, I will see a similar result.</p>
<p>As I mentioned previously, these tables will be essential in converting any of those old profiler or server side traces into the XEvent platform.</p>
<h3>DMV</h3>
<p>Of all of the XEvent DMVs, all but one are used for the metadata of running sessions. The remaining DMV deals more with troubleshooting and session performance than it does with metadata. The name of the DMV is sys.dm_os_dispatcher_pools.</p>
<p>Why is this DMV thrown down to the supporting cast role? Well, despite (current) <a href="https://msdn.microsoft.com/en-us/library/bb630336.aspx">documentation</a>, this DMV is not exclusively used by Extended Events. You will see dispatcher pools and threads for various different background tasks like XEvents, In-Memory OLTP (Hekaton), and filestream &#8211; to name a few.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool.png"><img loading="lazy" class="alignnone wp-image-2851 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool-1024x176.png" alt="dispatcherpool" width="560" height="96" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool-1024x176.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool-300x52.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool-50x9.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/09/dispatcherpool.png 1768w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>The preceding results could be viewed using a query similar to the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT type
		, name
		, dispatcher_count
		, dispatcher_ideal_count
		, queue_length
	FROM sys.dm_os_dispatcher_pools</pre><p>If it seems there may be a problem with the server and you just don&#8217;t see events dumping into the target as quickly as you think they should, you may want to check this DMV. In the DMV, one will find things like queue_length and dispatcher_waiting_count. A high waiting_count would indicate no events are firing. While a high queue_length would indicate there are many events backing up while waiting to be processed.</p>
<p>Stay tuned for more quick tidbits as I continue this series.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2846" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/04/xevent-session-supporting-cast/">XEvent Session Supporting Cast</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/04/xevent-session-supporting-cast/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Shredding Extended Event Actions</title>
		<link>https://jasonbrimhall.info/2015/09/01/shredding-extended-event-actions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=shredding-extended-event-actions</link>
					<comments>https://jasonbrimhall.info/2015/09/01/shredding-extended-event-actions/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 01 Sep 2015 12:21:12 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2833</guid>

					<description><![CDATA[<p>Are you rolling the dice with your love/hate relationship with XML? Tune in to see how you can ease your XML frustration along with increasing your free time to do more important things.</p>
The post <a href="https://jasonbrimhall.info/2015/09/01/shredding-extended-event-actions/">Shredding Extended Event Actions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="size-medium wp-image-2834 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/lovehatedice_v1-300x129.png" alt="lovehatedice_v1" width="300" height="129" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehatedice_v1-300x129.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehatedice_v1-50x22.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehatedice_v1.png 856w" sizes="(max-width: 300px) 85vw, 300px" />The other day I wrote about that torrid love/hate relationship DBAs tend to have with working with XML. In that same post, I promised I would have a follow up post about XML in Extended Events.</p>
<p>Well, today I present to you another opportunity for you to renew your love/hate relationship with XML.</p>
<p>In the previous post (<a href="http://bit.ly/1Jvy9uM">which you can read here</a>), I discussed just one facet of shredding the XML related to Extended Events. Today, we have &#8220;actions&#8221; to discuss. I am not going to get into what an &#8220;action&#8221; is today. I will save that for a near future post.</p>
<p>For the shredding of the actions, I will use the TreeHuggerCPU Event Session I used in the last article (for the sake of consistency). The session doesn&#8217;t necessarily need to be running. I will just pull the actions related to the session from the metadata accessible via the system catalog views.</p>
<p>Should the session be running (and in my case it is for demonstration purposes), I could open the session data and view it as XML and see something like the following:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml.png"><img loading="lazy" class="alignnone wp-image-2835" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml-300x188.png" alt="action_xml" width="400" height="250" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml-300x188.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml-50x31.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/action_xml.png 939w" sizes="(max-width: 400px) 85vw, 400px" /></a></p>
<p>&nbsp;</p>
<p>I have highlighted two different types of nodes available in the XML data. In the previous article, I discussed the &#8220;data&#8221; nodes and I have highlighted that in red here. Today, we are talking actions, and those are highlighted in green this time around. It is the &#8220;action&#8221; nodes that we will be shredding via the following script.</p>
<p>&nbsp;</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @EventName VARCHAR(64) = NULL --'sp_statement_completed'
		, @EventSession VARCHAR(128) = NULL --'Deadlock' --NULL
	;

/* auto generate the xml associated to an event session action deployed to the server */
SELECT p.name AS package_name
	        ,o.name AS action_name
			,',event_data.value(''(event/action[@name="' + esa.name + '"]/value)[1]'', ''' + 
			CASE 
				WHEN o.type_name = 'guid'
				THEN 'uniqueidentifier'
				WHEN o.type_name = 'boolean'
				THEN 'bit'
				WHEN o.type_name = 'binary_data'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'callstack'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'filetime'
				THEN 'varbinary(max)'
				WHEN o.type_name = 'cpu_cycle'
				THEN 'varbinary(max)'
				WHEN ISNULL(o.type_name,'') = ''
				THEN NULL
				WHEN o.type_name &lt;&gt; 'unicode_string'
					AND o.type_name &lt;&gt; 'ansi_string'
					AND o.type_name &lt;&gt; 'ptr'
					AND o.type_name NOT LIKE '%int%'
				THEN o.type_name
				WHEN o.type_name LIKE '%int%'
				THEN 'int'
				ELSE 'varchar(max)' END + ''') AS ' + esa.name +'' AS ActionXML
			,ses.name AS EventSessionName
			, ese.name AS EventName
	        ,o.description
	FROM sys.dm_xe_packages AS p
		INNER JOIN sys.dm_xe_objects AS o
			ON p.guid = o.package_guid
		INNER JOIN sys.server_event_session_actions esa
			ON o.name = esa.name
		INNER JOIN sys.server_event_sessions ses
			ON esa.event_session_id = ses.event_session_id
		INNER JOIN sys.server_event_session_events ese
			ON esa.event_session_id = ese.event_session_id
			AND ese.event_id = esa.event_id
	WHERE o.object_type = 'action'
		AND (o.capabilities IS NULL OR o.capabilities &amp; 1 = 0)
		AND (p.capabilities IS NULL OR p.capabilities &amp; 1 = 0)
		AND ese.name = ISNULL(@EventName,ese.name)
		AND ses.name = ISNULL(@EventSession,ses.name)
	ORDER BY esa.name, ses.name, ese.name
	;</pre><p>With this script, I can either search for all actions tie to an XE Session, for the actions tied to one event within a Single XE Session, for all actions tied to a specific event across multiple sessions, or for all actions that are tied to any event tied to any event session deployed to the server.</p>
<p>Combine this with the previous script and suddenly all of that XML just got several times easier.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2833" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/09/01/shredding-extended-event-actions/">Shredding Extended Event Actions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/09/01/shredding-extended-event-actions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Shredding XML in XEvents</title>
		<link>https://jasonbrimhall.info/2015/08/26/shredding-xml-in-xevents/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=shredding-xml-in-xevents</link>
					<comments>https://jasonbrimhall.info/2015/08/26/shredding-xml-in-xevents/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 26 Aug 2015 12:18:29 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<category><![CDATA[XML]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2823</guid>

					<description><![CDATA[<p>One of the biggest pains with Extended Events is the thing we love to hate - XML. XML is so foreign to many DBAs. It's not relational and often brings nightmares of parsing and performance issues.</p>
The post <a href="https://jasonbrimhall.info/2015/08/26/shredding-xml-in-xevents/">Shredding XML in XEvents</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="size-full wp-image-2824 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/lovehate.png" alt="lovehate" width="170" height="170" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehate.png 170w, https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehate-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/08/lovehate-50x50.png 50w" sizes="(max-width: 170px) 85vw, 170px" />One of the biggest pains with Extended Events is the thing we love to hate &#8211; XML. XML is so foreign to many DBAs. It&#8217;s not relational and often brings nightmares of parsing and performance issues.</p>
<p>Despite that, Extended Events takes advantage of XML much like we have seen in so many other areas of SQL Server. You might be familiar with execution plans, SSRS, SSIS, or maybe even the ring buffer. If you look hard enough, you will find XML within the database engine. Whether you love or hate it, you still have to deal with it. Today, I want to dive into a means of dealing with XML, as far as Extended Events is concerned.</p>
<h3>Mad Scientist Lab</h3>
<p>Let&#8217;s head on over to the lab to dive into XML head first. I will be using a session as an example of which I have <a href="http://bit.ly/XETreehugger">previously written &#8211; here</a>.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER EVENT SESSION TreeHuggerCPU 
ON SERVER 
STATE = START;
GO

SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM ( SELECT target_data = CONVERT(XML, target_data)
							FROM sys.dm_xe_session_targets t
								INNER JOIN sys.dm_xe_sessions s
									ON t.event_session_address = s.address
							WHERE t.target_name = 'event_file'
								AND s.name = 'TreeHuggerCPU'
						) cte1
					CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget )
					CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name',
																'varchar(1000)'),
																NULL, NULL, NULL) t2;

ALTER EVENT SESSION TreeHuggerCPU 
ON SERVER 
STATE = STOP;
GO</pre><p>If the session is already deployed &#8211; great. If not, you may need to create it to execute (successfully) these scripts. Note that I am starting the session and then fetching some data and then stopping the session. To see some data, you may want to wait a few cycles before stopping the event session.</p>
<p>The sole purpose is just so I can take a look at the session data in XML format. Now that I have some data, I would see something that might look like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;event name="perfobject_processor" package="sqlserver" timestamp="2015-08-26T02:47:28.993Z"&gt;
  &lt;data name="percent_c1_time"&gt;
    &lt;value&gt;4312500965&lt;/value&gt;
  &lt;/data&gt;
  &lt;data name="percent_c2_time"&gt;
    &lt;value&gt;260553380830&lt;/value&gt;
  &lt;/data&gt;
  &lt;data name="percent_c3_time"&gt;
    &lt;value&gt;0&lt;/value&gt;
  &lt;/data&gt;
  &lt;data name="percent_dpc_time"&gt;
    &lt;value&gt;529726562&lt;/value&gt;
  &lt;/data&gt;
  &lt;data name="percent_idle_time"&gt;
    &lt;value&gt;274891621093&lt;/value&gt;
  &lt;/data&gt;
  &lt;data name="percent_interrupt_time"&gt;
    &lt;value&gt;369296875&lt;/value&gt;
  &lt;/data&gt;</pre><p>For today&#8217;s lab, I just want to focus on the &#8220;data&#8221; node while saving the attributes of the event node, and the action node(s) for another discussion.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode.png"><img loading="lazy" class="alignnone wp-image-2826 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode-1024x563.png" alt="xml_datanode" width="560" height="308" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode-1024x563.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode-300x165.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode-50x27.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/xml_datanode.png 1033w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>The &#8220;data&#8221; node happens to be the data that is directly tied to an Extended Event event. When looking at the event metadata, this would be called the event columns. Knowing that all of these columns follow a fairly standard format can make it a bit easier to figure out how to query this data. One of the daunting things with XML is figuring out how to query the XML data to make it more relational &#8211; a format we may be more accustomed to seeing (as DBAs).</p>
<p>Due to the daunting task of figuring out how to query the XML and because it is a pretty decent format for consumption, I decided to simplify the entire process. Why not write some code that will write the XML parsing code for me? And that is what we have here.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* auto-gen the xml for the columns for your XE sessions */
DECLARE @EventName VARCHAR(64) = NULL --'query_post_execution_showplan'
	,@ReadFlag VARCHAR(64) = 'readonly' --NULL if all columntypes are desired
	,@SessionName	VARCHAR(128) = NULL --'system_health' --NULL if all Sessions are desired

SELECT oc.OBJECT_NAME AS EventName
		,oc.name AS column_name, oc.type_name
		,',event_data.value(''(event/data[@name="' + oc.name + '"]/value)[1]'',''' + 
			CASE 
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name = 'guid'
				THEN 'uniqueidentifier'
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name = 'boolean'
				THEN 'bit'
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name &lt;&gt; 'unicode_string'
					AND oc.type_name &lt;&gt; 'ansi_string'
					AND oc.type_name &lt;&gt; 'ptr'
					AND oc.type_name NOT LIKE '%int%'
				THEN oc.type_name
				WHEN ISNULL(xmv.name,'') = ''
					AND oc.type_name LIKE '%int%'
				THEN 'int'
				ELSE 'varchar(max)' END + ''') AS ' + oc.name + '' AS ColumnXML
		,oc.column_type AS column_type
		,oc.column_value AS column_value
		,oc.description AS column_description
		,ca.map_value AS SearchKeyword
	FROM sys.dm_xe_object_columns oc
	-- do we have any custom data types
		OUTER APPLY (SELECT DISTINCT mv.name FROM sys.dm_xe_map_values mv
			WHERE mv.name = oc.type_name
			AND mv.object_package_guid = oc.object_package_guid) xmv
	--just get the unique events that are tied to a session on the server (stopped or started state)
		CROSS APPLY (SELECT DISTINCT sese.name,ses.name AS SessionName
						FROM sys.server_event_session_events sese
							INNER JOIN sys.server_event_sessions ses
								ON sese.event_session_id = ses.event_session_id) sesea
	--keyword search phrase tied to the event
		CROSS APPLY (SELECT TOP 1 mv.map_value
						FROM sys.dm_xe_object_columns occ
						INNER JOIN sys.dm_xe_map_values mv
							ON occ.type_name = mv.name
							AND occ.column_value = mv.map_key
						WHERE occ.name = 'KEYWORD'
							AND occ.object_name = oc.object_name) ca
	WHERE oc.column_type &lt;&gt; @ReadFlag
		AND sesea.name = oc.object_name
		AND oc.object_name = ISNULL(@EventName,oc.object_name)
		AND sesea.SessionName = ISNULL(@SessionName,sesea.SessionName)
	ORDER BY sesea.SessionName,oc.object_name
	;
GO</pre><p>This script will take an event session name, an Extended Event event name, or a combination of both (imagine having multiple events tied to a session) to produce the XML strings automagically. This script does only produce some pretty generic column aliases, so that part is left to the user of the script to edit after generating the XML parse statements.</p>
<p>With this script, I can quickly retrieve all of the XML parse statements for all of the data nodes within the session or event that I specify. This can significantly reduce the amount of time taken to produce a usable script to consume the event session data.</p>
<p>This is just the script to parse the event data. If there are actions tied to the session, this will not produce the statements for those actions. The script for that will be provided in a future article. Stay tuned!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2823" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/08/26/shredding-xml-in-xevents/">Shredding XML in XEvents</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/08/26/shredding-xml-in-xevents/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Tables, Columns and Defaults Oh My!</title>
		<link>https://jasonbrimhall.info/2015/08/19/tables-columns-and-defaults-oh-my/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tables-columns-and-defaults-oh-my</link>
					<comments>https://jasonbrimhall.info/2015/08/19/tables-columns-and-defaults-oh-my/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 19 Aug 2015 18:42:38 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2814</guid>

					<description><![CDATA[<p>The joys of inheriting a new database and being thrown into the fire to quickly assimilate as much information about the database as possible can be troublesome. This script will help with that!</p>
The post <a href="https://jasonbrimhall.info/2015/08/19/tables-columns-and-defaults-oh-my/">Tables, Columns and Defaults Oh My!</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Picture this if you could. You inherit a new database either through the change of a job, or finding a black box database server, or maybe due to the acquisition of a new application.</p>
<p>No matter the cause, you are now responsible for maintaining that database and you also really need to become acquainted with it. Some of the acquaintance that is needed is learning how things are related and figuring out what data goes where. Not just what data, but what type of data.</p>
<p>I know that one of the things I am frequently asked is to figure out what data type belongs with which column. Furthermore, does this same column exist in more than one table. It&#8217;s nice when things are named consistently and you are able to tie things together by column name.</p>
<p>There are also times, when that column that is so consistently named, might need to be confirmed on data types between each of the implementations. I know I have run into cases when the column might be differently defined in different tables.</p>
<p>So, what to do to tie this all together and get that intimate acquaintance with your database?</p>
<p>Luckily, I have a script that will help you figure out some of these connections.</p>
<p>First, the script.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdventureWorks2014;
GO

DECLARE @tablename sysname = NULL --'Store'
	/* NULL for all tables and table name for a specific table */
	, @isMSShipped TINYINT = NULL 
	/* null for all, 0 for user objects, 1 for ms objects */
	, @ColName	sysname = NULL --'BusinessEntityID'
	/* null for all, column name to search all tables for specific column if tablename is null */
	;

SELECT SCHEMA_NAME(t.schema_id) AS TabSchema
		,t.name AS TableName
		, c.name AS ColumnName
		, c.column_id AS ColOrdPosit
		, dt.name AS DataType
		, c.max_length AS ColLength
		, c.precision AS Precision
		, c.scale AS Scale
		, dc.type_desc
		,dc.definition
	FROM sys.tables t
		INNER JOIN sys.columns c
			ON c.object_id = t.object_id
		INNER JOIN sys.types dt
			ON c.user_type_id = dt.user_type_id
			--For system data types, user_type_id = system_type_id
		LEFT OUTER JOIN sys.default_constraints dc
			ON c.object_id = dc.parent_object_id
			AND c.column_id = dc.parent_column_id
	WHERE t.is_ms_shipped = ISNULL(@isMSShipped,t.is_ms_shipped)
		AND t.name = ISNULL(@tablename,t.name)
		AND c.name = ISNULL(@ColName, c.name)
	ORDER BY TabSchema, TableName, ColumnName;</pre><p>Now, let&#8217;s give it a trial run. See if you can spot the difference by running that against the AdventureWorks database using the value &#8220;AccountNumber&#8221; for the @ColName parameter.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult.jpg"><img loading="lazy" class="alignnone wp-image-2816 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult-1024x127.jpg" alt="ColData_Queryresult" width="560" height="69" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult-1024x127.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult-300x37.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult-50x6.jpg 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/ColData_Queryresult.jpg 2044w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>Maybe there is a legitimate reason for that Column to have a different data type specification than the other two. Maybe it doesn&#8217;t. One thing for certain is that you will be able to walk away with some questions to ask and hopefully gain a better understanding!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2814" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/08/19/tables-columns-and-defaults-oh-my/">Tables, Columns and Defaults Oh My!</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/08/19/tables-columns-and-defaults-oh-my/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>What is DBCC?</title>
		<link>https://jasonbrimhall.info/2015/08/10/what-is-dbcc/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-is-dbcc</link>
					<comments>https://jasonbrimhall.info/2015/08/10/what-is-dbcc/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Aug 2015 03:35:54 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2801</guid>

					<description><![CDATA[<p>What is really mean by DBCC and what do people mean when they say DBCC?</p>
The post <a href="https://jasonbrimhall.info/2015/08/10/what-is-dbcc/">What is DBCC?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench.png"><img loading="lazy" class="alignright wp-image-2803 size-medium" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench-300x187.png" alt="DB Nuts and Bolts" width="300" height="187" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench-300x187.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench-50x31.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/db_maint_wrench.png 324w" sizes="(max-width: 300px) 85vw, 300px" /></a>If I ask you what is DBCC, what would your answer be?</p>
<p>I want you to think about that one for just a little bit. What comes to mind when you hear DBCC? Is it the default go-to used when talking about consistency checks? Is it something more involved? Maybe it is something entirely different?</p>
<p>I ponder this because I hear it from time to time used in complete replacement for CheckDB. I have to stop and think for a minute because as of SQL Server 2016, there are 35 DBCC statements of various use that are documented. Never-mind the bounty of un-documented statements (e.g. page, ind).</p>
<p>So, I ask, what does DBCC mean to you?</p>
<p>In trying to come up with some sort of answer, I did a little bit of research. If you look in the <a href="https://msdn.microsoft.com/en-us/library/ms188796.aspx">documentation</a> (including the <a href="https://technet.microsoft.com/en-us/library/Aa258281(v=SQL.80).aspx">SQL 2000 documentation</a>), one will find this definition for DBCC:</p>
<blockquote><p>The Transact-SQL programming language provides DBCC statements that act as <strong>D</strong>ata<strong>b</strong>ase <strong>C</strong>onsole <strong>C</strong>ommands for SQL Server.</p></blockquote>
<p>It seems the documentation says it pretty clearly that DBCC is <strong>D</strong>ata<strong>b</strong>ase <strong>C</strong>onsole <strong>C</strong>ommands. (And the SQL 2000 documentation says something similar). But every now and then you hear somebody say it means <strong>D</strong>ata<strong>b</strong>ase <strong>C</strong>onsistency <strong>C</strong>hecker. And it seems the root of that may come from the SQL 6.5 or earlier days. I found this snippet in BOL from SQL 6.5:</p>
<blockquote><p>Used to check the logical and physical consistency of a database, check memory usage, decrease the size of a database, check performance statistics, and so on. DBCC is the SQL Server &#8220;database consistency checker.&#8221; DBCC helps ensure the physical and logical consistency of a database; however, DBCC is not corrective. It is recommended that you make periodic checks to ensure the logical and physical consistency of your data.</p></blockquote>
<p>This seems a little odd to me since not all DBCC statements are used for database consistency checking as this definition would call it. It seems more of a documentation bug that has taken hold than a legitimate acronym. Just think about it. With that definition, one will also see a list of DBCC statements &#8211; many of which do not perform consistency checks. Let&#8217;s look at them:</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC {
	CHECKALLOC [(database_name [, NOINDEX])] | 
	CHECKCATALOG [(database_name)] | 
	CHECKTABLE (table_name [, NOINDEX | index_id]) | 
	CHECKDB [(database_name [, NOINDEX])] | 
	CHECKIDENT [(table_name)] | 
	DBREPAIR (database_name, DROPDB [, NOINIT]) | 
	dllname (FREE) | 
	INPUTBUFFER (spid) | 
	MEMUSAGE | 
	NEWALLOC [(database_name [, NOINDEX])] | 
	OPENTRAN ({database_name} | {database_id}) 
		[WITH TABLERESULTS] | 
	OUTPUTBUFFER (spid) | 
	PERFMON | 
	PINTABLE (database_id, table_id) | 
	SHOW_STATISTICS (table_name, index_name) | 
	SHOWCONTIG (table_id, [index_id]) | 
	SHRINKDB (database_name [, new_size [, 'MASTEROVERRIDE']]) | 
	SQLPERF ({IOSTATS | LRUSTATS | NETSTATS | RASTATS [, CLEAR]} |
		{THREADS} | {LOGSPACE}) | 
	TEXTALL [({database_name | database_id}[, FULL | FAST])] | 
	TEXTALLOC [({table_name | table_id}[, FULL | FAST])] | 
	TRACEOFF (trace#) | 
	TRACEON (trace#) |
	TRACESTATUS (trace# [, trace#...]) | 
	UNPINTABLE (database_id, table_id) | 
	UPDATEUSAGE ({0 | database_name} [, table_name [, index_id]]) |
	USEROPTIONS}</pre><p>For instance, DBCC PINTABLE is hardly useful for checking consistency. The TRACESTATUS is also one that does not quite fit this acronym. That is likely why you will see the difference in the SQL 2000 and beyond documentation for DBCC.</p>
<p>Don&#8217;t be surprised if you hear me ask which DBCC statement is being inferred if I hear somebody say they ran DBCCs. It is just plain more clear to hear &#8220;CheckDB came up clean&#8221; over the alternative &#8220;DBCC came up clean&#8221;. There is little room for interpretation there.</p>
<p>In short, DBCC is an acronym for Database Console Command, and it seems more of a documentation mistake when it was called Database Consistency Checker.</p>
<p>Another interesting thought. How many people say DBCC Command(s)? Think about that one for a minute &#8211; Database Console Command Command(s). That one is less of an issue imho than the prior.</p>
<p>Just remember, think about what you mean to say when talking about a specific DBCC statement and if you really mean a consistency check, try saying CheckDB instead. I bet the clarity in the conversation will improve and there will be less hair tugging.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2801" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/08/10/what-is-dbcc/">What is DBCC?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/08/10/what-is-dbcc/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>HealthySQL &#8211; A Review</title>
		<link>https://jasonbrimhall.info/2015/08/07/healthysql-a-review/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=healthysql-a-review</link>
					<comments>https://jasonbrimhall.info/2015/08/07/healthysql-a-review/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 07 Aug 2015 19:47:37 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Book review]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2797</guid>

					<description><![CDATA[<p>A quick look into the book by Robert Pearl: Healthy SQL.</p>
The post <a href="https://jasonbrimhall.info/2015/08/07/healthysql-a-review/">HealthySQL – A Review</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>How well do you know the health of your SQL Servers and databases? Ever wonder about the current health or even what the health was like a few months back? Sure, one could anecdotally say the databases and servers are healthy, but how do you quantify it?</p>
<p>Many have asked or pondered what to do to quantify a healthy SQL server. How do you get the hard numbers to show whether the server is or is not healthy? How do you get the numbers to show that the server is performing just as well or better than it did three months ago?</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/08/dbhealth_maint.png"><img loading="lazy" class="aligncenter wp-image-2798 size-medium" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/dbhealth_maint-300x162.png" alt="dbhealth_maint" width="300" height="162" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/08/dbhealth_maint-300x162.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/08/dbhealth_maint-50x27.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/08/dbhealth_maint.png 550w" sizes="(max-width: 300px) 85vw, 300px" /></a>Now we have a way to answer those questions and more! Robert Pearl has finally published his book on Healthy SQL. In the book, Robert takes you on a journey from mapping out a plan, to capturing data, storing that data, and then how to report on that data. You will learn what to capture and what some of the various things actually mean (e.g. waits and indexes).</p>
<p>Throughout the book, you will see that Robert will introduce you to various tools. These tools can either be native to SQL Server or they could be third party tools. You will get a <img loading="lazy" class=" wp-image-2799 size-thumbnail alignright" src="http://jasonbrimhall.info/wp-content/uploads/2015/08/healthyDB-150x150.png" alt="healthyDB" width="150" height="150" />good primer on what the tool is and how to quickly use it as you become acquainted with the internals and the Health of your database and server.</p>
<p>As you progress through the book and learn about what makes a database healthy, you will encounter a chapter on how to store the data and make a repository to track your database health. You will want to create a repository so you can progress into the sections on reporting about your database health. Who doesn&#8217;t want to market to management how healthy the databases are?</p>
<p>With the tools in this book, and the repository you will create, audits and discussions will become much easier. You will be able to implement processes to help make you more aware of the environment and help keep you from getting that annoying page in the middle of the night.</p>
<p>Take a look at the book and enjoy.  You can get it from <a href="http://bit.ly/PearlHealthySQL">Amazon here</a>.</p>
<p>If you are a young DBA, new to being a DBA, an accidental DBA, or just any DBA looking for a little extra help in figuring out how to check and track the health of your server, it is worth reading this book.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2797" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/08/07/healthysql-a-review/">HealthySQL – A Review</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/08/07/healthysql-a-review/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Recipes &#8211; 2014 Edition</title>
		<link>https://jasonbrimhall.info/2015/07/21/tsql-recipes-2014-edition/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-recipes-2014-edition</link>
					<comments>https://jasonbrimhall.info/2015/07/21/tsql-recipes-2014-edition/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 21 Jul 2015 16:49:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Authored Books]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[In-memory]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2774</guid>

					<description><![CDATA[<p>Announcing&#8230;the book At long last the wait is over. After much blood, sweat and more blood and sweat, the next edition of the SQL Server Recipes book is finished. This edition brings several changes and [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/07/21/tsql-recipes-2014-edition/">TSQL Recipes – 2014 Edition</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Announcing&#8230;the book</h3>
<p><img loading="lazy" class="alignleft wp-image-2775 size-medium" src="http://jasonbrimhall.info/wp-content/uploads/2015/07/book_cover-210x300.png" alt="book_cover" width="210" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/07/book_cover-210x300.png 210w, https://jasonbrimhall.info/wp-content/uploads/2015/07/book_cover-35x50.png 35w, https://jasonbrimhall.info/wp-content/uploads/2015/07/book_cover.png 350w" sizes="(max-width: 210px) 85vw, 210px" />At long last the wait is over. After much blood, sweat and more blood and sweat, the next edition of the SQL Server Recipes book is finished.</p>
<p>This edition brings several changes and quite a bit of re-write. It has been updated for many of the new SQL Server 2014 (well, new, at least until SQL 2016 hits mainstream) features that were added. In addition, we revisited some of the other features that had been omitted from previous editions to try and give it a more encompassing feel.</p>
<p>All of that said, the book is not a comprehensive listing of every command, jot or tittle in SQL Server. There were a finite number of pages and the features in SQL Server just has far too many features and nuances to cover within a single edition.</p>
<p>Despite the limitation of page quantity, we do feel that this is a pretty comprehensive book covering a wide array of features with several examples of how to perform various tasks along with use-cases for when to use the example.</p>
<p>When you crack the covers, you will find examples of how to perform backups to blob storage in Azure, create In-memory OLTP tables, restore from blob storage, and in some cases you will see how to use Extended Events to help with troubleshooting. That is just a small sampling of the contents that fill the almost 900 pages in this book.</p>
<p>Combine this reference book with the previous editions, and you will have an excellent resource for SQL Server.</p>
<p>You can purchase the book on <a href="http://bit.ly/SQLRecipes2014">Amazon &#8211; here</a>.</p>
<h3>Now for the mushy stuff</h3>
<p>I am grateful to the folks at Apress for letting us come on board with this book and continue writing about SQL Server and creating a great resource.</p>
<p>I am grateful to the other authors Jonathan Gennick and Wayne Sheffield for helping push this along. The collaboration and support provided by these guys was fantastic. Their patience was also exceptional.</p>
<p>Equally important was the patience and understanding afforded by my family. Writing does take a significant amount of time and they sacrificed so I could continue on this project.</p>
<p>Thanks to all these folks for helping make this a great achievement!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2774" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/07/21/tsql-recipes-2014-edition/">TSQL Recipes – 2014 Edition</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/07/21/tsql-recipes-2014-edition/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server and Defaults</title>
		<link>https://jasonbrimhall.info/2015/07/14/sql-server-and-defaults/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-and-defaults</link>
					<comments>https://jasonbrimhall.info/2015/07/14/sql-server-and-defaults/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 14 Jul 2015 06:22:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Professional Development]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2766</guid>

					<description><![CDATA[<p>What is that default setting? SQL server does a fantastic job of having numerous settings at the server level and at the database level predefined for you. Additionally, the OS has a bunch of settings [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/07/14/sql-server-and-defaults/">SQL Server and Defaults</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3><img loading="lazy" class=" size-full wp-image-2309 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL2sDay" width="150" height="150" />What is that default setting?</h3>
<p>SQL server does a fantastic job of having numerous settings at the server level and at the database level predefined for you. Additionally, the OS has a bunch of settings that are predefined. These are notoriously the default settings. Or as some would say: &#8220;Set it and Forget it Settings.&#8221; Sadly, the set it part never really happens &#8211; except during the install.</p>
<p>Today is the second Tuesday of the the month, and that means it is TSQL Tuesday. As I mentioned in a <a href="http://bit.ly/1KP9hnU">previous article</a>, this month the topic is hosted by Andy Yun (<a href="https://sqlbek.wordpress.com">blog </a>| <a href="https://twitter.com/SQLBek">twitter</a>). Andy has chosen to have everybody talk about default settings in SQL Server. <a href="https://sqlbek.wordpress.com/2015/07/06/invitation-to-t-sql-tuesday-68-just-say-no-to-defaults/">You can read everything Andy has said in his invite for the month</a>.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/07/deadlydefaults.png"><img loading="lazy" class="aligncenter size-full wp-image-2767" src="http://jasonbrimhall.info/wp-content/uploads/2015/07/deadlydefaults.png" alt="deadlydefaults" width="276" height="183" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/07/deadlydefaults.png 276w, https://jasonbrimhall.info/wp-content/uploads/2015/07/deadlydefaults-50x33.png 50w" sizes="(max-width: 276px) 85vw, 276px" /></a></p>
<h3>Defaults Defaults Defaults</h3>
<p>I could ramble on about database settings that get changed, but I have already addressed the changing of database settings &#8211; <a href="http://bit.ly/1KP9hnU">here</a>. While I did address the changing of the settings, I did not address that it is an awesome thing to use to find out who might be changing those default settings (at the database level) that you have already set and optimized for the instance.</p>
<p>Or I could go on about how the OS has various settings that are far less than optimal for SQL Server. A good example would the that tree hugger setting that I talked about last month. But rather than do that, I will advise that you just read that article &#8211; <a href="http://bit.ly/XETreehugger">here</a>.</p>
<p>Or we can belabor the point about a fantastic setting that equates to NOLOCK. But, that isn&#8217;t a default setting and one would need a pretty good reason to change the default setting to READ UNCOMMITTED. So, just read a bit about the coolness you can see in the execution plans when the NOLOCK directive is used &#8211; <a href="http://bit.ly/1Qytj9F">here</a>.</p>
<p>There are just so many wonderful default settings within SQL Server (or within the Windows OS) that could be discussed or that have already been discussed.</p>
<p>About all of those settings, I will say this. Database Settings are not &#8220;One Size Fits ALL.&#8221; But that is what a default setting is trying to do. If you find default settings within a database, then you should probably evaluate the setting and make sure it is set appropriately.</p>
<h3>What default to discuss then?</h3>
<p>Rather than talk about a plethora of settings that could / should be changed, I want to speak about one I doubt most would consider. This is the default setting that can only be adjusted from between the ears!</p>
<p>This is a default behavior I have noticed with many DBAs. I have heard various names for this behavior and most are probably quite accurate. The default setting that I think should be changed is one that will lead to a longer more fulfilling career. Let me see if I can describe the behavior well enough.</p>
<p>Often times, companies will purchase monitoring software to help alert to problems within the environment. This is a good thing. A DBA can&#8217;t be available 24x7x365. So the software should be configured and tuned to each database to allow for different tolerance/alert thresholds. This is a good thing too &#8211; if it is done. When done properly, the DBA can get a good nights rest as well as feel confident the environment is running properly.</p>
<p>If the software is not properly tuned and configured, the DBA will probably rectify that sooner rather than later. This is not the big behavior to change.</p>
<p>What I do see all too often is a complete reliance on the software that is monitoring &#8211; to a fault. I have seen hundreds of DBAs just sit and watch the pretty little dials and gauges on the screen of the software and only react when one of the items turns red. A career surely can&#8217;t be built off of this kind of behavior.</p>
<p>Rather than sit there and wait for something to fail, why not proactively check the servers? Why not try to build a script repository that will do everything (and more) that the monitoring software can do? While building that repository, think of the skills that will be gained and the knowledge that can be retained across jobs! In addition, I have been some places where a script repository was able to replace the purchased software and saved 100&#8217;s of thousands of dollars per year in software maintenance costs.</p>
<p>One of my favorite statements is that a &#8220;Senior DBA should be able to script his own solutions!&#8221; Being able to create monitoring scripts to replace that canned app will certainly get you to that next level. It will also get you out of that default behavior of complete reliance on the canned software and imminent career stagnation.</p>
<p>Learn a little and grow your career.</p>
<p>Oh, and there are some great monitoring tools out there. They can provide a great asset to a company &#8211; if and when used properly.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/07/saynoribbon.png"><img loading="lazy" class="aligncenter size-full wp-image-2768" src="http://jasonbrimhall.info/wp-content/uploads/2015/07/saynoribbon.png" alt="saynoribbon" width="250" height="301" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/07/saynoribbon.png 250w, https://jasonbrimhall.info/wp-content/uploads/2015/07/saynoribbon-249x300.png 249w, https://jasonbrimhall.info/wp-content/uploads/2015/07/saynoribbon-42x50.png 42w" sizes="(max-width: 250px) 85vw, 250px" /></a></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2766" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/07/14/sql-server-and-defaults/">SQL Server and Defaults</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/07/14/sql-server-and-defaults/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>PASS Summit 2015 &#8211; Guess What?</title>
		<link>https://jasonbrimhall.info/2015/07/13/pass-summit-2015-guess-what/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pass-summit-2015-guess-what</link>
					<comments>https://jasonbrimhall.info/2015/07/13/pass-summit-2015-guess-what/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 13 Jul 2015 18:14:51 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS SUMMIT]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2763</guid>

					<description><![CDATA[<p>Quick run the other way! PASS Summit will never be the same! Why? Well, because for the first time in the history of me, I have been selected to speak at such a prestigious event. Isn&#8217;t [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/07/13/pass-summit-2015-guess-what/">PASS Summit 2015 – Guess What?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Quick run the other way!</h3>
<p>PASS Summit will never be the same!</p>
<p>Why?</p>
<p>Well, because for the first time in the history of me, I have been selected to speak at such a prestigious event.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/07/Im-Speaking-Graphic_Large.png"><img loading="lazy" class="aligncenter size-full wp-image-2764" src="http://jasonbrimhall.info/wp-content/uploads/2015/07/Im-Speaking-Graphic_Large.png" alt="I'm Speaking Graphic_Large" width="600" height="315" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/07/Im-Speaking-Graphic_Large.png 600w, https://jasonbrimhall.info/wp-content/uploads/2015/07/Im-Speaking-Graphic_Large-300x158.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/07/Im-Speaking-Graphic_Large-50x26.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<h3>Isn&#8217;t that just crazy?</h3>
<p>In some ways it seems crazy. When I received the email I was exhilarated and completely astonished. I had hoped I would be selected, but did not entirely think it would happen this year.</p>
<p>I have to confess that I am honored to be one of the many to have been selected. This is really cool. You may be wondering why I am blogging about this opportunity soooo late after the speakers were announced. Well, the answer is rather straight forward. Life has been a bit crazy the past few weeks.</p>
<p>The last night of <a href="http://bit.ly/CruiseMed15">SQL Cruise</a> I received a phone call from my family letting me know that my grandfather had become fatally ill. I spent the next several days with him in the hospital until <a href="http://bit.ly/1IENm0T">he passed away a week later</a>. Then there were the holidays and the funeral. And to cap that off, I flew down to Phoenix to speak to the two user groups last week. SO, it has been a whirlwind!</p>
<p>All of that said, I am announcing it now and really am excited to be a apart of such an AWESOME event.</p>
<h3>Now for the surprise.</h3>
<p>When I discovered which session had been selected, I was very surprised. I expected one of my Extended Events sessions to be picked. Nope! Instead, one of my other fun sessions was picked. We will be talking about Compression in SQL Server at Summit.</p>
<p>I am hopeful we are able to make this an exciting and enjoyable session for the attendees. I hope the attendees will also be able to take the information home and be able to use it for better (or worse) in their environments.</p>
<p>I do hope to see many of you in attendance. On the agenda for the attendees in this session will be:</p>
<ol>
<li>Dive into functions available to help learn about compression</li>
<li>Evaluation of compression settings and possible savings</li>
<li>Dive into the Pages</li>
<li>A quick look at the CD and compressed data types</li>
<li>Levity</li>
</ol>
<p>Of course, I could just decide to change this on a whim &#8211; buahaha!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2763" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/07/13/pass-summit-2015-guess-what/">PASS Summit 2015 – Guess What?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/07/13/pass-summit-2015-guess-what/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>New Extended Events for 2016</title>
		<link>https://jasonbrimhall.info/2015/07/06/newxe2016/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=newxe2016</link>
					<comments>https://jasonbrimhall.info/2015/07/06/newxe2016/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 06 Jul 2015 12:47:51 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2753</guid>

					<description><![CDATA[<p>As we begin to get a grasp of all that is available with SQL Server 2016 and all of the new features, it is a great idea to see what else has been made available [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/07/06/newxe2016/">New Extended Events for 2016</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As we begin to get a grasp of all that is available with SQL Server 2016 and all of the new features, it is a great idea to see what else has been made available to us in order to help support and troubleshoot these new features. With that, it is well worth a look at the new changes to Extended Events to support all the shiny new stuff.</p>
<p>Here is a list of what I could find as of CTP 2 (I have yet to look at CTP 2.1). This list alone has some really cool stuff in it.  Browse through it and you will be able to find new stuff to help support and administer things like Stretch Database as well as JSON. You won&#8217;t find these events within Trace or profiler &#8211; only XE.</p>
<p>The presence of these new events (even some new ones for Query Store) is quite enough to get me excited for that next release of SQL Server. There is some great stuff coming down the pipe.</p>
<p>I have randomly highlighted some of the new events to support some of these new features. (And since this is only CTP 2.0, one can be sure there will be changes made to this list with the actual release of SQL Server 2016.)</p>
<table width="1131">
<tbody>
<tr>
<td width="221">SQLVersion</td>
<td width="462">EventName</td>
<td width="102">PackageName</td>
<td width="346">EventDescription</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">availability_replica_database_fault_reporting</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a database reports a fault to the availability replica manager which will trigger a replica restart if the database is critical</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">backup_restore_progress_trace</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Prints backup/restore progress trace messages with details</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">batchmode_sort_spill_file</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Record the spill file read/write information for batch mode sort</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">batchmode_sort_status</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Record batch mode sort status</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">cl_duration</td>
<td style="font-weight: 400;">XtpCompile</td>
<td style="font-weight: 400;" width="346">Reports the duration of the C compilation.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">clr_context_dump</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">ClrContextDump triggered.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">column_store_expression_filter_apply</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">An expression bitmap filter was applied on a rowgroup column batch.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">column_store_expression_filter_bitmap_set</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">An expression bitmap filter was set on a rowgroup column at rowgroup compile time.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_delete_buffer_closed_rowgroup_with_generationid_found</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Delete buffer can not be flushed due to existence of one or more closed rowgroups with generation ID.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_delete_buffer_flush_failed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Columnstore delete buffer flush failed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_delete_buffer_state_transition</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when closed delete buffer state changes.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_delta_rowgroup_closed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A delta rowgroup was closed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_no_rowgroup_qualified_for_merge</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A user invoked a REORG command but based on the policy, no rowgroup qualified.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_rowgroup_compressed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A compressed rowgroup was created.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_rowgroup_merge_complete</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A MERGE operation completed merging columnstore rowgroups together.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_rowgroup_merge_start</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A MERGE operation started merging columnstore rowgroups together.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_begin_delete_buffer_flush</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Columnstore tuple mover started flushing a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_compression_stats</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Statistics about the movement of a deltastore to a compressed rowgroup, including duration, size, etc.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_delete_buffer_flush_requirements_not_met</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when column store tuple mover was not able to acquire required locks for flushing a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_delete_buffer_truncate_requirements_not_met</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when column store tuple mover was not able to acquire required locks for truncating a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_delete_buffer_truncated</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Columnstore tuple mover truncated delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_delete_buffers_swapped</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Columnstore tuple mover swapped delete buffers.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_end_delete_buffer_flush</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Columnstore tuple mover completed flushing a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_met_requirements_for_delete_buffer_flush</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when column store tuple mover has acquired required locks and is ready to start flushing a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_tuple_mover_met_requirements_for_delete_buffer_truncate</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when column store tuple mover has acquired required locks and is ready to start truncating a delete buffer.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">columnstore_x_dbfl_acquired</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when X Delete Buffer Flush Lock is acquired.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">compressed_alter_column_is_md_only</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs during an alter column operation. Indicates whether the alter column is metadata only or not.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">connection_accept</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a new connection is accepted by (or duplicated into) the server. This event serves to log all connection attempts.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">connection_duplication_failure</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when connection duplication fails</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">data_purity_checks_for_dbcompat_130</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when an operation that may require a data purity check for dbcompat level 130 occurs.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">database_recovery_times</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Database recovery times</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">database_tde_encryption_scan_duration</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Database TDE Encryption Scan</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">database_transaction_yield</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a database transaction yields execution due to TDS buffer being full.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">ex_raise2</td>
<td style="font-weight: 400;">sqlos</td>
<td style="font-weight: 400;" width="346">Raised exception</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">fulltextlog_written</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Errorlog written</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">global_transaction</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when global transaction is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_db_log_throttle</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when DB log generation throttle changes.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_db_log_throttle_configuration_parameters</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when DB log generation throttle configuration parameters are read.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_db_log_throttle_input</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when HADR Fabric log management component updates log throttle.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_db_marked_for_reseed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a HADR secondary DB falls too far behind primary and is marked for reseed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_db_remote_harden_failure</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A harden request as part of a commit or prepare failed due to remote failure.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_log_block_send_complete</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs after a log block message has been sent. This event is only used for failpoints.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_partner_log_send_transition</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Log send transition between log writer and log capture.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_partner_restart_scan</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Restart partner scans for this partner.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_backup_state_change</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Backup Side State Change.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_failure</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Failure Event.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_forwarder_state_change</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Forwarder Side State Change.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_forwarder_target_state_change</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Forwarder Target Side State Change.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_progress</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Progress Event.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_restore_state_change</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Restore Side State Change.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_physical_seeding_submit_callback</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Physical Seeding Submit Callback Event.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_send_harden_lsn_message</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when we&#8217;re crafting a message to send containing a new hardened LSN on a secondary. Test only.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_configuration_state</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Indicates session state changes</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_dump_dropped_message</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Use this event to trace dropped HADR transport messages throughout the system.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_dump_failure_message</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Use this event to help trace HADR failure messages.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_dump_preconfig_message</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Use this event to help trace HADR preconfig messages.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_sync_send_failure</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Synchronous send failure in hadr transport.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">hadr_transport_ucs_registration</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports UCS registration state changes</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #00ff00;">json_depth_error</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when depth of json text being parsed is bigger than 128.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #00ff00;">json_parsing_error</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Indicates json parser error. Occurs when json format is not valid.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #00ff00;">json_stackoverflow_error</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Json parser stack overflow.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #00ff00;">json_unescaped_character</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Jsonparser hitted unescaped character in json string.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">log_pool_cache_miss</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a log consumer attempts to lookup a block from the log pool but fails to find it.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">log_pool_push_no_free_buffer</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when log pool push fails to get a free buffer and bails out.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">login_event</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">This is an abbreviated version of process_login_finish, containing only the columns required by external monitoring telemetry pipeline.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">notify_on_clr_disabled</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">Event_ClrDisabled has been triggered in ClrHost.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">on_app_domain_failure</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">AppDomain hit a failure.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">on_app_domain_unloading</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">AppDomain is unloading.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">on_host_policy_callback</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">IHostPolicyManager received an event.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">on_host_policy_failure</td>
<td style="font-weight: 400;">sqlclr</td>
<td style="font-weight: 400;" width="346">IHostPolicyManager received an event.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">page_cache_trace</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Modification of the page cache.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">premature_systemthread_wakeup</td>
<td style="font-weight: 400;">sqlos</td>
<td style="font-weight: 400;" width="346">system thread is woken up prematurely</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">private_login_accept</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">TDS connection accept event that is logged to private MDS table.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">private_login_finish</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">TDS login finish event that is logged to private MDS table.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">process_login_finish</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">This event is generated when server is done processing a login (success or failure).</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_execution_batch_filter</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when batch processing filters one batch using expression services.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_execution_batch_spill_started</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when batch operator runs out of granted memory and initiates spilling to disk of another partition of in-memory data.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_execution_column_store_rowgroup_scan_finished</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when row bucket processor finishes column store row group scan.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_execution_column_store_segment_scan_finished</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when row bucket processor finishes column store segment scan.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_execution_column_store_segment_scan_started</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when column segment scan starts.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_memory_grant_blocking</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a query is blocking other queries while waiting for memory grant</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_memory_grant_usage</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs at the end of query processing for queries with memory grant over 5MB to let users know about memory grant inaccuracies</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_background_task_persist_finished</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired if the background task for Query Store data persistence is completed successfully</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_background_task_persist_started</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired if the background task for Query Store data persistence started execution</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_capture_policy_abort_capture</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when an UNDECIDED query failed to transition to CAPTURED.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_capture_policy_evaluate</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when the capture policy is evaluated for a query.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_capture_policy_start_capture</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when an UNDECIDED query is transitioning to CAPTURED.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_db_data_structs_not_released</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired if Query Store data structures are not released when feature is turned OFF.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_db_diagnostics</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Periodically fired with Query Store diagnostics on database level.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_db_settings_changed</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when Query Store settings are changed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_db_whitelisting_changed</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when Query Store database whitelisting state is changed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_generate_showplan_failure</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when Query Store failed to store a query plan because the showplan generation failed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffcc00;">query_store_global_mem_obj_size_kb</span></td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Periodically fired with Query Store global memory object size.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_load_started</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when query store load is started</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_schema_consistency_check_failure</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when the QDS schema consistency check failed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_cleanup_finished</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when size retention policy clean-up task is finished.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_cleanup_skipped</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when starting of size retention policy clean-up task is skipped because its minimum repeating period did not pass yet.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_cleanup_started</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when size retention policy clean-up task is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_plan_cost</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when eviction cost is calculated for the plan.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_query_cost</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when query eviction cost is calculated for the query.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_store_size_retention_query_deleted</td>
<td style="font-weight: 400;">qds</td>
<td style="font-weight: 400;" width="346">Fired when size based retention policy deletes a query from Query Store.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">query_trace_column_values</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Trace output column values of each row on each query plan operator</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">recalculate_mem_target</td>
<td style="font-weight: 400;">sqlos</td>
<td style="font-weight: 400;" width="346">New Memory Targets which are set after RecalculateTarget is executed</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_db_ddl</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when the database T-SQL ddl for stretching data is processed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_provision_operation</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a provisioning operation starts or ends.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_query_rewrite</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when RelOp_Get is replaced during query rewrite for Stretch.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_table_ddl</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when the table T-SQL ddl for stretching data is processed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_telemetry</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs whenever an on premise system transmits a telemetry event to Azure DB.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">remote_data_archive_telemetry_rejected</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs whenever an AzureDB Stretch telemetry event is rejected</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">report_login_failure</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">This event is generated for a TDS login failure.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">rpc_starting_aggregate</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs periodically, aggregating all occasions an rpc call is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">rpc_starting_aggregate_xdb</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs periodically, aggregating all occasions an rpc call is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">sql_batch_starting_aggregate</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs periodically, aggregating all occasions a sql batch is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">sql_batch_starting_aggregate_xdb</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs periodically, aggregating all occasions a sql batch is started.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">startup_dependency_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs on the completion of a startup dependency in the SQL Server startup sequence</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_codegen_errorlog</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the output from the code generator</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_codegen_start</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of stretch code generation</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_create_migration_proc_start</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of migration procedure creation</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_create_remote_table_start</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of remote table creation</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_create_update_trigger_start</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of create update trigger for remote data archive table</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_database_disable_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of a ALTER DATABASE SET REMOTE_DATA_ARCHIVE OFF command</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_database_enable_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of a ALTER DATABASE SET REMOTE_DATA_ARCHIVE ON command</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_database_events_submitted</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion telemetry transfer</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_migration_debug_trace</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Debug trace of stretch migration actions.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_migration_queue_migration</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Queue a packet for starting migration of the database and object.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_migration_sp_stretch_get_batch_id</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Call sp_stretch_get_batch_id</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #ffff00;">stretch_migration_start_migration</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Start migration of the database and object.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_sync_metadata_start</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of metadata checks during the migration task.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_codegen_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of code generation for a stretched table</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_provisioning_step_duration</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the duration of a stretched table provisioning operation</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_remote_creation_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of remote execution for the generated code for a stretched table</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_row_migration_event</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of the migration of a batch of rows</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_row_migration_results_event</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports an error or completion of a successful migration of a number of batches of rows</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_unprovision_completed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion removal of local resources for a table that was unstretched</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_table_validation_error</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the completion of validation for a table when the user enables stretch</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">stretch_unprovision_table_start</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Reports the start of stretch table un-provisioning</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">trace_dump_deleted_object_table_row</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Dump deleted object table row</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">trust_verification_failed</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when a SQL Server binary fails Authenticode signature verification.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">ucs_negotiation_completion</td>
<td style="font-weight: 400;">ucs</td>
<td style="font-weight: 400;" width="346">UCS transport connection negotiation completed</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">unable_to_verify_trust</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs when SQL Server is unable to perform Authenticode signature verification on binaries.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_blob_properties_obtained</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Windows Azure Storage blob property is obtained from response header.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_failed_request</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Failed to complete a request to Windows Azure Storage.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_header_obtained</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Response header is obtained from request to Windows Azure Storage.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_read_complete</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Read complete from Windows Azure Storage response.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_request_opened</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">A request is opened to Windows Azure Storage.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_send_complete</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Request send to Windows Azure Storage is complete.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;"><span style="background-color: #cc99ff;">xio_write_complete</span></td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Request send to Windows Azure Storage is complete.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xstore_acquire_lease</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">The properties of the lease acquire reques.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xstore_create_file</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Creating an XStore file has been attempted with the options below.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xstore_debug_trace</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Telemetry tracing event has occurred.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xstore_lease_renewal_request</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Attempt to renew blob lease</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_alter_table</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs at start of XTP table altering.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_ckptctrl_abort_checkpoint</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the checkpoint close thread aborted a checkpoint.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_ckptctrl_close_checkpoint</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the checkpoint close thread hardened a checkpoint.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_ckptctrl_close_install_merge</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the checkpoint close thread installed a merge.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_ckptctrl_new_segment_definition</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the checkpoint controller processed a new segment definition.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_ckptctrl_storage_array_grow</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates the XTP storage array has grown in size.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_drop_table</td>
<td style="font-weight: 400;">sqlserver</td>
<td style="font-weight: 400;" width="346">Occurs after an XTP table has been dropped.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_merge_request_start</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that an XTP storage merge was requested.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_merge_request_stop</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that an XTP storage merge request ended.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_merge_start</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that an XTP storage merge range is starting.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_merge_stop</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that an XTP storage merge range completed.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_redo_log_corruption</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the redo process failed due to log corruption.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_root_file_deserialized</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the load of a checkpoint root file is complete.</td>
</tr>
<tr>
<td style="font-weight: 400;">Microsoft SQL Server 2016 (CTP2.0)</td>
<td style="font-weight: 400;">xtp_root_file_serialized</td>
<td style="font-weight: 400;">XtpEngine</td>
<td style="font-weight: 400;" width="346">Indicates that the write of the checkpoint root file is complete.</td>
</tr>
</tbody>
</table>
<p><strong>There you have it, currently 165 new events available to help monitor and troubleshoot SQL Server.</strong></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2753" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/07/06/newxe2016/">New Extended Events for 2016</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/07/06/newxe2016/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Database Drops in SQL 2012</title>
		<link>https://jasonbrimhall.info/2015/07/01/database-drops-in-sql-2012/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-drops-in-sql-2012</link>
					<comments>https://jasonbrimhall.info/2015/07/01/database-drops-in-sql-2012/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 01 Jul 2015 19:19:48 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2751</guid>

					<description><![CDATA[<p>In the previous article on this topic (which can be read here), I discussed the problem of having a database get dropped and the need to find out who dropped the database and when they dropped [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/07/01/database-drops-in-sql-2012/">Database Drops in SQL 2012</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the <a href="http://bit.ly/XEMissingDB">previous article</a> on this topic (which can be read here), I discussed the problem of having a database get dropped and the need to find out who dropped the database and when they dropped it.  In that article, I demonstrated how the information (at least some of it) could be found through the use of Extended Events.</p>
<p>What I forgot to mention is the method I shared was for SQL Server 2014. While the events do exist for SQL Server 2012, there is a minor modification that needs to be made in order to avoid the dreaded error message that says something like:</p>
<blockquote><p><span style="color: #ff0000;">Msg 25713, Level 16, State 23, Line 1</span><br />
<span style="color: #ff0000;">The value specified for event attribute or predicate source, &#8220;object_type&#8221;, event, &#8220;object_created&#8221;, is invalid.</span></p></blockquote>
<p>I am sure many of us would rather not have to deal with such a terrible thing as an error when we want to do something that should just work. Well, here is the fix for that error if you tried to deploy that XE Session to a previous version (such as 2012).</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

-- Create the Event Session
IF EXISTS(SELECT * 
 FROM sys.server_event_sessions 
 WHERE name='DBDeletedCreated')
 DROP EVENT SESSION DBDeletedCreated 
 ON SERVER;
GO
CREATE EVENT SESSION DBDeletedCreated
ON SERVER
ADD EVENT sqlserver.object_created (
 SET collect_database_name = (1)
 ACTION(sqlserver.nt_username,sqlserver.session_id,sqlserver.client_hostname,sqlserver.client_app_name,sqlserver.sql_text)
WHERE object_type = 16964 -- 'DATABASE'

 ),
ADD EVENT sqlserver.object_deleted(
 SET collect_database_name = (1)
 ACTION(sqlserver.nt_username,sqlserver.session_id,sqlserver.client_hostname,sqlserver.client_app_name,sqlserver.sql_text)
WHERE object_type = 16964 -- 'DATABASE'
)
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\DBDeletedCreated.xel')

/* start the session */
ALTER EVENT SESSION DBDeletedCreated 
ON SERVER 
STATE = START;
GO</pre><p>Do you see that change? Instead of using the map_value in 2012, one must use  the map_key. This was a good change in 2014 to allow us to use human friendly terms instead of needing to lookup the map_key for everything like in 2012.</p>
<p>In following the theme from the previous article, here is the rest of the setup for testing this XEvent session to see how it would trap that data and how to parse the data from the session.</p>
<p><strong>Enjoy!</strong></p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE DATABASE XETestDB;
GO

DROP DATABASE XETestDB;
GO</pre><p>Nice and simple for a test. This should be enough to have trapped some data for our XEvent session.  Let&#8217;s parse the data and take a look.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO

SELECT
event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
	,event_data.value('(event/data[@name="database_name"]/value)[1]', 'varchar(max)') AS DBName
	,event_data.value('(event/data[@name="object_name"]/value)[1]', 'varchar(max)') AS ObjName
	,CASE event_data.value('(event/data[@name="ddl_phase"]/value)[1]', 'varchar(max)')
		WHEN 0 THEN 'BEGIN'
			WHEN 1 THEN 'COMMIT'
			WHEN 2 THEN 'ROLLBACK'
			END AS DDLPhase
	,event_data.value('(event/data[@name="object_type"]/value)[1]', 'varchar(max)') AS ObjType
	,event_data.value('(event/data[@name="transaction_id"]/value)[1]', 'varchar(max)') AS XactID
	,event_data.value('(event/action[@name="session_id"]/value)[1]', 'varchar(max)') AS SessionID
	,event_data.value('(event/action[@name="nt_username"]/value)[1]', 'varchar(max)') AS ExecUser
	,CONVERT(XML,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') )AS sql_text,
	event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'varchar(max)') AS Client_AppName
FROM(
SELECT CONVERT(XML, t2.event_data) AS event_data
 FROM (
  SELECT target_data = convert(XML, target_data)
   FROM sys.dm_xe_session_targets t
    INNER JOIN sys.dm_xe_sessions s 
        ON t.event_session_address = s.address
   WHERE t.target_name = 'event_file'
    AND s.name = 'DBDeletedCreated') cte1
   CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent(FileTarget)
   CROSS APPLY  sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name', 'varchar(1000)'), NULL, NULL, NULL) t2)
    AS evts(event_data)
ORDER BY event_data.value('(event/@timestamp)[1]', 'varchar(50)');</pre><p>With the XEvent session started, and a database that has been created and dropped, this last query will produce some data to help track who has been adding or removing databases from your SQL Instance.  If you have run the example code, you should see data very similar to what is shown in this next image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results.png"><img loading="lazy" class="aligncenter size-large wp-image-2660" src="http://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results-1024x173.png" alt="xe_results" width="560" height="95" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results-1024x173.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results-300x51.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/04/xe_results.png 1725w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>In the attached image, I have separated the pair of statements for the DB create from the pair of statements for the DB drop (recall that I mentioned each will fire twice).  I hope this serves you well in your attempts to reign in the control of your environment and discover who may be creating rogue databases or even dropping the databases that are essential to the business.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2751" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/07/01/database-drops-in-sql-2012/">Database Drops in SQL 2012</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/07/01/database-drops-in-sql-2012/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Cruise Mediterranean+</title>
		<link>https://jasonbrimhall.info/2015/06/24/sql-cruise-mediterranean/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-cruise-mediterranean</link>
					<comments>https://jasonbrimhall.info/2015/06/24/sql-cruise-mediterranean/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 24 Jun 2015 12:30:58 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2738</guid>

					<description><![CDATA[<p>This is a post that is looooong overdue. I have intended to write some of this at least since the first SQL Cruise I attended back in 2013 (in the Caribbean). Now with three Cruises [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/06/24/sql-cruise-mediterranean/">SQL Cruise Mediterranean+</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is a post that is looooong overdue. I have intended to write some of this at least since the first <a href="http://sqlcruise.com/">SQL Cruise</a> I attended back in 2013 (in the Caribbean). Now with three Cruises under the belt and plenty of awesome experiences, it is high time to follow through on those intentions.</p>
<p><a href="http://sqlcruise.com"><img loading="lazy" class="alignleft wp-image-2741 size-thumbnail" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015-150x150.png" alt="Official_SQLCruise_2015" width="150" height="150" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015-1024x1024.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015-50x50.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Official_SQLCruise_2015.png 1100w" sizes="(max-width: 150px) 85vw, 150px" /></a>For those that have not heard, SQL Cruise is a mix of training and vacation. You get a little (or a lot) of SQL and then you get a little (or a lot) of vacation mixed with the opportunity to see places you may not have otherwise visited. Last but certainly not least is the opportunity afforded to all attendees to meet other people they may have never otherwise gotten a chance to meet. This last benefit may be the most important facet of SQL Cruise in that the networking done during the cruise will last a long time and can certainly open a few doors if/when necessary.</p>
<p>One great example of this networking occurred on the first cruise I attended. In the meetings outside of the scheduled training, one of the other cruisers (he is now an MCM and MVP) asked a pretty important question about an issue within his work environment. A performance monitoring package they ran for all of their clients was causing some serious problems. The problems affected about 30% of all of the servers which numbered over 1500. The application on the affected servers would stop responding and they would no longer receive metrics or alerts to conditions being raised.</p>
<p>This problem was significant enough that they engaged Microsoft and Microsoft engineers had been collecting metrics and logs for over six months (at the time). There was a series of try this and try that and all of it resulted in no change whatsoever. So this fellow cruiser brought the issue to the cruise with him. In chatting with the cruiser (oh, and he had to fly to the US from Europe in order to attend), I discovered that the symptoms he was enduring were quite similar to some things I had seen within SSIS packages for example. We discussed a quick fix which he took back to his employer.</p>
<p>Through a series of tests and deployments, this Cruiser and his employer rolled out the fix to all of the servers in the environment. This fix ended up saving them so much money in labor and other costs, that his employer sent him and his family (eight people in total) back to SQL Cruise in the Caribbean the following year. The ROI for this Cruiser and his employer was huge! Additionally, he and I have become friends thanks to the Cruise. This is the sort of stuff that defines SQL Cruise.</p>
<p>This year, we had the chance to repeat the Cruise by attending the Mediterranean version. This installment was a whirlwind of touring Europe. Some started in London before proceeding to Barcelona and then on to such places as Pompeii, Rome, Pisa, Cannes, Monaco, and Mallorica before returning to Barcelona to continue on to Berlin or London before returning home. For me, we chose to start in Paris and then taking the bullet train on to Barcelona.</p>
<p><img loading="lazy" class="aligncenter wp-image-2745 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/20150620_2108571-1024x576.jpg" alt="Med Sunset" width="560" height="315" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/20150620_2108571-1024x576.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/20150620_2108571-300x169.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/20150620_2108571-50x28.jpg 50w" sizes="(max-width: 560px) 85vw, 560px" /></p>
<p>The tourism was fast and furious. The training was faster and more furious. And in the end, the European / Mediterranean trip was gone before we knew it. All who attended surely walked away with great memories and with having learned something (whether it be cultural, historic, or SQL in nature).</p>
<p>If you have the chance to attend a SQL Cruise, I would say do it. The training comes from the technical leads as well as the attendees in the rooms. Often, the tech lead will even defer to any of the other professionals in attendance. Especially in the case of Trace Flags as we learned this past week &#8211; in every session and in every office hours meeting. Just ask Grant Fritchey (<a href="http://www.scarydba.com/">blog </a>| <a href="https://twitter.com/GFritchey">twitter</a>) about it some time &#8211; he <em>loves</em> talking about Trace Flags.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2738" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/06/24/sql-cruise-mediterranean/">SQL Cruise Mediterranean+</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/06/24/sql-cruise-mediterranean/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Reading Extended Event File Session Data</title>
		<link>https://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reading-extended-event-file-session-data</link>
					<comments>https://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sun, 21 Jun 2015 11:27:35 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2719</guid>

					<description><![CDATA[<p>Using Extended Events to trap/trace information allows the trapping of that information to various targets. One of the targets I will frequently tell people to use is the file target. The reasoning for this is the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/">Reading Extended Event File Session Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Using Extended Events to trap/trace information allows the trapping of that information to various targets. One of the targets I will frequently tell people to use is the file target. The reasoning for this is the opportunity this affords to be able to review the output  at a later time whether the event session is running or not.</p>
<p>Along  with that recommendation, I also show some quick code to pull the data back from the session target (the file on disk). This code is written to dynamically pull the file information out of the XE Dynamic Management Views to make it a little easier on the user (and a bit less likely to have a typo). That code looks a bit like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    CAST(event_data.value('(event/action[@name="plan_handle"]/value)[1]', 'varchar(max)') AS XML) as plan_handle,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	,xmlplan.query('.') AS plan_xml
 	FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data--,xmlplan.query('.') AS event_plan
				FROM ( SELECT target_data = CONVERT(XML, target_data)
							FROM sys.dm_xe_session_targets t
								INNER JOIN sys.dm_xe_sessions s
									ON t.event_session_address = s.address
							WHERE t.target_name = 'event_file'
								AND s.name = 'TrapEstExecPlans'
						) cte1
					CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget )
					CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name',
																'varchar(1000)'),
																NULL, NULL, NULL) t2
			) AS evts ( event_data )
			CROSS APPLY event_data.nodes('(event/data[@name="showplan_xml"]/value)[last()]/*') AS showplan(xmlplan);</pre><p>This works really well when the session is running. It pulls the desired file path and name back from the DMVs and one is able to parse the session data. But what if that session is stopped?</p>
<p>Well, if the session is stopped, we have a problem. With a stopped session, the session above will not produce any results. The short of this is that SQL Server removes the entries from the <em>sys.dm_xe_session_targets</em> and <em>sys.dm_xe_sessions</em> DMVs. Due to that, there is a bit of a tweak to be able to query those files for the sessions that have been stopped.</p>
<p>To query those files, one could rewrite the previous query to something like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT evts.*, xmlplan.query('.') AS plan_xml 
INTO #parseevent
FROM (
SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM sys.fn_xe_file_target_read_file('C:\Database\XE\TrapEstExecPlans*.xel',
																NULL, NULL, NULL) t2
			) AS evts ( event_data )
			CROSS APPLY event_data.nodes('(event/data[@name="showplan_xml"]/value)[last()]/*') AS showplan(xmlplan)

SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    CAST(event_data.value('(event/action[@name="plan_handle"]/value)[1]', 'varchar(max)') AS XML) as plan_handle,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text,
	CAST(pe.event_data.value('(event/action[@name="query_hash"]/value)[1]', 'varchar(max)') AS XML) AS statementlevel_query_hash 
	,pe.plan_xml AS plan_xml
 	FROM #parseevent pe;

DROP TABLE #parseevent;</pre><p>Now, I bet you may be asking why stop an Extended Event session from running. Afterall, extended events is extremely light weight and has little impact on the server, right? True that may be, there is still a cost for traces. If you can just run a trace for a targeted time period, then why not limit the amount of tracing?</p>
<p>Looking at the code, you can see that I reverted to a less dynamic approach to read those event files. Instead of trying to get that info direct from the database, I am just telling SQL Server where to find the files on disk (note the filepath that is passed).</p>
<p>There you have it. A means to query these trace files whether the XE trace is running or stopped.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2719" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/">Reading Extended Event File Session Data</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/06/21/reading-extended-event-file-session-data/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Execution Plans in Extended Events</title>
		<link>https://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=execution-plans-in-extended-events</link>
					<comments>https://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 17 Jun 2015 12:00:56 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2713</guid>

					<description><![CDATA[<p>Extended Events is a wonderful tool. Execution Plans are also some wonderful things &#8211; or are a wonderful tool as well. Both of these tools are fantastic for troubleshooting. Combined, they can potentially be even better. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/">Execution Plans in Extended Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Extended Events is a wonderful tool. Execution Plans are also some wonderful things &#8211; or are a wonderful tool as well. Both of these tools are fantastic for troubleshooting. Combined, they can potentially be even better.</p>
<p>Or, they could just cause some hair loss and be a fairly complicated pain in your butt. Hopefully the combination of the two will be more useful than painful for you. And today, I will discuss one of the pains that could be an issue when combining these two tools. I will also discuss some options for getting around this pain point between XE and Execution Plans.</p>
<p>Let&#8217;s start by taking a quick look at two Extended Events events that can expose execution plans for you. These two events are <em>query_pre_execution_showplan</em> and <em>query_post_execution_showplan. </em>Here are a couple sample sessions set to trap these events.</p><pre class="urvanov-syntax-highlighter-plain-tag">IF EXISTS(SELECT * 
          FROM sys.server_event_sessions 
          WHERE name='TrapEstExecPlans')
    DROP EVENT SESSION TrapEstExecPlans 
    ON SERVER;
GO
CREATE EVENT SESSION TrapEstExecPlans
ON SERVER
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* The pre_execution_showplan event will trap estimated plan */
--ADD EVENT sqlserver.query_pre_execution_showplan,
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ADD EVENT sqlserver.query_pre_execution_showplan(
    ACTION (sqlserver.database_name,sqlserver.client_hostname,sqlserver.client_app_name,
            sqlserver.plan_handle,
            sqlserver.sql_text,
            sqlserver.tsql_stack,
            package0.callstack,
			sqlserver.query_hash,
			sqlserver.session_id,
            sqlserver.request_id)
 
--Change this to match the AdventureWorks, 
--AdventureWorks2008 or AdventureWorks2012 DB_ID()
WHERE sqlserver.database_id=9
	AND sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
)
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\TrapEstExecPlans.xel',max_file_size=(5),max_rollover_files=(4)),
ADD TARGET package0.ring_buffer
WITH (MAX_DISPATCH_LATENCY=5SECONDS, TRACK_CAUSALITY=ON)
GO</pre><p>And&#8230;</p><pre class="urvanov-syntax-highlighter-plain-tag">IF EXISTS(SELECT * 
          FROM sys.server_event_sessions 
          WHERE name='TrapExecPlans')
    DROP EVENT SESSION TrapExecPlans 
    ON SERVER;
GO
CREATE EVENT SESSION TrapExecPlans
ON SERVER
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* The pre_execution_showplan event will trap estimated plan */
--ADD EVENT sqlserver.query_pre_execution_showplan,
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ADD EVENT sqlserver.query_post_execution_showplan(
    ACTION (sqlserver.database_name,sqlserver.client_hostname,sqlserver.client_app_name,
            sqlserver.plan_handle,
            sqlserver.sql_text,
            sqlserver.tsql_stack,
            package0.callstack,
			sqlserver.query_hash,
			sqlserver.session_id,
            sqlserver.request_id)
 
--Change this to match the AdventureWorks, 
--AdventureWorks2008 or AdventureWorks2012 DB_ID()
WHERE sqlserver.database_id=9
	AND sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
)
ADD TARGET package0.event_file(SET filename=N'C:\Database\XE\TrapExecPlans.xel',max_file_size=(5),max_rollover_files=(4)),
ADD TARGET package0.ring_buffer
WITH (MAX_DISPATCH_LATENCY=5SECONDS, TRACK_CAUSALITY=ON)
GO</pre><p>With these sample sessions ready, we need a quick description of what is happening. I have built the sessions (at least the TrapEstExecPlans session) to go to both a file and the ringbuffer targets. This was done to test the behavior on both targets to ensure consistency in behavior between the different targets.</p>
<p>Also, I added a bunch of actions that are available to query, but the sample queries shown later will not use the data for those actions. This is only due to the examples I have chosen to share.</p>
<p>With those sessions created, go ahead and start them, then run a query like the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdventureWorks2012; --whatever your database id 9 is
GO
SELECT *
	FROM sys.allocation_units;</pre><p>After  having executed this query, I can start taking a look at the data captured. I will only query the TrapEstExecPlans session in this post because the behavior between the two sessions and events is consistent.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    CAST(event_data.value('(event/action[@name="plan_handle"]/value)[1]', 'varchar(max)') AS XML) as plan_handle,
    event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	--,CAST(REPLACE(REPLACE(CAST(planxml.query('.') AS VARCHAR(MAX)),'&lt;value&gt;',''),'&lt;/value&gt;','') AS XML) AS plan_xml
	,planxml.query('.') AS plan_xml
FROM(    SELECT evnt.query('.') AS event_data,xmlplan.query('.') AS event_plan
        FROM
        (    SELECT CAST(target_data AS xml) AS TargetData
            FROM sys.dm_xe_sessions AS s
            INNER JOIN sys.dm_xe_session_targets AS t
                ON s.address = t.event_session_address
            WHERE s.name = 'TrapEstExecPlans'
              AND t.target_name = 'ring_buffer'
        ) AS tab
        CROSS APPLY TargetData.nodes ('RingBufferTarget/event') AS split(evnt) 
		CROSS APPLY evnt.nodes('(data[@name="showplan_xml"]/value)[last()]/*') AS showplan(xmlplan)
    ) AS evts(event_data,planxml)
	;</pre><p>Keep in mind that I talked about having both a ringbuffer and a file target for this session. I am only going to share the query from the ringbuffer target because the behavior from the memory target and the filetarget is the same.</p>
<p>If I take a look at the execution plans shared from the results of that query, I might see something like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe.png"><img loading="lazy" class="aligncenter wp-image-2714 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe-1024x198.png" alt="Plan from XE" width="560" height="108" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe-1024x198.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe-300x58.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe-50x10.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/planfromxe.png 1693w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>If I look at the execution plan at runtime for that same query, I would see something like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/execplan.png"><img loading="lazy" class="aligncenter size-large wp-image-2715" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/execplan-1024x314.png" alt="Exec Plan" width="560" height="172" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/execplan-1024x314.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/execplan-300x92.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/execplan-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/execplan.png 1652w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Between the two plans, I have color coded the various attributes of the plan to pair the matching attributes and make it easier to spot the differences. In this case, the differences are in the first two nodes. The plan from Extended Events does not have the connection properties, but is also missing a few other important things like the StatementType and StatementText. Looking at the plan from XE in the gui, you would see something like this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan.png"><img loading="lazy" class="aligncenter size-large wp-image-2717" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan-1024x411.png" alt="XE-plan" width="560" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan-1024x411.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan-300x120.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan-50x20.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/XE-plan.png 1482w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Instead of this:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic.png"><img loading="lazy" class="aligncenter size-large wp-image-2716" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic-1024x347.png" alt="Execplan_graphic" width="560" height="190" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic-1024x347.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic-300x102.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic-50x17.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/Execplan_graphic.png 1690w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Those minor differences in the XML of the execution plans can lead to somewhat of a pain. Alas, there is a fix for that. And the fix comes down to doing one of a few things already available to us in the XE session data. We can either lookup the plan_handle that was trapped by the action, or we can lookup the QueryPlanHash that is available in the XML from the execution plan data that has been trapped. With that information, one can <em>likely</em> retrieve the stored execution plan and catch the rest of the missing components of that execution plan.</p>
<p>There is one other option and that is the action that traps the sql_text. The sql_text that is captured can lead us to understand what kind of plan (select, update, delete, etc) we are looking at from the XE session data.</p>
<p>So, while it is a bit of a nuisance that the two sources of execution plans does not produce the same plan, it is not the end of the world. There is still adequate information available from the XE session data to figure out the missing pieces of the execution plan.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2713" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/">Execution Plans in Extended Events</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/06/17/execution-plans-in-extended-events/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Extended Events, Birkenstocks and SQL Server</title>
		<link>https://jasonbrimhall.info/2015/06/09/birkenstockxevents/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=birkenstockxevents</link>
					<comments>https://jasonbrimhall.info/2015/06/09/birkenstockxevents/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 10 Jun 2015 01:42:48 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[performance tune]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2688</guid>

					<description><![CDATA[<p>I bring you yet another installment in the monthly meme called T-SQL Tuesday.  This is the 67th edition, and this time we have been given the opportunity to talk about something I really enjoy &#8211; [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/06/09/birkenstockxevents/">Extended Events, Birkenstocks and SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://blogs.lessthandot.com/index.php/uncategorized/youre-invited-to-t-sql-tuesday-67-extended-events/"><img loading="lazy" class="alignright wp-image-2309 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL Tuesday" width="150" height="150" /></a></p>
<p class="instapaper_ignore">I bring you yet another installment in the monthly meme called T-SQL Tuesday.  This is the 67th edition, and this time we have been given the opportunity to talk about something I <strong><em>really</em> </strong>enjoy &#8211; Extended Events.</p>
<p class="instapaper_ignore">Props to Jes Borland (<a href="http://blogs.lessthandot.com/author/jes-borland" class="broken_link">blog </a>| <a href="http://twitter.com/grrl_geek">twitter</a>) for picking such an awesome topic. There is so much to cover with extended events, it&#8217;s like a green canvas ready for anything you can imagine.</p>
<h3 class="instapaper_ignore">Birkenstocks?</h3>
<p><img loading="lazy" class=" size-medium wp-image-2689 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/birkentstocks-300x241.png" alt="birkentstocks" width="300" height="241" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/birkentstocks-300x241.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/birkentstocks-1024x824.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/birkentstocks-50x40.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/birkentstocks.png 1112w" sizes="(max-width: 300px) 85vw, 300px" /></p>
<p>I will save the explanation here for later when hopefully it all ties together for you (well, at least buckles up).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/treehugger.png"><img loading="lazy" class="aligncenter size-medium wp-image-2690" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/treehugger-176x300.png" alt="treehugger" width="176" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/treehugger-176x300.png 176w, https://jasonbrimhall.info/wp-content/uploads/2015/06/treehugger-29x50.png 29w, https://jasonbrimhall.info/wp-content/uploads/2015/06/treehugger.png 210w" sizes="(max-width: 176px) 85vw, 176px" /></a></p>
<p>While that is all fun and playful, let&#8217;s get down to the serious side now. One of my favorite quick fixes as a consultant is to come in and find that the server is set to &#8220;environment friendly&#8221; / &#8220;green&#8221; / &#8220;treehugger&#8221; mode. You can read more about power saving cpus from my friend Wayne Sheffield <a href="http://bit.ly/SSGGreenCPU">here</a>.</p>
<p>That poor old cpu thing has been beat up pretty good. But how can we tell if the server is running in that mode if the only thing we can do is look in SQL Server (can&#8217;t install cpu-z, or don&#8217;t have adequate permissions on the server to see windows settings &#8211; just play along)? Lucky for us there is this cool thing called Extended Events.</p>
<p>In SQL Server we have this cool event called perfobject_processor. This particular event has some really cool metrics that it captures.  One such metric is the frequency. The frequency is an indicator to us whether the server has the cpu set to balanced, high performance, or power saver. Having that in mind, let&#8217;s create a session to trap this data and experiment a little with the cpu settings.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO
-- Create the Event Session
IF EXISTS ( SELECT *
				FROM sys.server_event_sessions
				WHERE name = 'TreeHuggerCPU' )
	DROP EVENT SESSION TreeHuggerCPU 
    ON SERVER;
GO

EXECUTE xp_create_subdir 'C:\Database\XE';
GO

CREATE EVENT SESSION TreeHuggerCPU ON SERVER
ADD EVENT sqlserver.perfobject_processor (
	ACTION ( sqlos.cpu_id, sqlos.numa_node_id, package0.collect_cpu_cycle_time,
	sqlserver.server_instance_name,
	package0.collect_system_time ) --WHERE sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense'
	)
ADD TARGET package0.event_file ( SET filename = N'C:\Database\XE\TreeHuggerCPU.xel' );

/* start the session */
ALTER EVENT SESSION TreeHuggerCPU 
ON SERVER 
STATE = START;
GO</pre><p>Well, that looks amazingly easy and straight forward. I am telling the session to trap the additional CPU information such as numa_node_id and cpu_id. You can eliminate those if you wish. They may be beneficial when trying to identify if there is an issue on a specific processor though.</p>
<p>To experiment, I will break out the age old argument provoker &#8211; xp_cmdshell. I will use that to cycle through each of the power saving settings and look at the results. Here is the bulk of the script all together.</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_configure 'xp_cmdshell', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO

 --max power saving
EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_MAX';
GO
--now look at the XE
 --balanced power saving
EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_BALANCED';
--now look at the XE
--min power saving
EXECUTE xp_cmdshell 'powercfg -SETACTIVE SCHEME_MIN'; 
--now look at the XE</pre><p>And now for the XE Parser.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE master;
GO

SELECT event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
		, event_data.value('(event/@timestamp)[1]', 'varchar(50)') AS [TIMESTAMP]
		, event_data.value('(event/action[@name="server_instance_name"]/value)[1]',
							'varchar(max)') AS ServerInstance
		, event_data.value('(event/action[@name="numa_node_id"]/value)[1]',
							'varchar(max)') AS NUMANodeID
		, event_data.value('(event/action[@name="cpu_id"]/value)[1]',
							'varchar(max)') AS CPUID
		, event_data.value('(event/action[@name="collect_cpu_cycle_time"]/value)[1]',
							'varchar(max)') AS CPUCycleTime
		, event_data.value('(event/action[@name="collect_system_time"]/value)[1]',
							'varchar(max)') AS SystemTime
		, event_data.value('(event/data[@name="parking_status"]/value)[1]',
							'varchar(max)') AS ProcessorParkStatus
		, event_data.value('(event/data[@name="processor_frequency"]/value)[1]',
							'varchar(max)') AS ProcessorFrequency
		, event_data.value('(event/data[@name="percent_maximum_frequency"]/value)[1]',
							'varchar(max)') AS PercentMaxProcessorFrequency
		, event_data.value('(event/data[@name="processor_state_flags"]/value)[1]',
							'varchar(max)') AS ProcessorState
		, event_data.value('(event/data[@name="instance_name"]/value)[1]',
							'varchar(max)') AS CPUInstance
	FROM ( SELECT CONVERT(XML, t2.event_data) AS event_data
				FROM ( SELECT target_data = CONVERT(XML, target_data)
							FROM sys.dm_xe_session_targets t
								INNER JOIN sys.dm_xe_sessions s
									ON t.event_session_address = s.address
							WHERE t.target_name = 'event_file'
								AND s.name = 'TreeHuggerCPU'
						) cte1
					CROSS APPLY cte1.target_data.nodes('//EventFileTarget/File') FileEvent ( FileTarget )
					CROSS APPLY sys.fn_xe_file_target_read_file(FileEvent.FileTarget.value('@name',
																'varchar(1000)'),
																NULL, NULL, NULL) t2
			) AS evts ( event_data );</pre><p>If I parse through the extended event after each change of the power scheme, I would be able to see the effect of each scheme change in the event session as well as in a tool such as Resource Monitor. Here is what I was able to see with each of the changes.</p>
<h4>Balanced Saver</h4>
<p>From Resource Monitor:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu.png"><img loading="lazy" class=" size-medium wp-image-2691 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu-300x87.png" alt="balanced_cpu" width="300" height="87" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu-300x87.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu-1024x298.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_cpu.png 1455w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>And the XE data:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results.png"><img loading="lazy" class="aligncenter size-medium wp-image-2692" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results-300x70.png" alt="balanced_results" width="300" height="70" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results-300x70.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results-1024x239.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results-50x12.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/balanced_results.png 1318w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>This is my default power scheme. On my laptop, this is ok. For a production SQL server, this will cause problems.</p>
<h4>High Performance</h4>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower.png"><img loading="lazy" class="aligncenter size-medium wp-image-2693" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower-300x87.png" alt="fullpower" width="300" height="87" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower-300x87.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower-1024x298.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower.png 1474w" sizes="(max-width: 300px) 85vw, 300px" /></a> <a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results.png"><img loading="lazy" class="aligncenter size-medium wp-image-2694" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results-300x48.png" alt="fullpower_results" width="300" height="48" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results-300x48.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results-1024x165.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/fullpower_results.png 1325w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>Quickly, you should be able to spot that the blue line in the graph, and the numeric values from the XE session correlate to the processor giving you everything it has. This is good for SQL Server.</p>
<h4>Power Saver</h4>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu.png"><img loading="lazy" class="aligncenter size-medium wp-image-2695" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu-300x85.png" alt="powersaver_cpu" width="300" height="85" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu-300x85.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu-1024x290.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu-50x14.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_cpu.png 1488w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>See how that blue line falls off sharply?</p>
<p>&nbsp;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results.png"><img loading="lazy" class="aligncenter size-medium wp-image-2696" src="http://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results-300x60.png" alt="powersaver_results" width="300" height="60" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results-300x60.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results-1024x203.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results-50x10.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/06/powersaver_results.png 1330w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>&nbsp;</p>
<p>Supporting that steep fall in the graph, we can see that the XE trapped the percent of max frequency as 36%. You might be lucky and attain 36%. Don&#8217;t be surprised if you see something even lower. Please don&#8217;t use this setting on a production box &#8211; unless you want to go bald.</p>
<p>We can see that we have great tools via Extended Events to help troubleshoot various problems. As I said, this is one of my favorites because it is a very common problem and a very easy fix.</p>
<p>SQL Server is not GREEN! Do not put birkenstocks on the server and try to turn the server into a tree hugger. It just won&#8217;t work out that well. Set your fileservers or your print servers to be more power conscientious, but this is something that will not work well on SQL Server.</p>
<p>Final thought. If you have not figured out the birkenstocks, well it is a common stereotype with environmentalists in some areas that they may wear woolly socks and birkenstocks.</p>
<p>No wool socks were harmed in the making of this blog post!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2688" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/06/09/birkenstockxevents/">Extended Events, Birkenstocks and SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/06/09/birkenstockxevents/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Monitoring SQL Server</title>
		<link>https://jasonbrimhall.info/2015/05/12/monitoring-sql-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=monitoring-sql-server</link>
					<comments>https://jasonbrimhall.info/2015/05/12/monitoring-sql-server/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 May 2015 21:00:18 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2668</guid>

					<description><![CDATA[<p>Welcome to the fabulous world of blog parties, SQL Server and what has been the longest running SQL Server related meme in the blogosphere &#8211; TSQLTuesday. This month we are hosted by Catherine Wilhemsen (blog [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/05/12/monitoring-sql-server/">Monitoring SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.cathrinewilhelmsen.net/2015/05/05/invitation-to-t-sql-tuesday-66-monitoring/"><img loading="lazy" class=" size-full wp-image-2309 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL2sDay150x150" width="150" height="150" /></a>Welcome to the fabulous world of blog parties, SQL Server and what has been the longest running SQL Server related meme in the blogosphere &#8211; TSQLTuesday.</p>
<p>This month we are hosted by Catherine Wilhemsen (<a href="http://www.cathrinewilhelmsen.net/">blog </a>| <a href="https://twitter.com/cathrinew">twitter</a>) from Norway. And interestingly, Catherine has asked for us to talk about monitoring SQL Server.  Wow! Talk about a HUGE topic to cover in such a short space. Well, let&#8217;s give it a go.</p>
<p>I am going to try and take this in a bit of a different direction, and we shall see if I have any success with it or not.</p>
<h3>Direction the First</h3>
<p>Monitoring is a pretty important piece of the database puzzle. Why? Well, because you want to try and find out before the end-users that something is happening. Or do you? It is a well established practice at many shops to allow the end-users to be the monitoring solution. How does this work, you ask?</p>
<p>It works, by waiting for an end-user to experience an error or some unexpected slowness. Then the user will either call you (the DBA), your manager, the company CEO, or (if you are lucky) the helpdesk. Then, the user will impatiently wait for you to try and figure out what the problem is.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/05/eyeball_monitor.png"><img loading="lazy" class="alignright wp-image-2670" title="Eyeball Monitoring" src="http://jasonbrimhall.info/wp-content/uploads/2015/05/eyeball_monitor-290x300.png" alt="" width="190" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/05/eyeball_monitor-290x300.png 290w, https://jasonbrimhall.info/wp-content/uploads/2015/05/eyeball_monitor-48x50.png 48w, https://jasonbrimhall.info/wp-content/uploads/2015/05/eyeball_monitor.png 417w" sizes="(max-width: 190px) 85vw, 190px" /></a>The pros to this solution involve a much lower cost to implementation.  The cons, well we won&#8217;t talk about that because I am trying to sell you on this idea. No, in all seriousness, the con to this approach could involve a lot of dissatisfaction, job loss, outages, delays in processing, delays in paychecks, dizziness, fainting, shortness of breath, brain tumors, and rectal bleeding.  Oh wait, those last few are more closely related to trial medications for &lt;insert ailment here&gt;.</p>
<p>If you are inclined to pursue this type of monitoring &#8211; may all the hope, prayers, faith and luck be on your side that problems do not occur.</p>
<h3>New Direction</h3>
<p>This methodology is also rather cheap to implementation.  The risk is relatively high as well and I have indeed seen this implementation. In this new approach, we will require that the DBA eyeball monitor the databases all day and all night.</p>
<p>At the DBA&#8217;s disposal is whatever is currently available in SQL Server to perform the monitoring.  It is preferred that only Activity Monitor and Profiler be used to perform these duties. However, the use of sp_who2 and the DMVs is acceptable for this type of duty.</p>
<p>The upside to this is that you do not incur any additional cost for monitoring over what has been allocated for the salary of the DBA. This an easy and quick implementation and requires little knowledge transfer or ability.</p>
<p>The downside here is &#8211; well &#8211; look at the problems from the last section and then add the glassed over stoner look of the 80s from staring at the monitor all day.</p>
<p>If you have not had the opportunity to use this type of monitoring &#8211; consider how lucky you are.  This has been mandated by several companies (yes I have witnessed that mandate).</p>
<h3>Pick your Poison</h3>
<p>Now we come to a multi-forked path.  Every path at this level leads to a different tool set.  All of these tools bare different costs and different levels of knowledge.</p>
<p>The pro here is that these come with lower risk to those suspicious symptoms from the previous two options. The con is that it will require a little bit more grey matter to configure and implement.</p>
<p>You can do anything you would like at this level so long as it involves automation.  You should configure alerts, you should establish baselines, you should establish some level of history for what has been monitored and discovered. My recommendation here is to know your data and your environment and then to create scripts to cover your bases.</p>
<p>One last thought, no matter what solution you decide to implement, you should also monitor the monitor. If the DBA collapses from long hours of eyeball monitoring, who will be there to pick him/her up to resume the monitoring?</p>
<p>If you opt to not implement any of these options, or if you opt to implement either of the first two options, I hope you have dusted off your resume!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2668" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/05/12/monitoring-sql-server/">Monitoring SQL Server</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/05/12/monitoring-sql-server/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Audit Schema Change Report</title>
		<link>https://jasonbrimhall.info/2015/03/11/audit-schema-change-report/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=audit-schema-change-report</link>
					<comments>https://jasonbrimhall.info/2015/03/11/audit-schema-change-report/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 11 Mar 2015 12:58:33 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2651</guid>

					<description><![CDATA[<p>In a recent article on SSG, I discussed how to use Extended Events to function in a Profiler like fashion.  You can read about that here.  I recommend reading that article first because it helps [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/03/11/audit-schema-change-report/">Audit Schema Change Report</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In a recent article on SSG, I discussed how to use Extended Events to function in a Profiler like fashion.  You can read about that <a title="XE Profiler" href="http://bit.ly/XEProfilerSSG">here</a>.  I recommend reading that article first because it helps to lay some of the groundwork for this article.</p>
<p>Within Management Studio, from a righ-click context menu, there is an option to run a report called &#8220;Schema Changes History&#8221;.  The name of this report might indicate that there is some means to find when a change occurred in the schema and potentially what the change was as well as who made the change.  It does say &#8220;Schema Changes History&#8221; after-all.</p>
<p>If you run the report, you would be able to see a report similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report.png"><img loading="lazy" class="aligncenter size-large wp-image-2652" src="http://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report-1024x437.png" alt="Change_Report" width="560" height="239" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report-1024x437.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report-300x128.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report-50x21.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/03/Change_Report.png 1547w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>This looks like it could be a pretty useful report.  If I drill into the collapsed items, I can get better information.  But, how exactly is this report producing this kind of data?  I don&#8217;t have a database audit running to trap this information.  I also don&#8217;t have SSDT-BI installed, so I can&#8217;t export the report and check the report definition.</p>
<p>I could run a trace and refresh the report data and see what pops there.  I would really hate to use Profiler though, and I really don&#8217;t want to go through the hassle of creating a server side trace to figure out the source data definitions.  Then the lightbulb moment occurs.  I already have an XE session that can trace the SQL queries just like Profiler.  Why not use a better tool to do the job and satisfy my curiosity at the same time?</p>
<p>So, go read that <a href="http://bit.ly/XEProfilerSSG">article, </a>I wrote for SSG, to get the XE session definition in order to follow along a little better.  With that XEvent session running, I can refresh the report data and start to evaluate what is happening in order to produce the Audit report.</p>
<p>By this point, you have probably thought to yourself that the source of the data must be coming from the default trace.  If you thought that, then you are correct.  It is a good presumption based on a knowledge of what kind of data is being tracked in the default trace.  But I really wanted to know for certain what the source of the data was.  As I perused the XEvent session data, I noticed several queries similar to the following in the results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture.png"><img loading="lazy" class="aligncenter size-large wp-image-2653" src="http://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture-1024x358.png" alt="XE_Capture" width="560" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture-1024x358.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture-300x105.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture-50x17.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/03/XE_Capture.png 1453w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Yes, I am using the GUI (*shrug*) in this image to explore the data from the session.  That is just for display friendliness.  But, as you look through those queries you start to see a few patterns and some obvious signs that the source of the data is the default trace.  Here is a cleaner look at the code being used to get the data-set.</p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @curr_tracefilename varchar(256)
	,@indx varchar(256)
	,@base_tracefilename varchar(256)

select @curr_tracefilename = path from sys.traces where is_default = 1

 set @curr_tracefilename = reverse(@curr_tracefilename) 
select @indx  = PATINDEX('%\%', @curr_tracefilename) 
set @curr_tracefilename = reverse(@curr_tracefilename) 
        
set @base_tracefilename = LEFT( @curr_tracefilename,len(@curr_tracefilename) - @indx) + '\log.trc';  

select ObjectName as obj_name
        ,       ObjectID
        ,       DatabaseName
        ,       StartTime as start_time
        ,       EventClass as event_class
        ,       EventSubClass
        ,       ObjectType as object_type
        ,       ServerName
        ,       LoginName
        ,       NTUserName
        ,       ApplicationName
        ,       convert(varchar(128),'temp') as DDL_Operation
		INTO #temp_trace  
        FROM ::fn_trace_gettable( @base_tracefilename, default )  
        where EventClass in (46,47,164) and EventSubclass = 0  and DatabaseID = db_id()

update #temp_trace set DDL_Operation = 'CREATE' where event_class = 46

update #temp_trace set DDL_Operation = 'DROP' where event_class = 47
update #temp_trace set DDL_Operation = 'ALTER' where event_class = 164

DECLARE @d1 DATETIME
	,@diff DATETIME
select @d1 = min(start_time) from #temp_trace
set @diff= datediff(hh,@d1,getdate())          


select  @diff as difference          
,       @d1 as date          
,       object_type as obj_type_desc           
,       (dense_rank() over (order by obj_name,object_type ) )%2 as l1           
,       (dense_rank() over (order by obj_name,object_type,start_time ))%2 as l2          
,       *          
from #temp_trace 
where object_type not in (21587) -- don't bother with auto-statistics as it generates too much noise          
order by start_time desc

drop table #temp_trace</pre><p>Now, I must confess that I altered it a bit to make sure it was doing what I thought.  Just a little thing like swapping a missing definition for the table variable for a quick insert into a temp table.  But the reality is, it is pretty much the source code of the report.  It is not the prettiest of code for the source, but it works.</p>
<p>Due to the lack of prettiness to the code and the seemingly overly complex means to get to the end result, I decided I wanted to &#8220;tune&#8221; it up a little bit.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @DBName sysname = 'AdventureWorks2014'
		,@d1 DATETIME
		,@diff INT;

SELECT ObjectName
		  , ObjectID
		  , DatabaseName
		  , StartTime
		  , EventClass
		  , EventSubClass
		  , ObjectType
		  , ServerName
		  , LoginName
		  , NTUserName
		  , ApplicationName
		  , CASE EventClass
				WHEN 46
					THEN 'CREATE'
				WHEN 47
					THEN 'DROP'
				WHEN 164
					THEN 'ALTER'
			END AS DDLOperation
		INTO #temp_trace  
	FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
			( SELECT REVERSE(SUBSTRING(REVERSE(path),
					CHARINDEX('\',REVERSE(path)),256)) + 'log.trc'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) T  
  WHERE EventClass in (46,47,164) 
			AND EventSubclass = 0
			AND ObjectType &lt;&gt; 21587-- don't bother with auto-statistics as it generates too much noise   
			AND DatabaseName = @DBName;


SELECT @d1 = MIN(StartTime) 
	FROM #temp_trace;

SET @diff= DATEDIFF(hh,@d1,GETDATE());


SELECT @diff AS HrsSinceFirstChange    
		, @d1 AS FirstChangeDate    
		, sv.name AS obj_type_desc
		, tt.ObjectType
		, tt.DDLOperation
		, tt.DatabaseName,tt.ObjectName,tt.StartTime
		, tt.EventClass,tt.EventSubClass
		, tt.ServerName,tt.LoginName, tt.NTUserName
		, tt.ApplicationName
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType ) )%2 AS l1     
		, (dense_rank() OVER (ORDER BY ObjectName,ObjectType,StartTime ))%2 AS l2    
	FROM #temp_trace tt
		INNER JOIN sys.trace_events AS te 
			ON tt.EventClass = te.trace_event_id
		INNER JOIN sys.trace_subclass_values tsv
			ON tt.EventClass = tsv.trace_event_id
			AND tt.ObjectType = tsv.subclass_value
		INNER JOIN master.dbo.spt_values sv 
			ON tsv.subclass_value = sv.number
			AND sv.type = 'EOD'
	ORDER BY StartTime DESC;

DROP TABLE #temp_trace;</pre><p>Now, I have something that is easier to read and maintain (my opinion) and works well.  It can also be used easily enough in an RDL should you wish to create an additional report different from the canned report in SSMS.  Or just continue to use it from within Management Studio and check the results without the overhead of the report presentation.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2651" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/03/11/audit-schema-change-report/">Audit Schema Change Report</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/03/11/audit-schema-change-report/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Last Execution of a Proc</title>
		<link>https://jasonbrimhall.info/2015/02/17/last-execution-of-a-proc/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=last-execution-of-a-proc</link>
					<comments>https://jasonbrimhall.info/2015/02/17/last-execution-of-a-proc/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 17 Feb 2015 22:21:53 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[Execution Plans]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2645</guid>

					<description><![CDATA[<p>SQL Server is full of good stuff.  There are plenty of features to be used.  Plenty of applications to help it.  And there is even plenty of metadata within SQL Server to help you better [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/02/17/last-execution-of-a-proc/">Last Execution of a Proc</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>SQL Server is full of good stuff.  There are plenty of features to be used.  Plenty of applications to help it.  And there is even plenty of metadata within SQL Server to help you better understand your data and the queries that are being run.</p>
<p>It just so happens that a couple of clients requested some information on this additional metadata.  Both of the clients wanted something just a little different from the other.  After a little bit of thought, it came pretty clearly that what they wanted was definitely available within SQL Server.  The first client simply wanted to know the last time a procedure had been executed.  That is relatively easy enough &#8211; granted the procedure has been executed and granted the execution statistics have not been evicted.</p>
<p>The second client also wanted to know some information about the execution of a stored procedure.  But this time, they wanted to get the execution plan.  There are a few ways to trap an execution plan.  You could either run a trace, an XE session, or you could execute the query and grab the plan.  But if you didn&#8217;t already have an XE session running or a trace running and the client does not want you to execute the query to trap that plan?</p>
<p>Well, that is not a problem because SQL Server stores this stuff.  As long as the query and plan have not been evicted from the plan cache then you can get the metadata you desire.</p>
<h2>Metadata to the Rescue</h2>
<p>The metadata that we seek happens to be accessible through the use of several dynamic management views.  These are sometimes called dynamic management objects and are great to use to get to know your data and environment.  This time around, I am mostly interested in the following dynamic management objects: <span style="color: #008000;">sys.dm_exec_query_stats</span> , <span style="color: #008000;">sys.dm_exec_cached_plans</span> , <span style="color: #008000;">sys.dm_exec_sql_text</span> , and <span style="color: #008000;">sys.dm_exec_query_plan</span>.  I am using these objects because I want to trap execution stats along with the query SQL statement as well as the cached plan for that query.</p>
<p>So this is what I came up with to aid each of the clients in getting the data they sought.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO

DECLARE @querysought VARCHAR(256) = '%boywhathairylegsyouhavethere%';

SELECT OBJECT_NAME(st.objectid) AS ObjName, qs.last_execution_time
		, cp.size_in_bytes, cp.usecounts, qp.query_plan
		,cp.cacheobjtype,cp.objtype
		, st.text AS QueryText
		,(SELECT st.text AS [processing-instruction(definition)]
            FROM sys.dm_exec_sql_text(qs.sql_handle) sti
            FOR XML PATH(''), TYPE) AS FormattedSQLText
	FROM sys.dm_exec_query_stats qs
		INNER JOIN sys.dm_exec_cached_plans cp
			ON qs.plan_handle = cp.plan_handle
	CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
	OUTER APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
	WHERE OBJECT_NAME(st.objectid) LIKE @querysought
		OR st.text LIKE @querysought
	;</pre><p>Pretty simple and straight forward.  Now, I have this quick query to find the last time a proc was run, as well as a means to trap the execution plan for that query.  If I run that query, I would be able to see something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/02/Capture.png"><img loading="lazy" class="aligncenter size-large wp-image-2648" src="http://jasonbrimhall.info/wp-content/uploads/2015/02/Capture-1024x125.png" alt="Capture" width="560" height="68" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/02/Capture-1024x125.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/02/Capture-300x37.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/02/Capture-50x6.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/02/Capture.png 1715w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>I hope this is useful to you and hope you enjoy.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2645" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/02/17/last-execution-of-a-proc/">Last Execution of a Proc</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/02/17/last-execution-of-a-proc/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Security as a Fleeting Thought</title>
		<link>https://jasonbrimhall.info/2015/02/10/security-as-a-fleeting-thought/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=security-as-a-fleeting-thought</link>
					<comments>https://jasonbrimhall.info/2015/02/10/security-as-a-fleeting-thought/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 10 Feb 2015 22:32:20 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[Security]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2642</guid>

					<description><![CDATA[<p>Today we have another installment in what is known as TSQL Tuesday.  This month we have an invitation and topic given to us by the infamous Kenneth Fisher ( blog &#124; twitter). Today, the invitation [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/02/10/security-as-a-fleeting-thought/">Security as a Fleeting Thought</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today we have another installment in what is known as TSQL Tuesday.  This month we have an invitation and topic given to us by the infamous Kenneth Fisher ( <a href="http://sqlstudies.com/">blog </a>| <a href="https://twitter.com/sqlstudent144">twitter</a>).</p>
<p><a href="http://sqlstudies.com/2015/02/03/tsql-tuesday-63-how-do-you-manage-security/"><img loading="lazy" class="alignleft wp-image-2309 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL2sDay150x150" width="150" height="150" /></a>Today, the <a href="http://sqlstudies.com/2015/02/03/tsql-tuesday-63-how-do-you-manage-security/">invitation </a>is for us to share our stories on how we like to manage security.  Or at least that is the request that was made by Kenneth.  I am going to take a bit of a twist on that request.  Instead of sharing how I like to manage security, I am going to share some interesting stories on how I have seen security managed.</p>
<p>Let&#8217;s just call this a short series on various case studies in how to manage your security in a very peculiar way.  Or as the blog title suggests, how to manage your security as an <strong>afterthought</strong>.</p>
<h2>Case Study #1</h2>
<p><img loading="lazy" class=" size-large wp-image-2643 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2015/02/dbsecurity.png" alt="dbsecurity" width="347" height="346" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/02/dbsecurity.png 347w, https://jasonbrimhall.info/wp-content/uploads/2015/02/dbsecurity-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2015/02/dbsecurity-300x300.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/02/dbsecurity-50x50.png 50w" sizes="(max-width: 347px) 85vw, 347px" />We have all dealt with the vendor that insists on the user account that will be used for their database and application be one of two things.  Either it needs to be sa or needs to be a member of the sysadmin fixed server role.  The ensuing discussion with those vendors is always a gem.  They insist the application will break, you as the diligent DBA prove otherwise, and then the senior manager sponsoring the application comes around with a mandate that you must provide the access the vendor is requesting.</p>
<p>Those are particularly fun times.  Sometimes, there is a mutual agreement in the middle on what security can be used and sometimes the DBA just loses.</p>
<p>But what about when it is not a vendor application that mandates such relaxed security for their application and database?  What if it happens to be the development group?  What if it happens to be a developer driven shop and you are the consultant coming in to help get things in order?</p>
<p>I have had the distinct pleasure of working in all of those scenarios.  My favorite was a client that hosted ~700 clients, each with their own database.  There were several thousand connections coming into the server and every single connection was coming in as &#8216;sa&#8217;.  Yes, that is correct.  There were no user logins other than the domain admins group on the server &#8211; which was also added to the <strong>sysadmin</strong> security role.  That is always a fun discussion to start and finish.  The look of color disappearing from the clients&#8217; eyes as the realize the severity of the problem.</p>
<p>Please do not attempt this stunt at home.</p>
<h2>Case Study #2</h2>
<p>In a similar vain, another one that I have seen far too often is the desire to grant users dbo access within a database.  While this is less heinous than granting everybody sysadmin access &#8211; it is only a tad better.  Think about it in this way &#8211; does Joe from financing really need to be able to create and drop tables within the accounting database?  Does Marie from human resources need to be able to create or drop stored procedures from the HR database?  The answer to both should be &#8216;NO&#8217;.</p>
<p>In another environment, I was given the opportunity to perform a security audit.  Upon looking over things, it became very clear what the security was.  Somebody felt it necessary to add <strong>[Domain Users]</strong> to the <strong>dbo</strong> role on every database.  Yes, you read that correctly.  In addition to that, the same [Domain Users] group was added to the <strong>sysadmin</strong> server fixed security role.  HOLY COW!</p>
<p>In this particular case, they were constantly trying to figure out why permissions and objects were changing for all sorts of things within the database environment.  The answer was easy.  The fix is also easy &#8211; but not terribly easy to accept.</p>
<p>Please do not attempt this stunt at home.</p>
<h2>Case Study #3</h2>
<p>I have encountered vendor after vendor that has always insisted that they <strong>MUST</strong> have <strong>local admin </strong>and<strong> sysadmin</strong> rights on the box and instance (respectively).  For many this is a grey area because of the contracts derived between the client and the vendor.</p>
<p>For me, I have to ask why they need that level of access.  Does the vendor really need to be able to backup your databases and investigate system performance on your server?  Does that vendor need, or are they even engaged, to troubleshoot your system as a whole?  Or, do they just randomly sign in and apply application updates without your knowledge or perform other &#8220;routine&#8221; tasks unknown to you?</p>
<p>I have seen vendors change permissions and add back door accounts far too often.  They seldom if ever are capable of providing the level of support necessary when you are stuck with deadlocks by the second or blocking chains that tie up the entire server.  In addition, they are generally unavailable for immediate support when a production halting issue arises in their application &#8211; or at least not for a few hours.</p>
<p>This is specifically in regards to application vendors.  They are not your sysadmin and they are not your DBA.  If they must have RDP access or access to the database &#8211; put it under tight control.  Disable the account until they request access.  Then a request can be made and a note documented about why the access is needed.  Then the account can be enabled, monitored and disabled after a specified amount of time.</p>
<p>Please do not attempt this stunt at home.</p>
<p>This also changes when that vendor happens to be providing you IT functionality and is not specifically tied to an application.  Those relationships are a bit different and do require a little more trust to the person who is acting on your behalf as your IT staff.</p>
<h2>Conclusion</h2>
<p>I have shared three very dangerous stunts that are sometimes portrayed to be done by professionals.  Do not try this in your environment or at home.  It is dangerous to treat security with so little concern.  Security is not some stunt, and should be treated with a little more care and attention.</p>
<p>If you find yourself in any of these situations, an <strong>audit</strong> is your friend.  Create some audit process within SQL Server or on the Local server to track changes and accesses.  Find out what is going on and be prepared to act while you build your case and a plan for implementing tighter security.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2642" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/02/10/security-as-a-fleeting-thought/">Security as a Fleeting Thought</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/02/10/security-as-a-fleeting-thought/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Las Vegas UG This week</title>
		<link>https://jasonbrimhall.info/2015/01/05/las-vegas-ug-this-week/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=las-vegas-ug-this-week</link>
					<comments>https://jasonbrimhall.info/2015/01/05/las-vegas-ug-this-week/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Jan 2015 21:12:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2625</guid>

					<description><![CDATA[<p>What a fun week we have tuned up for the folks in Las Vegas.  It is the first full week of January and there is this huge convention going on near the strip.  And as [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2015/01/05/las-vegas-ug-this-week/">Las Vegas UG This week</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>What a fun week we have tuned up for the folks in Las Vegas.  It is the first full week of January and there is this huge convention going on near the strip.  And as timing would have it, this week is also the perfect time to have our User Group meeting.</p>
<p>What major conference is going on this week you ask?  Why it is time for 200,000 people to invade the strip, all of the major convention centers (well nearly all of them), and every last hotel room (as seen by the tripling in price for hotel rooms starting Tuesday Night &#8211; unless you go to the Cosmo where the room rate increased 20x this week).  That conference happens to be <a href="https://web.archive.org/web/20160413114836/https://www.cesweb.org/">CES </a>(Consumer Electronics Show).</p>
<p>If you happen to be in town for CES, live here in Vegas or are just in town this week, we invite you to come join us at the Las Vegas UG meeting on Thursday.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/01/Capture.png"><img loading="lazy" class="aligncenter wp-image-2626 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/01/Capture-1024x397.png" alt="January SQL Invite" width="560" height="217" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/01/Capture-1024x397.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/01/Capture-300x116.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/01/Capture-50x19.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/01/Capture.png 1412w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>We have the full details for the meeting on our meetup site (http://www.meetup.com/SQL-Server-Society-of-Las-Vegas/events/219384209/).  <del>This month we have an interactive session where Wayne Sheffield will walk you through some nifty tips and tricks for Management Studio.</del>  Read the full details on the meetup site and come visit us in person or via our livemeeting.  We&#8217;d love to see you.</p>
<p><strong>Update:</strong></p>
<p>We are swapping presenters this month at the chance to have a presenter in person.  Randy Knight will be in the area and has asked to be able to present.  Thanks to Wayne for being understanding.  Please check the meetup site for more details.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2625" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/01/05/las-vegas-ug-this-week/">Las Vegas UG This week</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/01/05/las-vegas-ug-this-week/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Effects of Max Mem on Plan Cache</title>
		<link>https://jasonbrimhall.info/2015/01/05/effects-of-max-mem-on-plan-cache/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=effects-of-max-mem-on-plan-cache</link>
					<comments>https://jasonbrimhall.info/2015/01/05/effects-of-max-mem-on-plan-cache/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Jan 2015 14:45:59 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2619</guid>

					<description><![CDATA[<p>Some effects on plan cache and max memory settings</p>
The post <a href="https://jasonbrimhall.info/2015/01/05/effects-of-max-mem-on-plan-cache/">Effects of Max Mem on Plan Cache</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Reading a Microsoft Article (<a href="http://technet.microsoft.com/en-us/library/ms181055%28v=sql.105%29.aspx">which can be found here</a>) while making sure I understood what can cause a query plan to be recompiled or removed from the plan cache, I got to thinking a bit.</p>
<p>In the article, it lists the following as things that can cause a plan to be removed from cache or to be recompiled.</p>
<ul>
<li>Execution plans remain in the procedure cache as long as there is enough memory to store them. When memory pressure exists, the Database Engine uses a cost-based approach to determine which execution plans to remove from the procedure cache. To make a cost-based decision, the Database Engine increases and decreases a current cost variable for each execution plan.</li>
<li>Changes made to a table or view referenced by the query (ALTER TABLE and ALTER VIEW).</li>
<li>Changes made to a single procedure, which would drop all plans for that procedure from the cache (ALTER PROCEDURE).</li>
<li>Changes to any indexes used by the execution plan.</li>
<li>Updates on statistics used by the execution plan, generated either explicitly from a statement, such as UPDATE STATISTICS, or generated automatically.</li>
<li>Dropping an index used by the execution plan.</li>
<li>An explicit call to <strong>sp_recompile</strong>.</li>
<li>Large numbers of changes to keys (generated by INSERT or DELETE statements from other users that modify a table referenced by the query).</li>
<li>For tables with triggers, if the number of rows in the <strong>inserted</strong> or <strong>deleted</strong> tables grows significantly.</li>
<li>Executing a stored procedure using the WITH RECOMPILE option.</li>
</ul>
<p>The first item removes a plan from cache while the rest mark the plan is invalid and a recompile will be forced on the next execution of the SQL Statement.  But then the question comes, why make the distinction between the two?  Doesn&#8217;t removing a plan from cache in essence equate to a recompile further down the road when the query is executed again?  While semantically it is not a recompile, it sure sounds a lot like one.  The query was compiled, invalidated and removed from cache and then compiled again when executed the next time around.</p>
<p>When thinking about all of this, how can we see that memory pressure can &#8220;invalidate&#8221; query plans?  That is actually quite simple.  We can see the same net effects with the following experiment.</p>
<p><strong>WARNING: DO NOT DO THIS ON ANY ENVIRONMENT THAT IS NOT A SANDBOX ENVIRONMENT.</strong></p><pre class="urvanov-syntax-highlighter-plain-tag">select count(*) as PlanCount
	From sys.dm_exec_cached_plans
;
GO
EXEC sys.sp_configure N'max server memory (MB)', N'1024'
GO
RECONFIGURE WITH OVERRIDE
GO

select count(*) as PlanCount
	From sys.dm_exec_cached_plans
;
GO

EXEC sys.sp_configure N'max server memory (MB)', N'8100'
GO
RECONFIGURE WITH OVERRIDE
GO</pre><p>In this setup, I have a Sandbox server with a simulated load that keeps plenty of plans in cache and SQL Server is happy with about eight gigabytes of memory allocated to it.  To show that memory can cause a bunch of plans to be invalidated (and removed from the plan cache), I am going to take memory away from SQL Server and in essence simulate a memory leak or memory pressure.</p>
<p>This shows that the settings have taken effect on SQL Server and all of this without a Service restart (I keep hearing that myth).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect.png"><img loading="lazy" class="aligncenter wp-image-2620 size-large" src="http://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect-1024x776.png" alt="Max Memory in SQL Server" width="560" height="424" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect-1024x776.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect-300x227.png 300w, https://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect-50x38.png 50w, https://jasonbrimhall.info/wp-content/uploads/2015/01/MemChangeTakingEffect.png 1198w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Seeing that the memory settings are taking immediate effect, we can turn our attention to that query that was run.  In the query to experiment with this, I took a count of the number of plans in the plan cache first, then changed the max memory, and then took a count of the number of plans in cache again.  This next image shows the results of those two plan count queries.  It is obvious here that the number of plans in cache was severely impacted by this change in Max memory when taking TOO much memory away from SQL Server (this is why you should only do this on a sandbox server).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2015/01/CacheFlushed.png"><img loading="lazy" class="aligncenter wp-image-2621 size-medium" src="http://jasonbrimhall.info/wp-content/uploads/2015/01/CacheFlushed-128x300.png" alt="Max Mem effect on Plan Cache" width="128" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2015/01/CacheFlushed-128x300.png 128w, https://jasonbrimhall.info/wp-content/uploads/2015/01/CacheFlushed-21x50.png 21w, https://jasonbrimhall.info/wp-content/uploads/2015/01/CacheFlushed.png 262w" sizes="(max-width: 128px) 85vw, 128px" /></a></p>
<p>&nbsp;</p>
<p>If you happen to take too much memory away from SQL Server, you could end up in a severe memory pressure situation where connections are limited.  Even trying to increase max memory could be severely hampered due to insufficient resources in the default resource pool.  <a href="http://blogs.msdn.com/b/alexfeng/archive/2013/07/07/sql-server-can-t-start-after-accidently-set-the-quot-max-server-memory-quot-to-0.aspx">Here is a blog post</a> that demonstrates the effects on connections due to this error (even as bad as SQL Server not starting up).</p>
<p>Since the problem is in the default resource pool, you could try a connection to the DAC and modify the max memory there.  If the pressure is severe enough, you may be limited in your ability to connect to the DAC as well.  In that case, you may be in need of starting up in single user mode as referenced in that prior blog post.  Sometimes, it is enough to reduce the number of connections or resource requirements to regain access to the server to change the max memory appropriately.  Suffice it to say, do not run this on a production type of box, lest you are ready to cause a bit of an outage.  The intent here is solely to share that max memory can have an immediate impact on compiles and plans in cache.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2619" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2015/01/05/effects-of-max-mem-on-plan-cache/">Effects of Max Mem on Plan Cache</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2015/01/05/effects-of-max-mem-on-plan-cache/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Happy Holidays</title>
		<link>https://jasonbrimhall.info/2014/12/26/happy-holidays/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=happy-holidays</link>
					<comments>https://jasonbrimhall.info/2014/12/26/happy-holidays/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 26 Dec 2014 17:18:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Christmas]]></category>
		<category><![CDATA[Holiday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2614</guid>

					<description><![CDATA[<p>Quick and simple for today.  Happy Holidays to you!  </p>
The post <a href="https://jasonbrimhall.info/2014/12/26/happy-holidays/">Happy Holidays</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Quick and simple for today.  Happy Holidays to you!</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/12/Tree_color.png"><img loading="lazy" class="aligncenter wp-image-2616 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/12/Tree_color.png" alt="Happy Holidays" width="616" height="653" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/12/Tree_color.png 616w, https://jasonbrimhall.info/wp-content/uploads/2014/12/Tree_color-283x300.png 283w, https://jasonbrimhall.info/wp-content/uploads/2014/12/Tree_color-47x50.png 47w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/12/Tree.png"> </a></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2614" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/12/26/happy-holidays/">Happy Holidays</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/12/26/happy-holidays/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Murder in Charleston</title>
		<link>https://jasonbrimhall.info/2014/12/08/murder-in-charleston/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-in-charleston</link>
					<comments>https://jasonbrimhall.info/2014/12/08/murder-in-charleston/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 08 Dec 2014 17:14:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQL Saturday]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2601</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/12/08/murder-in-charleston/">Murder in Charleston</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/12/Charleston_Friend.png"><img loading="lazy" class="aligncenter wp-image-2602" src="http://jasonbrimhall.info/wp-content/uploads/2014/12/Charleston_Friend.png" alt="Charleston Friend" width="600" height="442" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/12/Charleston_Friend.png 303w, https://jasonbrimhall.info/wp-content/uploads/2014/12/Charleston_Friend-300x220.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/12/Charleston_Friend-50x36.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>Time to sink or sail, so to speak.  <a title="SQLSat354" href="https://www.sqlsaturday.com/354/eventhome.aspx">SQL Saturday 354</a> in South Carolina will mark the next attempt at what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in this all day workshop event.  The session is one of two all day sessions for the event in Charleston, SC.</p>
<p>If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3>Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" alt="wayne" width="141" height="211" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at <a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" alt="JasonBrimhall" width="141" height="211" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant, SQL Server MVP and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" class="aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" alt="kaboom" width="301" height="167" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us.  You can find registration information and event details at the Charleston SQL Saturday site &#8211; <a href="https://www.sqlsaturday.com/354/eventhome.aspx">here</a>.  There are only 75 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>The cost for the class is $110 (plus fees) up through the day of the event.  <a title="Registration" href="https://www.eventbrite.com/e/murder-they-wrote-tickets-14093715683" target="_blank" class="broken_link">When you register</a>, be sure to tell your coworkers and friends.</p>
<h3>Wait, there&#8217;s more&#8230;</h3>
<p>Not only will I be in Charleston for this workshop, we will also be presenting as a part of the SQLSaturday event on December 13, 2014 (the day after the workshop which is December 12, 2014).  You can view the available sessions <a href="https://www.sqlsaturday.com/354/schedule.aspx">here</a>.</p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some workshop sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2601" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/12/08/murder-in-charleston/">Murder in Charleston</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/12/08/murder-in-charleston/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Audit Database File Size Changes</title>
		<link>https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=audit-database-file-size-changes</link>
					<comments>https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 26 Nov 2014 23:23:30 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2584</guid>

					<description><![CDATA[<p>If you just so happen to be running on SQL Server 2012 or later, you will need to change your event sessions that were tracking file changes.  It is a bit of an exercise to make the change and can be frustrating, but it is well worth it.  The improved data that can be captured is going to help better control and oversee the environment.</p>
The post <a href="https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">Audit Database File Size Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png"><img loading="lazy" class="aligncenter size-full wp-image-2585" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png" alt="dbsizechange" width="537" height="392" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange.png 537w, https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange-300x218.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/dbsizechange-50x36.png 50w" sizes="(max-width: 537px) 85vw, 537px" /></a></p>
<p>Recently I shared an article on how to track the growths and shrinks that occur within database files.  I shared that article <a href="http://bit.ly/SSGFileSizeChange">here</a>, you should read it before proceeding with today&#8217;s article.</p>
<p>Near the end of that article I declared that it was a really good method to track that information within SQL Server 2008.  What if you happen to be on SQL 2012 or SQL 2014 (as of this writing)?  Will it work there too?</p>
<h3>Does it Work Past 2008?</h3>
<p>It is a good question.  Does that extended event session I shared work in SQL Server 2012 or 2014?  Let&#8217;s take a quick look.  I am skipping the setup scripts for that XE session in this article, so you will need to <a href="http://bit.ly/SSGFileSizeChange">get them from the previous article</a> in order to follow along in this segment.</p>
<p>Before we can investigate if this extended event session will work, let&#8217;s take a quick look to confirm that the session is running on the server.  We can do that with a query similar to the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SessionName VARCHAR(64) = 'TrackDBFileChange'
SELECT sn.SessionName
	, CASE WHEN ISNULL(es.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		End as XESessionExists
	, CASE WHEN ISNULL(xe.name,'No') = 'No'
		THEN 'NO'
		ELSE 'YES'
		End as XESessionRunning
	FROM (Select @SessionName as SessionName) sn
		LEFT OUTER JOIN sys.server_event_sessions es
			ON sn.SessionName = es.name
		LEFT OUTER JOIN sys.dm_xe_sessions xe
			ON es.name = xe.name
	;</pre><p>Running that query will produce results very similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/SessionCheck.png"><img loading="lazy" class="aligncenter size-full wp-image-2588" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/SessionCheck.png" alt="SessionCheck" width="608" height="84" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/SessionCheck.png 608w, https://jasonbrimhall.info/wp-content/uploads/2014/11/SessionCheck-300x41.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/SessionCheck-50x6.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>This is good news.  If you noticed, I am querying a couple of views to get this information.  In the server_event_sessions catalog view I can determine if the event exists.  When checking the dm_xe_sessions DMV, I can see if the session is running or not by whether or not the session exists in the view.  When the session is enabled and running, then the DMV will return a record for it. Otherwise, the DMV does not hold a record for the session.</p>
<p>With a session running, we can now validate if it is running properly by running any script that will cause the files to grow or shrink.  Recall that in the previous article, it was shown that any growth or shrink operation will cause an event to fire with this session.  Here is a sample of the query I am running.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DB_NAME(database_id) AS DBName,name AS FileName,size/124.0 AS size_mb
	FROM master.sys.master_files
	WHERE database_id in (2,DB_ID('Sandbox2'));

USE [Sandbox2]
GO
DBCC SHRINKFILE (N'Sandbox2' , 1)
GO

USE [Sandbox2]
GO
DBCC SHRINKFILE (N'Sandbox2_log' , 1)
GO

SELECT DB_NAME(database_id) AS DBName,name AS FileName,size/124.0 AS size_mb
	FROM master.sys.master_files
	WHERE database_id in (2,DB_ID('Sandbox2'));
GO</pre><p>That query has three distinct segments.  The first is just to check my file sizes.  The second segment performs my file shrink operations.  And the final segment checks the file sizes again.  Here is what the first and third segments would look like on the Sandbox2 database that I used in the previous article.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/filesizes_vold.png"><img loading="lazy" class="alignnone wp-image-2590 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/filesizes_vold.png" alt="filesizes_vold" width="455" height="382" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/filesizes_vold.png 455w, https://jasonbrimhall.info/wp-content/uploads/2014/11/filesizes_vold-300x251.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/filesizes_vold-50x41.png 50w" sizes="(max-width: 455px) 85vw, 455px" /></a></p>
<p>With the evidence that we have the session running and that there was indeed a file size change, let&#8217;s now check the event session data and confirm whether or not the session is working on this SQL 2014 server.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
	,event_data.value('(event/@timestamp)[1]','varchar(max)') as timestamp
    ,event_data.value('(event/data[@name="count"]/value)[1]', 'bigint') AS TraceFlag
	,event_data.value('(event/data[@name="increment"]/value)[1]', 'bigint') AS FlagType
	,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	,event_data.value('(event/action[@name="database_name"]/value)[1]', 'varchar(max)') AS DBQueryExecutedFrom
	,db_name(event_data.value('(event/data[@name="database_id"]/value)[1]','int')) as DBNamethatShrunk
	,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'varchar(max)') AS ClientHost
	,event_data.value('(event/action[@name="session_id"]/value)[1]', 'varchar(max)') AS session_id
FROM(    SELECT evnt.query('.') AS event_data
        FROM
        (SELECT CAST(event_data AS xml) AS TargetData
            FROM sys.fn_xe_file_target_read_file('C:\XE\DBFileSizeChange*.xel','C:\XE\DBFileSizeChange*.xem',NULL, NULL)
        ) AS tab
        CROSS APPLY TargetData.nodes ('RingBufferTarget/event') AS split(evnt) 
    ) AS evts(event_data)
WHERE event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_log_file_size_changed'
	or event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_data_file_size_changed'
	or event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_log_growth'
ORDER BY timestamp asc;</pre><p>The preceding is the query I am using to query the session data.  Running that query will produce the following results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/nodata.png"><img loading="lazy" class="aligncenter size-large wp-image-2591" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/nodata-1024x227.png" alt="nodata" width="560" height="124" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/nodata-1024x227.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/11/nodata-300x66.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/nodata-50x11.png 50w, https://jasonbrimhall.info/wp-content/uploads/2014/11/nodata.png 1384w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>That&#8217;s right!  There is no session data despite the event having occurred and despite the session running currently.  We also know that this session works (we demonstrated it on SQL 2008).  So there must be a bug, something is broken.  Right?</p>
<h3>What Now?</h3>
<p>Since the extended event obviously no longer works, we are stuck with few options.  We could always try resorting back to the default trace.  After all, I demonstrated that the default trace is already trapping information about file shrinks.  That was discussed in the prior article and <a href="http://bit.ly/19eAcUW">here as well</a>.</p>
<p>So, what if we tried to go and capture all of the same information from the default trace?  We could certainly try that.  Assuming that the default trace is still running on the server, this query could get us pretty close.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
		T.DatabaseName
		,T.EventClass
		,T.TextData
		,T.HostName
		,T.ApplicationName
		,T.LoginName
		,T.StartTime
		,T.SPID
		,T.Duration as DurationMS
		,T.IntegerData as Number8KPagesChanged
		,T.FileName as FileChanged
		,CASE T.IsSystem
			WHEN 1 THEN 'YES'
			ELSE 'NO'
			END AS IsSystem
			/* Check IsSystem to help ensure Autoshrink didn't cause the shrink 
			   MSDN indicates 1=system and 0=user
			   My testing shows Null = user and 0 did not occur */
	FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
			( SELECT REVERSE(SUBSTRING(REVERSE(path),
					CHARINDEX('\',REVERSE(path)),256)) + 'log.trc'
				FROM    sys.traces
				WHERE   is_default = 1)), DEFAULT) T
	WHERE (T.TextData LIKE '%SHRINK%'
		AND T.EventClass = 116) --Audit DBCC Event
		OR T.EventClass = 92 --Data File Auto Grow
		OR T.EventClass = 93 --Log File Auto Grow
		OR T.EventClass = 94 --Data File Auto Shrink
		OR T.EventClass = 95 --Log File Auto Shrink
	ORDER BY T.StartTime,T.EventSequence
	;</pre><p>And this does a fairly decent job of getting the info we seek.  Sadly, though, it does not trap all of the necessary information.  Only the DBCC event (event 116) traps the sql statement that triggered the event to be recorded in the default trace.  But for the most part it can be a decent swing at getting the information.  Without the sql statements tied to the event, I&#8217;d rather not use it because it really just shows me how many times the size changed, what time the event occurred, and the size of the change.</p>
<p>There has got to be some other way of getting this to work in extended events.  A good question to ask is &#8220;Why does the extended event no longer work?&#8221;</p>
<p>A little digging, and one might eventually find a document that can shed some light on the problem.  Reading <a href="http://sql2012only.blogspot.com/2013/09/discontinued-database-engine-features.html">this document</a>, we can see why the event no longer works.  It has been deprecated.  What?  After one release, they decide to take away a critical piece of information?  How can that be?</p>
<p>Time to back up those findings with something a little more authoritative such as this.  Looking at <a href="http://msdn.microsoft.com/en-us/library/ms144262.aspx">this article</a>, we see that indeed the event was deprecated.  But wait a minute, the event was not just deprecated, it was also replaced with a new event.  We are in business so let&#8217;s do some querying within event sessions.</p>
<h3>Back in Business</h3>
<p>We could have probably spared some time by checking the available events in SQL Server by using this next query.  However, the events used in the previously used event session still exist.  If they did not exist, the session creation would have failed.  This can be a bit misleading, so it is good to have the information from Microsoft that the events have been deprecated and merged into a single event.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.object_name as EventName,p.name as PackageName,o.description as EventDescription
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.object_name
			and o.package_guid = c.object_package_guid
		INNER JOIN sys.dm_xe_packages p
			on o.package_guid = p.guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND (c.object_name like '%file_size%'
			or c.object_name like '%growth%')
	Order By o.package_guid;</pre><p>This produces the desired results with the new event name specified in that Microsoft article.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent.png"><img loading="lazy" class="aligncenter size-large wp-image-2596" src="http://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent-1024x196.png" alt="2012filesizeevent" width="560" height="107" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent-1024x196.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent-300x57.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent-50x9.png 50w, https://jasonbrimhall.info/wp-content/uploads/2014/11/2012filesizeevent.png 1206w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>Based on this information, a rewrite of the extended event session is possible and necessary.  We can update the extended event session that audits when a database file changes in size.  This will look something like the following session.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [TrackDBFileChange12] ON SERVER 
ADD EVENT sqlserver.database_file_size_change(
	ACTION(sqlserver.session_id,sqlserver.database_name,sqlserver.client_hostname,
            sqlserver.sql_text)
	)
,ADD EVENT sqlserver.databases_log_growth(
	ACTION(sqlserver.session_id,sqlserver.database_name,sqlserver.client_hostname,
            sqlserver.sql_text)
	)
ADD TARGET  package0.asynchronous_file_target(
     SET filename='C:\XE\DBFileSizeChange12.xel',max_file_size = 5,max_rollover_files = 4
         ,metadatafile='C:\XE\DBFileSizeChange12.xem')
,
ADD TARGET package0.ring_buffer		-- Store events in the ring buffer target
	(SET max_memory = 4096)
WITH (MAX_MEMORY = 4MB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, TRACK_CAUSALITY = ON, MAX_DISPATCH_LATENCY = 1 SECONDS,startup_state = ON)
GO

ALTER EVENT SESSION TrackDBFileChange12
ON SERVER 
STATE = START;
GO</pre><p>And since I happened to have that session also running at the same time as the shrinkfiles that were run previously in this article, I can go ahead and check to see if anything was captured.  To check the session data, I will use the following query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
	,event_data.value('(event/@timestamp)[1]','varchar(max)') as timestamp
    ,event_data.value('(event/data[@name="size_change_kb"]/value)[1]', 'bigint') AS SizeChangeKb
	,event_data.value('(event/data[@name="total_size_kb"]/value)[1]', 'bigint') AS TotalSizeKb
	,event_data.value('(event/data[@name="duration"]/value)[1]', 'bigint') AS Duration_ms
	,event_data.value('(event/data[@name="is_automatic"]/value)[1]', 'varchar(20)') AS AutoChangeEvent
	,event_data.value('(event/action[@name="sql_text"]/value)[1]', 'varchar(max)') AS sql_text
	,event_data.value('(event/action[@name="database_name"]/value)[1]', 'varchar(max)') AS DBQueryExecutedFrom
	,db_name(event_data.value('(event/data[@name="database_id"]/value)[1]','int')) as AffectedDB
	,event_data.value('(event/data[@name="file_name"]/value)[1]','varchar(max)') as AffectedFile
	,event_data.value('(event/data[@name="file_type"]/text)[1]','varchar(max)') as FileType
	,event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'varchar(max)') AS ClientHost
	,event_data.value('(event/action[@name="session_id"]/value)[1]', 'varchar(max)') AS session_id
FROM(   SELECT CAST(event_data AS xml) AS TargetData
            FROM sys.fn_xe_file_target_read_file('C:\XE\DBFileSizeChange12*.xel',NULL,NULL, NULL)
        
    ) AS evts(event_data)
WHERE event_data.value('(event/@name)[1]', 'varchar(50)') = 'database_file_size_change'
	or event_data.value('(event/@name)[1]', 'varchar(50)') = 'databases_log_growth'
ORDER BY AffectedDB,FileType,timestamp asc;</pre><p>In this new event for 2012 and beyond, there is different data that is captured.  This means that I have access to better information about what is happening to my database files with regards to the size changes (growths and shrinks).</p>
<h3>Conclusion</h3>
<p>If you just so happen to be running on SQL Server 2012 or later, you will need to change your event sessions that were tracking file changes.  It is a bit of an exercise to make the change and can be frustrating, but it is well worth it.  The improved data that can be captured is going to help better control and oversee the environment.</p>
<p>For more help with your adventure into Extended Events, start <a href="https://jasonbrimhall.info/2015/09/08/learning-extended-events-in-60-days/">here</a>!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2584" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/">Audit Database File Size Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/11/26/audit-database-file-size-changes/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Tuesday #60: Something Learned This Way Comes</title>
		<link>https://jasonbrimhall.info/2014/11/11/tsql-tuesday-60-something-learned-this-way-comes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-tuesday-60-something-learned-this-way-comes</link>
					<comments>https://jasonbrimhall.info/2014/11/11/tsql-tuesday-60-something-learned-this-way-comes/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Nov 2014 18:56:38 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2574</guid>

					<description><![CDATA[<p>It is once again time to come together as a community and talk about a common theme.  This monthly gathering of the community has just reached it&#8217;s 5th anniversary.  Yes, that&#8217;s right.  We have been [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/11/11/tsql-tuesday-60-something-learned-this-way-comes/">TSQL Tuesday #60: Something Learned This Way Comes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://chrisyatessql.wordpress.com/2014/11/05/t-sql-tuesday-60-something-new-learned/"><img loading="lazy" class="alignleft wp-image-2309 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL2sDay150x150" width="150" height="150" /></a>It is once again time to come together as a community and talk about a common theme.  This monthly gathering of the community has just reached it&#8217;s 5th anniversary.  Yes, that&#8217;s right.  We have been doing this for 60 months or five years at this point.  That is pretty cool.</p>
<p>This month Chris Yates (<a href="http://chrisyatessql.wordpress.com/">blog </a>| <a href="http://twitter.com/yatessql">twitter</a>) has taken the helm to lead us in our venture to discuss all the wonderful things that we have learned.  Well, maybe not all the things we have learned, but at least to discuss something we have learned.</p>
<p>Here are some details from the actual invite that you can read <a href="http://chrisyatessql.wordpress.com/2014/11/05/t-sql-tuesday-60-something-new-learned/">here</a>.</p>
<blockquote><p>Why do we come to events, webinars, sessions, networking? The basic fundamental therein is to learn; community. With that said here is this month’s theme. You have to discuss one thing, few things, or many things on something new you&#8217;ve learned recently. It could be from a webinar, event, conference, or colleague. The idea is for seasoned vets to new beginners to name at least one thing; in doing so it might just help one of your fellow SQL friends within the community.</p></blockquote>
<p>The topic is straight forward but can be a bit difficult at times.  This is a pretty good topic to try and discuss.  I know I have been struggling for content for the topic.  Which makes it that much better because it provides a prime example of how to think about and discuss some pretty important things, while trying to compile that into a recap of one&#8217;s personal progress.</p>
<p>Let&#8217;s think about the topic for a bit and the timing of the topic.  This comes to us right on the heels of <a href="http://www.sqlpass.org/summit/2014/Home.aspx">PASS Summit 2014</a> and in the middle of <a href="https://devintersection.com/#!/">SQL Intersections</a> in Las Vegas.  We might as well throw in there all of the other things like SQL Saturdays that have been happening leading up to and following those major conferences.</p>
<p>There has been ample opportunity over the past few weeks to learn technical content.  When networking with people there are ample opportunities at these major conferences to also learn about other people and about one&#8217;s self.  A good example of that can be seen in a blog post I wrote while attending PASS Summit, which you can read <a href="http://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/">here</a>.</p>
<p>The biggest learning opportunity that evolved from PASS Summit 2014 for me was the constant prodding in various sessions to break out the debugger and become more familiar with what is happening in various cases.  I saw the debugger used in three of the sessions I attended.  There are some great opportunities to learn more about SQL Server by taking some trinket of information from a session and trying to put it to use in your development environment.  This is where learning becomes internalized and gives a deeper understanding.</p>
<p>I hope you have been able to pick up on some tidbit that can be used to your advantage to get a deeper understanding of SQL Server.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2574" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/11/11/tsql-tuesday-60-something-learned-this-way-comes/">TSQL Tuesday #60: Something Learned This Way Comes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/11/11/tsql-tuesday-60-something-learned-this-way-comes/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Summit 2014 &#8211; Next Impressions</title>
		<link>https://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=summit-2014-next-impressions</link>
					<comments>https://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 07 Nov 2014 18:49:13 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[PASS SUMMIT]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2568</guid>

					<description><![CDATA[<p>As Summit 2014 begins to wind down, it is time for some more impressions from the week.  The week has been good so far.  It has been very busy and also can be quite a [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/">Summit 2014 – Next Impressions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As Summit 2014 begins to wind down, it is time for some more impressions from the week.  The week has been good so far.  It has been very busy and also can be quite a drain mentally and physically from <em>everything</em> that has transpired.</p>
<p>If you are interested, I have written about some of my other impressions from the week, <a href="http://bit.ly/1u1RwIL">here</a>.</p>
<p>Several years ago, I <a href="http://jasonbrimhall.info/2010/05/24/content-copy-followup/">blogged about an incident with plagiarism</a> with both an original post and a follow-up.  I bring that up, not to rehash the negative, but instead to discuss an impression from this week.  If you read the follow-up, you will see that I had a chat, at that time, with Steinar (<a href="https://twitter.com/SQLSteinar">twitter</a>) about the problem and how to resolve it.  I met Steinar for the first time this week.  And to be honest, I had forgotten about the conflict and had removed the RSS feed since the original domain had gone down.</p>
<p>Anyway, Steinar and I had the chance to chat for the first time face to face this week.  Steinar, in my opinion, is a pretty cool guy that made a simple RSS mistake.  The impression is that he remembered me for how I treated him several years ago and was very appreciative of that.  How cool is that?  I really appreciate the opportunity to chat with him and that something I did left a positive impact on him.</p>
<p>Another opportunity is to be able to perform random acts of kindness or service while at Summit.  Much like helping Paul White learn how to use a smart phone, I had the even more rare opportunity to help Kalen Delaney (<a href="http://sqlblog.com/blogs/kalen_delaney/default.aspx" class="broken_link">blog </a>| <a href="https://twitter.com/sqlqueen">twitter</a>) out of a sticky situation.  It was a minor but frustrating thing that all of us run into from time to time.  The zipper on her Surface case had become stuck, so I helped her with that.  It&#8217;s a little thing but it is the type of thing that, if you are watching, you will see happening all over the place during the week of PASS Summit.</p>
<p>So, the next time you are at Summit, and while back in your local communities after the week has ended for Summit, keep an eye out for those little acts of kindness.  But at the same time, keep an eye out for those that might be watching you.  What kind of impression are you leaving for them or for the SQL Community?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2568" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/">Summit 2014 – Next Impressions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/11/07/summit-2014-next-impressions/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Ghosts &#8211; an eXtrasensory Experience</title>
		<link>https://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ghosts-an-extrasensory-experience</link>
					<comments>https://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 28 Oct 2014 19:25:19 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2540</guid>

					<description><![CDATA[<p>Really, at this point what is there that hasn't been done about the ghosts?  Well, if you are well tuned to these apparitions, you may have received the urge to explore them with Extended Events - sometimes called XE for short.</p>
The post <a href="https://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/">Ghosts – an eXtrasensory Experience</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/ghostrip_fire.png"><img loading="lazy" class="alignright wp-image-2541" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/ghostrip_fire-173x300.png" alt="ghostrip_fire" width="200" height="346" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostrip_fire-173x300.png 173w, https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostrip_fire.png 376w" sizes="(max-width: 200px) 85vw, 200px" /></a>This is the last article in a mini-series diving into the existence of ghosts and how to find them within your database.</p>
<p>So far this has been a fun and rewarding dive into Elysium to see and chat with these entities.  We have unearthed some means to be able to see these things manifesting themselves in the previous articles.  You can take a look at the <a href="http://bit.ly/rnnrGhosts1">previous articles here</a>.</p>
<p>For this article, I had planned to discuss another undocumented method to look into the ghost records and their existence based on what was said on an <a href="http://blogs.msdn.com/b/sqljourney/archive/2012/07/28/an-in-depth-look-at-ghost-records-in-sql-server.aspx">msdn blog</a>.  But after a lot of research, testing and finally reaching out to Paul Randal, I determined that won&#8217;t work.  So that idea was flushed all the way to Tartarus.</p>
<p>Let it be made very clear that DBTABLE does not offer a means to see the ghosts.  Paul and I agree that the other article that mentioned DBTABLE really should have been referring to DBCC Page instead.</p>
<p>Despite flushing the idea to Tartarus, it was not a fruitless dive.  It just was meaningless for the purpose of showing ghosts via that DBCC command.  I still gained value from the dive!!</p>
<p>All of that said, the remainder of the plan still applies and it should be fun.</p>
<p>Really, at this point what is there that hasn&#8217;t been done about the ghosts?  Well, if you are well tuned to these apparitions, you may have received the urge to explore them with Extended Events &#8211; sometimes called XE for short.</p>
<p>As has been done in the past, before we board Charon&#8217;s boat to cross the River Styx to Hades to find these ghosts in Elysium, one really needs to run the setup outlined <a href="http://bit.ly/rnnrGhosts1">here</a>.</p>
<p>With the framework in place, you are now ready to explore with XE.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT c.object_name as EventName,o.description as EventDescription
	FROM sys.dm_xe_objects o
		INNER JOIN sys.dm_xe_object_columns c 
			ON o.name = c.object_name
			and o.package_guid = c.object_package_guid
	WHERE object_type='event'
		AND c.name = 'channel'
		AND (o.description like '%ghost%'
			OR c.object_name like '%ghost%')
	Order By o.package_guid;</pre><p>Look at that! There are several possible events that could help us track these ghosts.  Or at the least we could get to know how these ghosts are handled deep down in the confines of Hades, err I mean the database engine.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/Ghost_XE.png"><img loading="lazy" class="aligncenter wp-image-2543" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/Ghost_XE.png" alt="Ghost_XE" width="600" height="117" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/Ghost_XE.png 1006w, https://jasonbrimhall.info/wp-content/uploads/2014/10/Ghost_XE-300x58.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/Ghost_XE-50x9.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>From these possible events, I opted to work with ghost_cleanup and ghost_cleanup_task_process_pages_for_db_packet.  The sessions I defined to trap our ghost tracks are as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION [GhostHunt] ON SERVER 
ADD EVENT sqlserver.ghost_cleanup(
    ACTION (sqlserver.database_name,sqlserver.client_hostname,sqlserver.client_app_name,
            sqlserver.plan_handle,
            sqlserver.sql_text,
			sqlserver.query_hash,
			sqlserver.session_id)
    WHERE ([sqlserver].[equal_i_sql_unicode_string]([sqlserver].[database_name],N'Cemetery'))
    AND sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense')
ADD TARGET package0.histogram(SET filtering_event_name=N'sqlserver.ghost_cleanup', source = 'database_name')
WITH (MAX_DISPATCH_LATENCY=5SECONDS, TRACK_CAUSALITY=ON)

CREATE EVENT SESSION [SoulSearch] ON SERVER 
ADD EVENT sqlserver.ghost_cleanup_task_process_pages_for_db_packet(
    ACTION (sqlserver.database_name,sqlserver.client_hostname,sqlserver.client_app_name,
            sqlserver.plan_handle,
            sqlserver.sql_text,
 			sqlserver.query_hash,
			sqlserver.session_id)
    WHERE sqlserver.client_app_name &lt;&gt; 'Microsoft SQL Server Management Studio - Transact-SQL IntelliSense')
ADD TARGET package0.ring_buffer
WITH (MAX_DISPATCH_LATENCY=5SECONDS, TRACK_CAUSALITY=ON)
GO</pre><p>You can see there are two sessions defined for this trip down the Styx.  Each session aptly named for our journey.  The first (GhostHunt) is defined to trap ghost_cleanup and sends that information to a histogram target.  The second (SoulSearch) is defined to use the other event, and is configured to send to the ring_buffer.  Since the second event has a &#8220;count&#8221; field defined as a part of the event, it will work fine to just send it to the ring buffer for later evaluation.</p>
<p>Once I have the traps, I mean event sessions defined, I can now resume the test harness from the delete step as was previously done in previous articles.  The following Delete is what I will use.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Somebody made a mistake and thought Halloween was Oct 30 instead of Oct 31 
we need to kill those records
*/

Delete top(666)
	From Halloween.Ghosts
	WHERE Slimer = '10/30/2014';</pre><p>Prior to running that delete though, I checked the Event Session data to confirm a starting baseline.  Prior to the delete, I had the following in my histogram target.</p>
<p>&nbsp;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/predelete_count.png"><img loading="lazy" class="alignnone wp-image-2544 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/predelete_count.png" alt="predelete_count" width="283" height="65" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/predelete_count.png 283w, https://jasonbrimhall.info/wp-content/uploads/2014/10/predelete_count-50x11.png 50w" sizes="(max-width: 283px) 85vw, 283px" /></a></p>
<p>&nbsp;</p>
<p>After running the delete, and checking my histogram again, I see the following results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/post_count.png"><img loading="lazy" class="alignnone wp-image-2545 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/post_count.png" alt="post_count" width="281" height="61" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/post_count.png 281w, https://jasonbrimhall.info/wp-content/uploads/2014/10/post_count-50x10.png 50w" sizes="(max-width: 281px) 85vw, 281px" /></a></p>
<p>&nbsp;</p>
<p>You can see from this that in addition to the 25 pre-existing ghosts, we had another 672 ghosts (666 of which were from the delete).</p>
<p>This is how I was able to investigate the GhostHunt Extended Event Histogram.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Query the histogram */
SELECT 
    n.value('(value)[1]', 'nvarchar(60)') AS database_name,
    n.value('(@count)[1]', 'bigint') AS ghost_count
FROM
(SELECT CAST(target_data as XML) target_data
 FROM sys.dm_xe_sessions AS s 
 JOIN sys.dm_xe_session_targets t
     ON s.address = t.event_session_address
 WHERE s.name = 'GhostHunt'
  AND t.target_name = 'histogram' ) as tab
CROSS APPLY target_data.nodes('HistogramTarget/Slot') as q(n)
;</pre><p>But what about looking at the other event session?</p>
<p>Let&#8217;s look at how we can go and investigate that session first and then look at some of the output data.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    event_data.value('(event/@name)[1]', 'varchar(50)') AS event_name
    ,CAST(event_data.value('(event/action[@name="plan_handle"]/value)[1]', 'varchar(max)') AS XML) as plan_handle
    ,event_data.value('(event/data[@name="first_ghost_page_page_id"]/value)[1]', 'bigint') AS FirstPage_PageID
	,event_data.value('(event/data[@name="last_ghost_page_page_id"]/value)[1]', 'bigint') AS LastPage_PageID
	,event_data.value('(event/data[@name="ghost_page_count"]/value)[1]','int') as GhostPageCount
	,db_name(event_data.value('(event/data[@name="database_id"]/value)[1]','int')) as DBName
FROM(    SELECT evnt.query('.') AS event_data
        FROM
        (    SELECT CAST(target_data AS xml) AS TargetData
            FROM sys.dm_xe_sessions AS s
            INNER JOIN sys.dm_xe_session_targets AS t
                ON s.address = t.event_session_address
            WHERE s.name = 'SoulSearch'
              AND t.target_name = 'ring_buffer'
        ) AS tab
        CROSS APPLY TargetData.nodes ('RingBufferTarget/event') AS split(evnt) 
    ) AS evts(event_data)
WHERE event_data.value('(event/@name)[1]', 'varchar(50)') = 'ghost_cleanup_task_process_pages_for_db_packet';</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean.png"><img loading="lazy" class="aligncenter size-large wp-image-2546" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean-1024x165.png" alt="ghostclean" width="560" height="90" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean-1024x165.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean-300x48.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean-50x8.png 50w, https://jasonbrimhall.info/wp-content/uploads/2014/10/ghostclean.png 1067w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>Cool!  Querying the SoulSearch session has produced some information for various ghosts in the database.  Unlike the histogram session that shows how many ghosts have been cleaned, this session shows us some page ids that could contain some ghosts &#8211; in the present.  I can take page 1030111 for instance and examine the page with DBCC PAGE as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC PAGE('cemetery',1,1030111,3) with TABLERESULTS;</pre><p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/pagealt.png"><img loading="lazy" class="aligncenter wp-image-2548" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/pagealt.png" alt="pagealt" width="600" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/pagealt.png 976w, https://jasonbrimhall.info/wp-content/uploads/2014/10/pagealt-300x86.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/pagealt-50x14.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>Look at that page and result!! We have found yet another poltergeist.</p>
<h3>RIP</h3>
<p>Once again we have been able to journey to the depths of the Database engine and explore the ghosts that might be there.  This just happens to illustrate a possible means to investigate those ghosts.  That said, I would not necessarily run these types of event sessions on a persistent basis.  I would only run these sessions if there seems to be an issue with the Ghost cleanup or if you have a strong penchant to learn (on a sandbox server).</p>
<p>Some good information can be learned.  It can also give a little insight into how much data is being deleted on a routine basis from your database.  As a stretch, you could even possibly use something like this to get a handle on knowing the data you support.  Just be cautious with the configuration of the XE and understand that there could be a negative impact on a very busy server.  And certainly proceed at your own risk.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2540" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/">Ghosts – an eXtrasensory Experience</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/10/28/ghosts-an-extrasensory-experience/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Database Ghosts</title>
		<link>https://jasonbrimhall.info/2014/10/22/database-ghosts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-ghosts</link>
					<comments>https://jasonbrimhall.info/2014/10/22/database-ghosts/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 22 Oct 2014 22:16:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[Halloween]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2523</guid>

					<description><![CDATA[<p>Recently you may have seen my first article on this topic over at SQL Solutions Group.  If not, here is the link so you can read that article first before proceeding here.  This article is [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/10/22/database-ghosts/">Database Ghosts</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignright wp-image-2529" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip.png" alt="phantasmrip" width="200" height="346" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip.png 376w, https://jasonbrimhall.info/wp-content/uploads/2014/10/phantasmrip-173x300.png 173w" sizes="(max-width: 200px) 85vw, 200px" />Recently you may have seen my first article on this topic over at SQL Solutions Group.  If not, <a href="http://bit.ly/ssgghost">here is the link so you can read that article first</a> before proceeding here.  This article is intended as a first of two part follow-up to that <a href="http://bit.ly/ssgghost">article</a>.</p>
<p>Now that you have read that other article, we can recap it a little bit.</p>
<p>You will recall that in that article, I discussed the presence of Ghosts in your database.  I also discussed that those ghosts are a good thing.  They have some benefits to them, of which is a bit of a performance boost for some operations like the rollback of a delete.</p>
<p>In that article I discussed one method with which you could see these ghost records.  In this article, I would like to share an alternate method to be able to see these ghosts.</p>
<p>In order to explore this alternate means, let&#8217;s go ahead and follow the first few steps from the other article to get the setup complete so our second ghost hunting foray can begin.</p><pre class="urvanov-syntax-highlighter-plain-tag">Use master;
Go
IF DB_ID('Cemetery') IS NULL 
BEGIN
 EXECUTE ('CREATE DATABASE Cemetery');
 ALTER DATABASE [Cemetery] SET RECOVERY SIMPLE WITH NO_WAIT
 ALTER DATABASE [Cemetery] MODIFY FILE ( NAME = N'Cemetery', SIZE = 6144000KB , FILEGROWTH = 262144KB )
 ALTER DATABASE [Cemetery] MODIFY FILE ( NAME = N'Cemetery_log', SIZE = 131072KB , FILEGROWTH = 131072KB )
END
GO
Use Cemetery;
Go

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
IF SCHEMA_ID('Halloween') IS NULL EXECUTE ('CREATE SCHEMA Halloween');
GO

IF OBJECT_ID('Halloween.Ghosts','U') IS NOT NULL
BEGIN
DROP TABLE Halloween.Ghosts
END
GO


DECLARE @BeginDate DATE = '2014-10-01'
		,@EndDate DATE = '2014-10-31'

 SELECT TOP 1000000
        Pinky       = IDENTITY(INT,1,1),
        Blinky		= 'GHOST ITEM ' + CONVERT(VARCHAR(20),ISNULL('', 0)),
        CandyMan	= ABS(CHECKSUM(NEWID()))%50000+1,
        Sadako		= CHAR(ABS(CHECKSUM(NEWID()))%26+65)
                     + CHAR(ABS(CHECKSUM(NEWID()))%26+65),
        Slimer		= DATEADD(DAY,RAND(CHECKSUM(NEWID())) * ( 1 + DATEDIFF(DAY, @EndDate,@BeginDate) ), @EndDate),
        Poltergeist	= RIGHT(NEWID(),12),
        MalcomCrowe	= CAST(ABS(CHECKSUM(NEWID()))%10000 /100.0 AS MONEY),
        TheBlob		= REPLICATE('Hey, Dracula!! Why do you say blah, blah blah?',1000)
   INTO Halloween.Ghosts
   FROM Master.dbo.SysColumns t1,
        Master.dbo.SysColumns t2 --Lack of join criteria makes this a CROSS-JOIN

/* let's get our Blinky updated properly */
Update hg
	Set Blinky = 'GHOST ITEM ' + CONVERT(VARCHAR(20),ISNULL(Pinky, 0))
	From Halloween.Ghosts hg;

--===== A table is not properly formed unless a Primary Key has been assigned
     -- Takes about 1 second to execute.
  ALTER TABLE Halloween.Ghosts
        ADD PRIMARY KEY CLUSTERED (Pinky)

/* additional index to show the ghosts */

Create NonClustered Index IX_GhostPinky on Halloween.Ghosts (Pinky)</pre><p>Now with the setup complete, we should once again confirm that we have appropriate data available for the hunt.  Once again a simple query can suffice to show the data.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Take a peek at the data */
Select top 100 *
	From Halloween.Ghosts</pre><p>Upon execution of the check script, we should see something similar to the following data-set.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/datasample.png"><img loading="lazy" class="aligncenter size-full wp-image-2530" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/datasample.png" alt="datasample" width="630" height="414" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/datasample.png 630w, https://jasonbrimhall.info/wp-content/uploads/2014/10/datasample-300x197.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/datasample-50x32.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>Great, the data is confirmed and we should have a wonderful chance to find some ghosts once again.  In the previous attempt, we needed an additional plasma blaster in the form of a trace flag.  In this attempt we will hunt these ghosts without that tool and see what we can find.  Why attempt it in this way?  Well, it is simply because I&#8217;d rather not use a trace flag if it is not necessary.  If you recall, that trace flag had a couple of noted effects.  One of the effects was that it turned off the ghost cleanup process.  If I can avoid it, I&#8217;d rather leave the containment unit in tact.</p>
<p>Now, due to that clerical error of putting Halloween on the wrong date, we need to follow the prescribed policy to delete records prior to creating the proper records.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Somebody made a mistake and thought halloween was Oct 30 instead of Oct 31 
we need to kill those records
*/
Begin tran
Delete top(666)
	From Halloween.Ghosts
	WHERE Slimer = '10/30/2014';</pre><p>Notice that we issued the delete in a transaction this time around.  We are going to leave that transaction open for a bit while we hunt those ghosts.</p>
<p>The first step is to verify that some ghosts might be present.  To do that we should run a query such as the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* ghost_record_count */
Set transaction Isolation level read uncommitted
SELECT DB_NAME(database_id) AS DBName,schema_name(so.schema_id) + '.' + so.name as ObjName, record_count,index_type_desc
	,ghost_record_count,version_ghost_record_count
FROM sys.dm_db_index_physical_stats(db_id('Cemetery'), OBJECT_ID('Halloween.Ghosts'), NULL, NULL , 'DETAILED') ps
	INNER JOIN sys.objects so
		ON ps.object_id = so.object_id
WHERE index_level = 0
	;</pre><p>From that query we should see something like the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/idxstats_ghosts.png"><img loading="lazy" class="aligncenter wp-image-2531" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/idxstats_ghosts.png" alt="idxstats_ghosts" width="700" height="74" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/idxstats_ghosts.png 827w, https://jasonbrimhall.info/wp-content/uploads/2014/10/idxstats_ghosts-300x31.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/idxstats_ghosts-50x5.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Once again we are on the right track.  We can further confirm the existence of these ghosts through a little more investigation and monitoring.  Let&#8217;s try the trick with the dblog function again.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Use Fn_dblog to get Pages with Ghost Counts..works with TF 661 or an uncommitted tx */
Select Operation,Context,[Transaction ID],[Page ID] AS [File:PageIDHex],AllocUnitId,[Slot ID],PartitionId
		,CONVERT(INT,CONVERT(VARBINARY,'0x' + RIGHT([Page ID], 8),1)) AS PageID
	From fn_dblog(null,null) fn
	Where CONTEXT = 'LCX_MARK_AS_GHOST';</pre><p>With that query, we should see something like the following result set.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts.png"><img loading="lazy" class="aligncenter wp-image-2532" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts-1024x314.png" alt="dblog_ghosts" width="700" height="215" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts-1024x314.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts-300x92.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts-50x15.png 50w, https://jasonbrimhall.info/wp-content/uploads/2014/10/dblog_ghosts.png 1279w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>Very cool.  We once again can see that these phantasms are in the database.  We have enough information that we can proceed on to the next stage.  We can pass the PageID into DBCC PAGE in order to investigate the ghosts on the page.  If we use the PageID that is circled with the green in the preceding result set, we can get a better feel for these specters.</p><pre class="urvanov-syntax-highlighter-plain-tag">DBCC PAGE('Cemetery',1,2002440,3) WITH TABLERESULTS
GO</pre><p>And we may see results such as the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/page_ghosts2.png"><img loading="lazy" class="aligncenter wp-image-2537" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/page_ghosts2.png" alt="page_ghosts2" width="700" height="195" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/page_ghosts2.png 1009w, https://jasonbrimhall.info/wp-content/uploads/2014/10/page_ghosts2-300x83.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/page_ghosts2-50x13.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Recall that the log says this page has ghost records on it.  When we check the page with DBCC PAGE we can definitely see that there are ghosts on the page.  This is very cool.  Now, had we tried to check for ghost records on the PFS page we would not be able to see the ghost count like we were able to see by enabling the TF.</p>
<p>Once again we have been able to display the existence of ghosts in the database.  In order to get these ghosts to move on from the database to their afterlife, we merely need to commit the transaction or roll back the transaction.</p>
<p>Stay tuned for the next article in this mini-series about ghosts.  Who knows, we may even have a bonus Halloween article since this is Halloween month.</p>
<p><a href="http://bit.ly/rnnrGhosts2">Part III of the series can now be found here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2523" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/10/22/database-ghosts/">Database Ghosts</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/10/22/database-ghosts/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Murder In Utah</title>
		<link>https://jasonbrimhall.info/2014/10/14/murder-in-utah/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-in-utah</link>
					<comments>https://jasonbrimhall.info/2014/10/14/murder-in-utah/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 14 Oct 2014 20:18:31 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQL Saturday]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2519</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/10/14/murder-in-utah/">Murder In Utah</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike.png"><img loading="lazy" class="aligncenter size-large wp-image-2520" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike-1024x577.png" alt="goldspike" width="560" height="315" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike-1024x577.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike-300x169.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike-50x28.png 50w, https://jasonbrimhall.info/wp-content/uploads/2014/10/goldspike.png 1600w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>&nbsp;</p>
<p>Time to sink or sail, so to speak.  <a href="http://sqlsaturday.com/349/eventhome.aspx">SQL Saturday 349</a> in Utah will mark the next attempt at what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in this all day workshop event.  The session is one of two all day sessions for the event in Lehi, UT (just south of Salt Lake City).</p>
<p>If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3>Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" alt="wayne" width="141" height="211" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at <a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" alt="JasonBrimhall" width="141" height="211" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" class="aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" alt="kaboom" width="301" height="167" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us.  You can find registration information and event details at the Salt Lake City SQL Saturday site &#8211; <a href="https://www.sqlsaturday.com/349/eventhome.aspx">here</a>.  There are only 75 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>The cost for the class is $150 (plus fees) up through the day of the event.  <a title="Registration" href="http://bit.ly/1w5nJ0j" target="_blank">When you register</a>, be sure to tell your coworkers and friends.</p>
<h3>Wait, there&#8217;s more&#8230;</h3>
<p>Not only will I be in Utah for this workshop, I will also be presenting as a part of the SQLSaturday event on October 25, 2014 (the day after the workshop which is Oct. 24, 2014).  You can view the available sessions <a href="https://www.sqlsaturday.com/349/schedule.aspx">here</a>.</p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some workshop sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2519" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/10/14/murder-in-utah/">Murder In Utah</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/10/14/murder-in-utah/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>October 2014 Las Vegas UG Meeting</title>
		<link>https://jasonbrimhall.info/2014/10/08/october-2014-las-vegas-ug-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=october-2014-las-vegas-ug-meeting</link>
					<comments>https://jasonbrimhall.info/2014/10/08/october-2014-las-vegas-ug-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 08 Oct 2014 12:05:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2511</guid>

					<description><![CDATA[<p>The Las Vegas User Group is happy to announce our monthly meeting.  The meeting is available for in person and webinar style.  The start time is 6:30 PM Pacific and the details are listed in [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/10/08/october-2014-las-vegas-ug-meeting/">October 2014 Las Vegas UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>The Las Vegas User Group is happy to announce our monthly meeting.  The meeting is available for in person and webinar style.  The start time is 6:30 PM Pacific and the details are listed in this post.  We hope to see you there!</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/invite_oct2014.png"><img loading="lazy" class="aligncenter wp-image-2512" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/invite_oct2014.png" alt="invite_oct2014" width="800" height="302" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/invite_oct2014.png 980w, https://jasonbrimhall.info/wp-content/uploads/2014/10/invite_oct2014-300x113.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/invite_oct2014-50x18.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>This month we have a special treat brought to us by fellow MVP Argenis Fernandez (<a href="http://sqlblog.com/blogs/argenis_fernandez/default.aspx" class="broken_link">blog </a>| <a href="https://twitter.com/DBArgenis">twitter</a>).  If you had a devilish little trick to upgrade SQL Server without an outage, would you do it?  Argenis will show you a good set of tricks to put your upgrade nightmares to rest.</p>
<p>You can read all about what Argenis is planning to present and read all about Argenis on our meetup page (http://www.meetup.com/SQL-Server-Society-of-Las-Vegas/events/211325962/).</p>
<p>We hope to see you either in person or virtually for our monthly UG installment.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2511" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/10/08/october-2014-las-vegas-ug-meeting/">October 2014 Las Vegas UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/10/08/october-2014-las-vegas-ug-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft, Me and the MVP</title>
		<link>https://jasonbrimhall.info/2014/10/02/microsoft-me-and-the-mvp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=microsoft-me-and-the-mvp</link>
					<comments>https://jasonbrimhall.info/2014/10/02/microsoft-me-and-the-mvp/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 02 Oct 2014 21:17:55 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[MVP]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2502</guid>

					<description><![CDATA[<p>October 1st is one of the quarterly dates that Microsoft announces all of the new people into the MVP program.  It is also a day in which Microsoft recognizes many already in the program and [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/10/02/microsoft-me-and-the-mvp/">Microsoft, Me and the MVP</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/10/Microsoft_MVP_logo_thumb.png"><img loading="lazy" class="alignleft wp-image-2508 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/Microsoft_MVP_logo_thumb.png" alt="Microsoft_MVP_logo_thumb" width="124" height="195" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/Microsoft_MVP_logo_thumb.png 124w, https://jasonbrimhall.info/wp-content/uploads/2014/10/Microsoft_MVP_logo_thumb-31x50.png 31w" sizes="(max-width: 124px) 85vw, 124px" /></a>October 1st is one of the quarterly dates that Microsoft announces all of the new people into the MVP program.  It is also a day in which Microsoft recognizes many already in the program and renews their status for the upcoming year.</p>
<p>This time around, I had the distinct honor and pleasure of joining the ranks of so many people who have been a part of this program for some time or who might have also been recently named to the program.</p>
<p>The MVP program is a program designed to recognize people for their efforts in teaching about various Microsoft technologies.  In my case, that happens to be SQL Server.  It is a humbling feeling to have been nominated and to be welcomed into the program.</p>
<p>To top it all off, I found it really cool that my welcome letter came in French rather than the standard English.  This is perfectly acceptable to me since it is a language I speak fluently and do try to keep up to date with it.  It was also interesting to see the MVP Lead call me within minutes of receipt of one of NDA email to make sure it was ok.  He was thrown by the NDA being in French and was concerned whether I could understand it or not.  At which point we had a good chuckle because I had no qualms with the language in use.</p>
<p>Attached are a couple of screen grabs with the welcome letter and so forth.  I geek out every time I look at them and it is totally cool.</p>
<p>In addition, I have also attached a link to my updated MVP profile.  You can find that <a href="https://mvp.microsoft.com/en-us/mvp/Jason%20Brimhall-5001062">here</a>.</p>
<p><a href="https://mvp.microsoft.com/en-us/mvp/Jason%20Brimhall-5001062"><img loading="lazy" class="aligncenter wp-image-2504" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/notice.png" alt="notice" width="900" height="307" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/notice.png 1262w, https://jasonbrimhall.info/wp-content/uploads/2014/10/notice-300x102.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/notice-1024x348.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/10/notice-50x17.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<h3><a href="https://mvp.microsoft.com/en-us/mvp/Jason%20Brimhall-5001062"><img loading="lazy" class="aligncenter wp-image-2503 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/10/Congrats.png" alt="Congrats" width="859" height="494" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/10/Congrats.png 859w, https://jasonbrimhall.info/wp-content/uploads/2014/10/Congrats-300x172.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/10/Congrats-50x28.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a>So what does it mean now that I am an MVP?</h3>
<p>Well, to be truthful, it means status quo.  Having this means that a recognition was given.  It also means that, in my opinion, I am on the right track in doing good things for the community.  Because of that, I will continue to do what I can where and when I can to help teach others about SQL Server.  I am indeed grateful to be in pretty good company with people who also try to teach about SQL Server.</p>
<p>To all who helped this happen, I am grateful for your support.</p>
<p>I am also grateful to SQL Solutions Group who first broke the news.  You can read about that <a href="http://www.sqlsolutionsgroup.com/jason-brimhall-mvp/">here</a>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2502" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/10/02/microsoft-me-and-the-mvp/">Microsoft, Me and the MVP</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/10/02/microsoft-me-and-the-mvp/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>September 2014 Las Vegas UG Meeting</title>
		<link>https://jasonbrimhall.info/2014/09/10/september-2014-las-vegas-ug-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=september-2014-las-vegas-ug-meeting</link>
					<comments>https://jasonbrimhall.info/2014/09/10/september-2014-las-vegas-ug-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 10 Sep 2014 16:02:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2490</guid>

					<description><![CDATA[<p>Who is up for a little free learning this week? Besides the opulence and feast that was the 24 Hours of PASS (Summit Preview), we have more training in store for you from the people [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/09/10/september-2014-las-vegas-ug-meeting/">September 2014 Las Vegas UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Who is up for a little free learning this week? Besides the opulence and feast that was the <a href="http://www.sqlpass.org/24hours/2014/summitpreview/About.aspx">24 Hours of PASS</a> (Summit Preview), we have more training in store for you from the people in Las Vegas. Let&#8217;s call this a preview for next week which happens to be <a href="http://www.devconnections.com/Dev14/public/enter.aspx">DevConnections</a> (which also happens to be in Vegas)!!</p>
<p>The Las Vegas User Group is happy to announce our monthly meeting.  The meeting is available for in person and webinar style.  The start time is 6:30 PM Pacific and the details are listed in this post.  We hope to see you there!</p>
<p><a href="https://web.archive.org/web/20150108214303/http://www.meetup.com:80/SQL-Server-Society-of-Las-Vegas/events/196294192/"><img loading="lazy" class="aligncenter wp-image-2491" src="http://jasonbrimhall.info/wp-content/uploads/2014/09/Capture.png" alt="Capture" width="600" height="321" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/09/Capture.png 814w, https://jasonbrimhall.info/wp-content/uploads/2014/09/Capture-300x160.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/09/Capture-50x26.png 50w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<h3>Abstract: PowerShell: The Way of the DBA Dragon</h3>
<p>In this introduction to PowerShell, attendees will learn how to start from scratch with PowerShell 3.0 or newer, use the pipeline, run T-SQL against multiple instances, use transcripts, and be shown martial arts usage of one of the SQLPSX cmdlets.  Scripts will be provided.</p>
<h3>BIO</h3>
<p>Lars Rasmussen was born in Illinois, but considers Utah home.  He does not play video games, is learning to camp and hike, and is happy to have shared the summit of Mt. Timpanogos with two of his sons.  Lars&#8217; wife and four children help him smile and laugh, and the family dog is teaching him patience.  Playing board games is one his favorite pastimes.  He considers SQL Server, PowerShell, and CMD.EXE some of his dearest frenemies.  Lars enjoys the company of SQL Server professionals and sysadmins &#8211; he used to be one of the latter, and is employed as a database administrator for HealthEquity.</p>
<h3>LiveMeeting Info</h3>
<p><b>Attendee URL</b>: <a>https://www.livemeeting.com/cc/UserGroups/join?id=MR7C92&amp;role=attend</a></p>
<p><b>Meeting ID</b>: MR7C92</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2490" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/09/10/september-2014-las-vegas-ug-meeting/">September 2014 Las Vegas UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/09/10/september-2014-las-vegas-ug-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Effects of sp_rename on Stored Procedures</title>
		<link>https://jasonbrimhall.info/2014/08/14/effects-of-sp_rename-on-stored-procedures/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=effects-of-sp_rename-on-stored-procedures</link>
					<comments>https://jasonbrimhall.info/2014/08/14/effects-of-sp_rename-on-stored-procedures/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 14 Aug 2014 18:29:26 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2472</guid>

					<description><![CDATA[<p>There comes a time when mistakes are made.  Sometimes those mistakes can be as annoying as a spelling mistake during the creation of a stored procedure.  When a mistake such as that happens, we are [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/14/effects-of-sp_rename-on-stored-procedures/">Effects of sp_rename on Stored Procedures</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>There comes a time when mistakes are made.  Sometimes those mistakes can be as annoying as a spelling mistake during the creation of a stored procedure.  When a mistake such as that happens, we are given a few choices.  One could either rename the stored procedure, drop and recreate the stored procedure or simply leave the mistake alone.</p>
<p>When choosing to rename the stored procedure, one may quickly reach for the stored procedure that can be readily used for renaming various objects.  That procedure was provided by Microsoft after-all and is named sp_rename.  Reaching for that tool however might be a mistake.  Here is what is <a href="http://msdn.microsoft.com/en-us/library/ms188351.aspx">documented</a> about the use of sp_rename to rename a stored procedure.  That documentation can be read at this <a href="http://msdn.microsoft.com/en-us/library/ms188351.aspx">link </a>on MSDN.</p>
<blockquote><p><span style="color: #2a2a2a;">We recommend you do not use this statement to rename stored procedures, triggers, user-defined functions, or views; instead, drop the object and re-create it with the new name.</span></p></blockquote>
<p>And later in the same documentation, one can read the following.</p>
<blockquote><p><span style="color: #2a2a2a;">Renaming a stored procedure, function, view, or trigger will not change the name of the corresponding object name in the definition column of the </span><a style="color: #03697a;" href="http://msdn.microsoft.com/en-us/library/ms175081.aspx">sys.sql_modules</a><span style="color: #2a2a2a;"> catalog view. Therefore, we recommend that sp_rename not be used to rename these object types. Instead, drop and re-create the object with its new name.</span></p></blockquote>
<p>Now, a chief complaint against dropping and recreating the stored procedure, as recommended, is that process can cause permissions issues.  I am less concerned about the permissions issues and see that as more of a nuisance that is easily overcome due to great documentation and a few quick script executions to restore the permissions.  Despite that, I think we might have a means to address the rename and permissions issue that will be shared later in this article.</p>
<h3>Using sp_rename</h3>
<p>When using sp_rename, it would be good to understand what happens and what one might expect to see.  Let&#8217;s use the following script to create a stored procedure to step through an exercise to rename a stored procedure and evaluate the results.</p><pre class="urvanov-syntax-highlighter-plain-tag">IF EXISTS (SELECT name FROM sys.objects WHERE name = 'Renamed')
DROP PROCEDURE Renamed
GO

/* This proc is created to search for column names
-- throughout a database
*/
CREATE PROCEDURE RenameMe @objname VARCHAR(50)
AS

SELECT o.name AS TableName,c.name AS ColumnName,t.name AS DataType
	FROM sys.objects o
		INNER JOIN sys.columns c
			ON o.object_id = c.object_id
		INNER JOIN sys.types t
			ON c.user_type_id = t.user_type_id
	WHERE c.name = @objname
		AND o.type = 'u'

GO

SELECT object_id,OBJECT_NAME(sm.object_id) AS ObjName
		,definition AS ProcDefinition
	FROM sys.sql_modules sm
	WHERE OBJECT_NAME(sm.object_id) = 'RenameMe';
GO

SELECT so.object_id, so.name
		, OBJECT_NAME(so.object_id) AS FuncObjName
		, OBJECT_ID('RenameMe') AS FuncObjID
	FROM sys.objects so
	WHERE so.name = 'RenameMe';
GO

EXECUTE sp_rename 'RenameMe','Renamed'
GO

SELECT object_id,OBJECT_NAME(sm.object_id) AS ObjName
		,definition AS ProcDefinition
	FROM sys.sql_modules sm
	WHERE OBJECT_NAME(sm.object_id) = 'Renamed';
GO

SELECT so.object_id, so.name
		, OBJECT_NAME(so.object_id) AS FuncObjName
		, OBJECT_ID('Renamed') AS FuncObjID
	FROM sys.objects so
	WHERE so.name = 'Renamed';
GO</pre><p>When I execute that series of batches, I will get an output that matches the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/renameme.png"><img loading="lazy" class="aligncenter wp-image-2476" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/renameme.png" alt="renameme" width="600" height="516" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/renameme.png 700w, https://jasonbrimhall.info/wp-content/uploads/2014/08/renameme-300x258.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>When looking at the results we can see that the use of sp_rename does indeed change the name of the stored procedure as it is represented via sys.objects and metadata.  We can also see that the definition of the stored procedure does not change as it is held within the metadata.</p>
<p>If I choose to check the definition through the use of OBJECT_DEFINITION()  instead of sys.sql_modules, you will be pleased to know that sys.sql_modules calls OBJECT_DEFINITION() to produce the definition that is seen in the catalog view.</p>
<p>Well, that does pose a potential problem.  We see that the object definition is unchanged and may report the name as being different than what the object name truly is.  What happens if I execute the stored procedure?  Better yet, if I can execute the stored procedure and then capture the sql text associated to that plan, what would I see?</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Now let's get an execution plan for the proc
-- and see what the query text is related to that plan
*/
EXECUTE Renamed 'Last Update Date'
GO</pre><p>Yes!  The renamed stored procedure does indeed execute properly.  I even get three results back for that execution.  Better yet, I get an execution plan which I can pull a plan_hash from in order to evaluate the sql text associated to the plan.  In case you are wondering, the execution plan does contain the statement text of the procedure.  But for this case, I want to look at the entire definition associated to the plan rather than the text stored in the plan.  In this particular scenario, I only see the body of the procedure and not the create statement that is held in metadata.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/plan.png"><img loading="lazy" class="aligncenter wp-image-2477" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/plan-300x138.png" alt="plan" width="400" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/plan-300x138.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/08/plan.png 763w" sizes="(max-width: 400px) 85vw, 400px" /></a></p>
<p>For this particular execution and plan, I can see a plan_hash of 0xE701AFB2D865FA71.  I can now take this and provide it to the following query to find the full proc definition from metadata.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Look at the execution plan and get a query_plan_hash from the plan xml */
SELECT qs.query_plan_hash,t.text,t.objectid
	FROM sys.dm_exec_query_stats qs
	CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) t
		WHERE qs.query_plan_hash = 0xE701AFB2D865FA71
		--where 0xE701AFB2D865FA71 was the hash for the proc we
		--renamed.
GO</pre><p>And after executing that query, I can see results similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/execplancache_text.png"><img loading="lazy" class="aligncenter wp-image-2478" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/execplancache_text.png" alt="execplancache_text" width="600" height="139" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/execplancache_text.png 686w, https://jasonbrimhall.info/wp-content/uploads/2014/08/execplancache_text-300x69.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>Now is that because in some way the query that was just run was also running OBJECT_DEFINITION()?  Let&#8217;s look at the execution plan for both OBJECT_DEFINITION() and the query that was just run.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Only produces an estimated plan - not an actual plan */
SELECT OBJECT_DEFINITION(OBJECT_ID('Renamed'))
GO</pre><p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/obj_def_plan.png"><img loading="lazy" class="aligncenter size-full wp-image-2479" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/obj_def_plan.png" alt="obj_def_plan" width="443" height="208" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/obj_def_plan.png 443w, https://jasonbrimhall.info/wp-content/uploads/2014/08/obj_def_plan-300x140.png 300w" sizes="(max-width: 443px) 85vw, 443px" /></a></p>
<p>&nbsp;</p>
<p>Looking at the XML for that particular plan and we see xml supporting that plan.  There is no further function callout and the plan is extremely simple.</p>
<p>Now looking at the plan for the query involving the query_plan_hash we will see the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/fngetsql.png"><img loading="lazy" class="aligncenter wp-image-2480" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/fngetsql.png" alt="fngetsql" width="601" height="242" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/fngetsql.png 638w, https://jasonbrimhall.info/wp-content/uploads/2014/08/fngetsql-300x120.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>&nbsp;</p>
<p>Looking at this graphical plan, we can see that we are calling FNGETSQL.  Looking at the XML for this plan, we can verify that FNGETSQL is the only function call to retrieve the full sql text associated to this plan execution.  FNGETSQL is an internal function for SQL server used to build internal tables that might be used by various DMOs.  You can read just a bit more about that <a href="http://jasonbrimhall.info/2012/01/17/a-trio-of-functions/">here</a>.</p>
<h3>What now?</h3>
<p>After all of that, it really looks pessimistic for sp_rename.  The procedure renames but does not properly handle metadata and stored procedure definitions.  So does that mean we are stuck with drop and create as the Microsoft documentation suggests?</p>
<p>If you have access to the full procedure definition you could issue an alter statement.  In the little example that I have been using, I could issue the following statement.</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER PROCEDURE Renamed @objname VARCHAR(50)
AS

SELECT o.name AS TableName,c.name AS ColumnName,t.name AS DataType
	FROM sys.objects o
		INNER JOIN sys.columns c
			ON o.object_id = c.object_id
		INNER JOIN sys.types t
			ON c.user_type_id = t.user_type_id
	WHERE c.name = @objname
		AND o.type = 'u'

GO</pre><p>After executing that script, I could check sys.sql_modules once again and find a more desirable result.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT object_id,OBJECT_NAME(sm.object_id) AS ObjName
		,definition AS ProcDefinition
	FROM sys.sql_modules sm
	WHERE OBJECT_NAME(sm.object_id) = 'Renamed';
GO</pre><p>And my results&#8230;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/finallymatching.png"><img loading="lazy" class="aligncenter wp-image-2481 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/finallymatching.png" alt="finallymatching" width="575" height="185" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/finallymatching.png 575w, https://jasonbrimhall.info/wp-content/uploads/2014/08/finallymatching-300x96.png 300w" sizes="(max-width: 575px) 85vw, 575px" /></a></p>
<p>&nbsp;</p>
<p>If you don&#8217;t have the text to create the proc, you could use SSMS to script it out for you.  It is as simple as right-clicking the proc in question, selecting modify and then executing the script.  It should script at with the correct proc name (the beauty of SMO) and then you can get the metadata all up to snuff in your database.</p>
<p>Of course, if you prefer, you could just drop and recreate the procedure.  Then reapply all of the pertinent permissions.  That is pretty straight forward too.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2472" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/14/effects-of-sp_rename-on-stored-procedures/">Effects of sp_rename on Stored Procedures</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/14/effects-of-sp_rename-on-stored-procedures/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server UG in Vegas August 2014 Meeting</title>
		<link>https://jasonbrimhall.info/2014/08/13/sql-server-ug-in-vegas-august-2014-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-ug-in-vegas-august-2014-meeting</link>
					<comments>https://jasonbrimhall.info/2014/08/13/sql-server-ug-in-vegas-august-2014-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 14 Aug 2014 03:10:04 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2469</guid>

					<description><![CDATA[<p>&#160; Another Great meeting and topic is coming to the folks in Las Vegas.  This month we have had the luck of finding Mike Fal (blog &#124; twitter) step up and fill our speaker void. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/13/sql-server-ug-in-vegas-august-2014-meeting/">SQL Server UG in Vegas August 2014 Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/evite.png"><img loading="lazy" class="aligncenter wp-image-2470" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/evite.png" alt="evite" width="550" height="266" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/evite.png 825w, https://jasonbrimhall.info/wp-content/uploads/2014/08/evite-300x145.png 300w" sizes="(max-width: 550px) 85vw, 550px" /></a></p>
<p>&nbsp;</p>
<p>Another Great meeting and topic is coming to the folks in Las Vegas.  This month we have had the luck of finding Mike Fal (<a href="http://www.mikefal.net/">blog </a>| <a href="https://twitter.com/Mike_Fal">twitter</a>) step up and fill our speaker void.</p>
<p>Yes, it happens to be the second Thursday of the month already.  Being that time of month, the SQL Server UG of Las Vegas will be meeting at the Tahitti Village Resort and Spa to take in some great info on SQL Server and Powershell.</p>
<p>You can read the information about the meeting on our Meetup page here (http://www.meetup.com/SQL-Server-Society-of-Las-Vegas/events/197512652/).  Or you can continue reading this page.</p>
<p style="color: rgba(0, 0, 0, 0.670588);"><span style="font-weight: bold;">Improving Database Restores with Powershell</span></p>
<p style="color: rgba(0, 0, 0, 0.670588);">Database restores are a key function of any database administrator&#8217;s job. However, it can be an extremely time consuming task to sort through your backups, find the right files, and then get your database up and running. In an emergency this will have a disastrous impact on your Recovery Time Objective(RTO) and lead to the dreaded angry-CTO-in-your-cube effect. By leveraging some easy-to-use Powershell scripts, you can avoid the second disaster and the pain that comes with it. By attending this session, you will understand how you can use the Powershell automation framework for database restores, see scripts that will let you restore faster, and learn techniques to extend these tools for migrating data and testing backups.</p>
<p style="color: rgba(0, 0, 0, 0.670588);"><span style="font-weight: bold;">Michael Fal  </span></p>
<p style="color: rgba(0, 0, 0, 0.670588);">Mike Fal is a musician turned SQL Server DBA, with 10+ years of experience as a database administrator. He has worked for several different industries, including healthcare, software development, marketing, and manufacturing and has experience supporting databases from 1 GB to 4 TB in size. Mike received his a Bachelor&#8217;s Degree from the University of Colorado at Boulder in 1996 and has been caught playing trombone in public on more than one occasion.</p>
<p style="color: rgba(0, 0, 0, 0.670588);"><span style="font-weight: bold;">LiveMeeting Info</span></p>
<p style="color: rgba(0, 0, 0, 0.670588);">Attendee URL:https://www.livemeeting.com/cc/UserGroups/join?id=4RD8NP&amp;role=attend</p>
<p style="color: rgba(0, 0, 0, 0.670588);">Meeting ID: 4RD8NP</p>
<p style="color: rgba(0, 0, 0, 0.670588);">Whether you are in Vegas or you are somewhere else, you are welcome to join us.  We hope to see you Thursday evening.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2469" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/13/sql-server-ug-in-vegas-august-2014-meeting/">SQL Server UG in Vegas August 2014 Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/13/sql-server-ug-in-vegas-august-2014-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #57 – SQL Family and Community</title>
		<link>https://jasonbrimhall.info/2014/08/12/t-sql-tuesday-57-sql-family-and-community/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-57-sql-family-and-community</link>
					<comments>https://jasonbrimhall.info/2014/08/12/t-sql-tuesday-57-sql-family-and-community/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 Aug 2014 16:03:27 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2467</guid>

					<description><![CDATA[<p>Look at that, it is once again that time of the month that has come to be known as TSQL Tuesday.  TSQL Tuesday is a recurring blog party that occurs on the second Tuesday (most [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/12/t-sql-tuesday-57-sql-family-and-community/">T-SQL Tuesday #57 – SQL Family and Community</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://devjef.wordpress.com/2014/08/12/t-sql-tuesday-57-sql-family-and-community-2/"><img loading="lazy" class="alignright wp-image-2309 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" alt="TSQL2sDay150x150" width="150" height="150" /></a>Look at that, it is once again that time of the month that has come to be known as TSQL Tuesday.  TSQL Tuesday is a recurring blog party that occurs on the second Tuesday (most generally) of the month.  This event was the brainchild of Adam Machanic <span style="color: #555555;">(<a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" target="_blank" class="broken_link">Blog</a></span><span style="color: #555555;"> | <a href="http://twitter.com/adammachanic" target="_blank">Twitter</a></span><span style="color: #555555;">).  </span></p>
<p><span style="color: #555555;">Anybody who desires to participate in this blog party is welcome to join.  Coincidentally, that open invitation is at the base of this months topic &#8211; Family and Community.  The <a href="http://devjef.wordpress.com/2014/08/05/t-sql-tuesday-57-sql-family-and-community/" target="_blank">invitation</a>, issued by Jeffrey Verheul (<a href="http://devjef.wordpress.com/" target="_blank">blog</a> | <a href="https://twitter.com/DevJef" target="_blank">twitter</a>), for this month said the following.</span></p>
<blockquote>
<p style="color: #555555;">This month I would like to give everyone the opportunity to write about SQL Family. The first time I heard of SQL Family, was on Twitter where someone mentioned this. At first I didn’t know what to think about this. I wasn’t really active in the community, and I thought it was a little weird. They were just people you meet on the internet, and might meet in person at a conference some day. But I couldn’t be more wrong about that!</p>
<p style="color: #555555;">Once you start visiting events, forums, or any other involvement with the community, you’ll see I was totally wrong. I want to hear those stories. How do you feel about SQL Family? Did they help you, or did you help someone in the SQL Family? I would love to hear the stories of support, how it helped you grow and evolve, or how you would explain SQL Family to your friends and family (which I find hard). Just write about whatever topic you want, as long as it’s related to SQL Family or community.</p>
</blockquote>
<h2>What is it?</h2>
<p>We have all likely seen SQL Family thrown about here and there.  But what exactly is this notion we hear about so often?</p>
<p>I think we have a good idea about what family might be.  I think we might even have a good idea of what a friend is.  Lastly, I might propose that we know what a community is.  When we talk of this thing called SQL Family, I like to think that it is a combination of family, friends and community.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/mushroom.jpg"><img loading="lazy" class="aligncenter size-full wp-image-2190" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/mushroom.jpg" alt="mushroom" width="259" height="194" /></a></p>
<p>These are people that can come together and talk about various different things that span far beyond SQL Server.  We may only see each other at events every now and then.  Those events can be anything from a User Group meeting to a large conference or even at a road race (5k, half marathon, marathon).</p>
<p>These are the people that are willing to help where help is needed or wanted.  That help can be anything ranging from well wishes and prayers, to teaching about SQL Server, to lending a vehicle, or anything along that spectrum.</p>
<p>I have seen this community go out of their way to help provide a lift to a hotel or to the airport.  These people will help with lodging in various circumstances when/if they can.  These are the people that have been known to make visits to hospitals to give well wishes for other people in the community.</p>
<p>Isn&#8217;t that what friends / family really boils down to?  <em>People that can talk to each other on an array of topics?  People that go out of their way to help?</em>  Think about it for a minute or three.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2467" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/12/t-sql-tuesday-57-sql-family-and-community/">T-SQL Tuesday #57 – SQL Family and Community</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/12/t-sql-tuesday-57-sql-family-and-community/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Virtual Box is TOO Small</title>
		<link>https://jasonbrimhall.info/2014/08/05/virtual-box-is-too-small/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=virtual-box-is-too-small</link>
					<comments>https://jasonbrimhall.info/2014/08/05/virtual-box-is-too-small/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 05 Aug 2014 13:00:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Lab]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2459</guid>

					<description><![CDATA[<p>I have been working on upgrading my laptop.  Since my laptop housed a bunch of my virtual machines for various presentations and labs, that means also upgrading and/or converting my virtual machines. The new laptop [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/05/virtual-box-is-too-small/">Virtual Box is TOO Small</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I have been working on upgrading my laptop.  Since my laptop housed a bunch of my virtual machines for various presentations and labs, that means also upgrading and/or converting my virtual machines.</p>
<p>The new laptop is Windows 8.1.  With the new laptop I was interested in converting a bunch of my Virtual Box machines to Hyper-V machines.  That desire was put on hold after discovering that I needed to first convert the virtual disks and then import them.  That wasn&#8217;t what put me off to it for awhile though.</p>
<p>The fact that I had to install Virtual Box on the new laptop to do the conversion made it less desirable. You see, in order to make Virtual Box work, I had to uninstall Hyper-V from Windows 8.1 because HV disables settings that are required by Virtual Box to work.  Jumping through those hoops just makes me less inclined to hurry and try the conversion to Hyper-V.  Maybe someday down the road.</p>
<p>That said, with the new laptop supporting a resolution of <span style="color: #333333;">3200 x 1800, I found that my virtual machines started displaying extremely tiny resolutions.  No matter how I scaled the machine, the internal machine resolution was remaining tiny.</span></p>
<p>Come to find out, the virtual machine was using the 3200 x 1800 resolution of the host despite setting the virtual machine (internally) to resolution settings as low as 640 x 480 (which just produced a small window on the desktop).  In the settings for Virtual Box, I could not find a means to override that behavior.</p>
<p>What I did find though was a setting in the Windows 8.1 host control panel that affected the virtual machine size.  In the Display control panel there is a setting <span style="color: #333333;"> saying &#8220;Let me choose one scaling level for all my displays&#8221;. That seems to help with this scaling issue.</span></p>
<p>As it appears, many applications automatically adjust the scaling on such a high resolution device.  Virtual Box does not automatically scale and just adopts the host machine resolution.  In my case, it was also always adopting the host machine max resolution.</p>
<p>I changed that setting, adjusted my resolution to <span style="color: #333333;">1920 x 1080</span>, and then also adjusted the scaling factor to 150%.  This fixed the issue with the excessively small screen on the virtual machines.  Sure, I could have continued to use the windows &#8220;+&#8221; combination to zoom in an out constantly, but that was more of a hassle than convenience.</p>
<p>We&#8217;ll just have to see how it goes for the time being.  Maybe in a few weeks when I have time to try the Hyper-V conversion again, I will be able to jump back to the higher resolution.  We&#8217;ll find out then if that scaling issue is an issue for Hyper-V just as it is for Virtual Box.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2459" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/05/virtual-box-is-too-small/">Virtual Box is TOO Small</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/05/virtual-box-is-too-small/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Presenting at PSSUG</title>
		<link>https://jasonbrimhall.info/2014/08/04/presenting-at-pssug/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=presenting-at-pssug</link>
					<comments>https://jasonbrimhall.info/2014/08/04/presenting-at-pssug/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 04 Aug 2014 16:00:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2456</guid>

					<description><![CDATA[<p>&#160; Coming up this week, I have been given the opportunity to do something I enjoy doing.  I have been invited to present to the folks in Philadelphia. Sebastian Meine (blog &#124; twitter) approached me [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/04/presenting-at-pssug/">Presenting at PSSUG</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.eventbrite.com/e/august-2014-pssug-meeting-tickets-12098070655?ref=enivtefor001&amp;invite=NjM1NjIzOS9icmltaGpAZ21haWwuY29tLzA%3D&amp;utm_source=eb_email&amp;utm_medium=email&amp;utm_campaign=inviteformal001&amp;utm_term=eventpage" target="_blank" class="broken_link"><img loading="lazy" class="aligncenter wp-image-2457 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/pssug.jpg" alt="pssug" width="450" height="196" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/pssug.jpg 450w, https://jasonbrimhall.info/wp-content/uploads/2014/08/pssug-300x130.jpg 300w" sizes="(max-width: 450px) 85vw, 450px" /></a></p>
<p>&nbsp;</p>
<p>Coming up this week, I have been given the opportunity to do something I enjoy doing.  I have been invited to present to the folks in Philadelphia.</p>
<p>Sebastian Meine (<a href="http://sqlity.net/">blog</a> | <a href="https://twitter.com/sqlity">twitter</a>) approached me during SQL Saturday in Philadelphia and I was happy to help where I could.</p>
<p>The topic for this presentation will be Extended Events.  We are going to try a slightly different approach, but here is what was posted in the meeting invite.</p>
<div style="color: #666666;"></div>
<div style="color: #666666;"><span style="font-weight: bold;">Jason Brimhall </span>&#8211; <span style="color: #272727;">SQL 2012 Extended Events</span></div>
<div style="color: #666666;"></div>
<div style="color: #666666;">Extended Events were introduced in SQL Server 2008. With each edition since, we have seen a significant upgrade to this feature. Join me for a little adventure into defining this thing called Extended Events. We will discuss how to use Extended Events to aid in performance tuning and in day to day administration. We will also explore some background and the architecture of Extended Events.</div>
<div style="color: #666666;">
<table border="0">
<tbody>
<tr valign="top">
<td>
<p><span style="font-weight: bold;"><em><img loading="lazy" title="Jason Brimhall" src="https://web.archive.org/web/20150123010720/https://media.licdn.com/media/p/8/000/1e3/3ae/0ab732a.jpg" alt="Jason Brimhall" width="150" height="150" /></em></span></p>
<p><span style="font-weight: bold;"><em>Jason Brimhall</em></span></p>
<p>&nbsp;</td>
<td align="left">
<p style="color: #272727;"><span style="color: #747474;">As a Microsoft Certified Master/Microsoft Certified Solutions Master, I have 19 years’ experience in the technology industry, including more than 10 with SQL Server. I also earned a Bachelor’s Degree in Business Information Systems from Utah State University. One of the highlights of my career was co-authoring </span><em style="color: #747474;"><a style="color: #333333;" href="http://www.amazon.com/Server-2012-T-SQL-Recipes-Problem-Solution/dp/1430242000/ref=tmm_pap_title_0" target="_blank" rel="nofollow">SQL Server 2012 T-SQL Recipes: A Problem-Solution Approach</a> . </em><span style="color: #747474;"> I am a frequent presenter at SQL Server events worldwide, which includes SQLSaturdays and User Groups. I am also currently helping lead the Las Vegas SQL Users Group.</span></p>
</td>
</tr>
</tbody>
</table>
<p>I am looking forward to this opportunity and to mingle with the group for a bit.  I hope to see you there.</p>
<p>Oh, and here is the <a href="https://www.eventbrite.com/e/august-2014-pssug-meeting-tickets-12098070655?ref=enivtefor001&amp;invite=NjM1NjIzOS9icmltaGpAZ21haWwuY29tLzA%3D&amp;utm_source=eb_email&amp;utm_medium=email&amp;utm_campaign=inviteformal001&amp;utm_term=eventpage" class="broken_link">link </a>to the invite for the meeting.</p>
</div>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2456" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/04/presenting-at-pssug/">Presenting at PSSUG</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/04/presenting-at-pssug/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Murder in Raleigh</title>
		<link>https://jasonbrimhall.info/2014/08/04/murder-in-raleigh/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-in-raleigh</link>
					<comments>https://jasonbrimhall.info/2014/08/04/murder-in-raleigh/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 04 Aug 2014 13:00:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQL Saturday]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2450</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/08/04/murder-in-raleigh/">Murder in Raleigh</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/sqlsat320_web.png"><img loading="lazy" class="alignright wp-image-2452 size-full" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/sqlsat320_web.png" alt="sqlsat320_web" width="236" height="115" /></a>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/08/raleigh_traini.jpg"><img loading="lazy" class="aligncenter wp-image-2451" src="http://jasonbrimhall.info/wp-content/uploads/2014/08/raleigh_traini.jpg" alt="raleigh_traini" width="550" height="290" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/08/raleigh_traini.jpg 700w, https://jasonbrimhall.info/wp-content/uploads/2014/08/raleigh_traini-300x158.jpg 300w" sizes="(max-width: 550px) 85vw, 550px" /></a></p>
<p>Time to sink or sail, so to speak.  <a href="http://sqlsaturday.com/320/eventhome.aspx">SQL Saturday 320</a> in Raleigh will mark the next attempt at what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in this all day workshop event.  The session is one of two all day sessions for the event in Raleigh NC.</p>
<p>If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3>Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" alt="wayne" width="141" height="211" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at<a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" alt="JasonBrimhall" width="141" height="211" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" class="aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" alt="kaboom" width="301" height="167" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us.  You can find registration information and event details at the Raleigh SQL Saturday site &#8211; <a href="http://sqlsaturday.com/320/eventhome.aspx">here</a>.  There are only 25 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>The cost for the class is $110 (plus fees) up through the day of the event.  <a title="Registration" href="https://www.eventbrite.com/e/murder-they-wrote-tickets-12399650689?ref=ebtn" target="_blank" class="broken_link">When you register</a>, be sure to tell your coworkers and friends.</p>
<h3>Wait, there&#8217;s more&#8230;</h3>
<p>Not only will I be in Raleigh for this workshop, I hope to also be presenting as a part of the SQLSaturday event on Sep 6 2014 (the day after the workshop which is Sep 5, 2014).  I hope to update with the selected session(s) when that information becomes available.</p>
<p>You can see more details about the topics lined up for this event &#8211; <a href="http://sqlsaturday.com/320/schedule.aspx">here</a>.</p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some workshop sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2450" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/08/04/murder-in-raleigh/">Murder in Raleigh</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/08/04/murder-in-raleigh/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Murder In Denver</title>
		<link>https://jasonbrimhall.info/2014/07/14/murder-in-denver/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-in-denver</link>
					<comments>https://jasonbrimhall.info/2014/07/14/murder-in-denver/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 14 Jul 2014 21:08:23 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2418</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/07/14/murder-in-denver/">Murder In Denver</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/07/sqlsat331_web.png"><img loading="lazy" class="alignright size-full wp-image-2420" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/sqlsat331_web.png" alt="sqlsat331_web" width="236" height="115" /></a>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/07/train.png"><img loading="lazy" class="size-full wp-image-2421 aligncenter" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/train.png" alt="train" width="470" height="353" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/train.png 470w, https://jasonbrimhall.info/wp-content/uploads/2014/07/train-300x225.png 300w" sizes="(max-width: 470px) 85vw, 470px" /></a></p>
<p style="text-align: left;">Time to sink or sail, so to speak.  <a href="http://sqlsaturday.com/331/eventhome.aspx">SQL Saturday 331</a> in Denver will mark the next attempt at what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in this all day pre-con / workshop event.  The session is one of three all day sessions for the event in Denver CO.</p>
<p>If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3>Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" alt="wayne" width="141" height="211" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at<a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" alt="JasonBrimhall" width="141" height="211" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" alt="kaboom" width="301" height="167" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us.  You can find registration information and event details at the Denver SQL site &#8211; <a href="http://richmondsql.org/cs2007/blogs/events/archive/2014/01/04/sqlsaturday-pre-con-with-wayne-sheffield-and-jason-brimhall.aspx" class="broken_link">here</a>.  There are only 30 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>The cost for the class is $125 up through the day of the event.  <a title="Registration" href="https://www.eventbrite.com/e/sql-saturday-331-denver-pre-con-wjason-brimhall-wayne-sheffield-tickets-11922345055?ref=ebtnebtckt" target="_blank" class="broken_link">When you register</a>, be sure to choose Wayne&#8217;s class.</p>
<h3>Wait, there&#8217;s more&#8230;</h3>
<p>Not only will I be in Denver for the Precon, I hope to also be presenting as a part of the SQLSaturday event on Sep 20 2014 (the day after the precon which is Sep 19, 2014).  I hope to update with the selected session(s) when that information becomes available.</p>
<p>You can see more details about the topics lined up for this event &#8211; <a href="http://sqlsaturday.com/331/schedule.aspx">here</a>.</p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some pre-con sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2418" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/07/14/murder-in-denver/">Murder In Denver</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/07/14/murder-in-denver/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Is your Team Willing to Take Control?</title>
		<link>https://jasonbrimhall.info/2014/07/08/is-your-team-willing-to-take-control/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=is-your-team-willing-to-take-control</link>
					<comments>https://jasonbrimhall.info/2014/07/08/is-your-team-willing-to-take-control/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Jul 2014 17:36:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2409</guid>

					<description><![CDATA[<p>The calendar tells us that once again we have reached the second tuesday of the month.  In the SQL Community, this means a little party as many of you may already know.  This is the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/07/08/is-your-team-willing-to-take-control/">Is your Team Willing to Take Control?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://web.archive.org/web/20170627004843/http://devnambi.com:80/2014/tsql-tuesday/"><img loading="lazy" class="alignright size-full wp-image-2309" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" width="150" height="150" /></a></p>
<p>The calendar tells us that once again we have reached the second tuesday of the month.  In the SQL Community, this means a little party as many of you may already know.  This is the TSQL Tuesday Party.</p>
<p>This month represents the 56th installment of this party.  This institution was implemented by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" class="broken_link">b</a>|<a href="https://twitter.com/AdamMachanic">t</a>) and is hosted by Dev Nambi (<a href="http://devnambi.com/" target="_blank">b</a>|<a href="https://twitter.com/DevNambi" target="_blank">t</a>) this month.</p>
<p>The topic chosen for the month is all about the art of being able to assume.</p>
<p>In many circles, to assume something infers a negative connotation.  From time to time, it is less drastic when you might have a bit of evidence to support the assumption.  In this case, it would be closer to a presumption.  I will not be discussing either of those connotations.</p>
<h2>What is this Art?</h2>
<p>Before getting into this art that was mentioned, I want to share a little background story.</p>
<p>Let&#8217;s try to paint a picture of a common theme I have seen in environment after environment.  There are eight or nine different teams.  Among these teams you will find multiple teams to support different data environments.  These data environments could include a warehouse team, an Oracle team, and a SQL team.</p>
<p>As a member of the SQL team, you have the back-end databases that support the most critical application for your employer/client.  As a member of the SQL team, one of your responsibilities is to ingest data from the warehouse or from the Oracle environment.</p>
<p>Since this is a well oiled machine, you have standards defined for the ingestion, source data, and the destination.  Right here we could throw out a presumption (it is well founded) that the standards will be followed.</p>
<p>Another element to consider is the directive from management that the data being ingested is not to be altered by the SQL team to make the data conform to standards.  That responsibility lies squarely on the shoulder of the team providing the data.  Should bad data be provided, it should be sent back to the team providing it.</p>
<p>Following this mandate, you find that bad data is sent to the SQL team on a regular basis and you report it back to have the data, process, or both fixed.  The next time the data comes it appears clean.  Problem solved, right?  Then it happens again, and again, and yet again.</p>
<p>Now it is up to you.  Do you continue to just report that the data could not be imported yet again due to bad data?  Or do you now assume the responsibility and change your ingestion process to handle the most common data mistakes that you have seen?</p>
<p>I am in favor of assuming the responsibility.  Take the opportunity to make the ingestion process more robust.  Take the opportunity to add better error handling.  Take the opportunity continue to report back that there was bad data.  All of these things can be done in most cases to make the process more seamless and to have it perform better.</p>
<p>By assuming the responsibility to make the process more robust and to add better reporting/ logging to your process, you can only help the other teams to make their process better too.</p>
<p>While many may condemn assumptions, I say proceed with your assumptions.  Assume more responsibility.  Assume better processes by making them better yourself.  If it means rocking the boat, go ahead &#8211; these are good assumptions.</p>
<p>If you don&#8217;t, you are applying the wrong form of assumption.  By not assuming the responsibility, you are assuming that somebody else will or that the process is good enough.  That is bad in the long run.  That would be the only burning &#8220;elephant in the room&#8221;.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/07/elephants.png"><img loading="lazy" class=" wp-image-2410 aligncenter" alt="elephants" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/elephants.png" width="493" height="328" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/elephants.png 770w, https://jasonbrimhall.info/wp-content/uploads/2014/07/elephants-300x199.png 300w" sizes="(max-width: 493px) 85vw, 493px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">From here, it is up to you.  How are you going to assume in your environment?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2409" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/07/08/is-your-team-willing-to-take-control/">Is your Team Willing to Take Control?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/07/08/is-your-team-willing-to-take-control/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Using Synonyms to Extend SSIS</title>
		<link>https://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-synonyms-to-extend-ssis</link>
					<comments>https://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 03 Jul 2014 12:30:23 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[performance tune]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2395</guid>

					<description><![CDATA[<p>There are a million and one uses for synonyms.  There are at least that many uses for SSIS.  The reality is, not all of those uses are good for you nor for your data nor [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/">Using Synonyms to Extend SSIS</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>There are a million and one uses for synonyms.  There are at least that many uses for SSIS.  The reality is, not all of those uses are good for you nor for your data nor for your database.</p>
<p>Recently I wrote an article about some good and some bad with synonyms.  You can read that article from my work blog site <a href="http://bit.ly/ssgsynonym">here</a>.  Today, I just want to expand on that article a little bit.  I glossed over some things pretty quick in that article that I though might be fun to explain with a little more detail.</p>
<h2>The Bad &#8211; a little closer look</h2>
<p>First, let&#8217;s take a look a little closer at the bad.  More specifically, in the example I used, there was a vendor that created a synonym for everything.  I really do mean everything.  This is one case where using the word &#8220;literally&#8221; would be accurate.  On the client database, I could run a quick query such as the following and see over 7300 synonyms.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT name AS SynonymName
		,SCHEMA_NAME(schema_id) AS SchName
		,create_date
		,base_object_name
	FROM sys.synonyms;</pre><p>[/codesyntax]</p>
<p>In the case of this client and this vendor, 7300+ synonyms is far too many.  It just led to mass confusion.  If you were to run that query, you might see something like the following image.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/07/massSynonyms.png"><img loading="lazy" class=" wp-image-2397 aligncenter" alt="massSynonyms" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/massSynonyms.png" width="571" height="169" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/massSynonyms.png 816w, https://jasonbrimhall.info/wp-content/uploads/2014/07/massSynonyms-300x88.png 300w" sizes="(max-width: 571px) 85vw, 571px" /></a></p>
<p style="text-align: left;">I added a &#8220;derived&#8221; column to show the total count of synonyms and the record name as it relates to that total.  That is a crazy amount of synonyms.  That just makes me think that somebody got into the krazy kool-aid one day, was bored and gave life to a synonym beast.</p>
<h2 style="text-align: left;">The Good &#8211; With more detail</h2>
<p style="text-align: left;">On the flip side, in the aforementioned article, I talked about synonyms as a means to tweak performance in SSIS.  Normally I would not tout a synonym as a performance tweak.  So I want to caution that the performance gains are specific to SSIS and a handful of those millions of uses for SSIS.</p>
<p style="text-align: left;">Let&#8217;s just begin with a little bit of background.  For that background, some pictures will be really handy.  So here goes.</p>
<p style="text-align: center;"><img loading="lazy" class="size-full wp-image-2398 aligncenter" alt="SpiceSource" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/SpiceSource.png" width="220" height="215" /></p>
<p style="text-align: left;">In the preceding image we see a very simple segment of a data flow.</p>
<p style="text-align: left;">The data source uses a sql command to fetch the data required for the data flow.  In the beginning, it is very straight forward.  You probably have some package lying around with something similar to this.</p>
<p style="text-align: left;">In the following image, we see what the SQL Command was for that data source circled in red in the previous image.</p>
<p style="text-align: left;"><img loading="lazy" class="size-full wp-image-2400 aligncenter" alt="SQLWithout" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWithout.png" width="471" height="403" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWithout.png 471w, https://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWithout-300x256.png 300w" sizes="(max-width: 471px) 85vw, 471px" /></p>
<p style="text-align: left;">In the next image we see a slight tweak to the query.  This time to include a reference to a table that is defined/obfuscated by a synonym.</p>
<p><img loading="lazy" class="size-full wp-image-2399 aligncenter" style="line-height: 15.600000381469727px; text-align: center;" alt="SQLWith" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWith.png" width="476" height="407" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWith.png 476w, https://jasonbrimhall.info/wp-content/uploads/2014/07/SQLWith-300x256.png 300w" sizes="(max-width: 476px) 85vw, 476px" /></p>
<p>At this point I can hear some of you saying, &#8220;Ok, I see what he is doing.&#8221;  While many others are wondering why I just made the query more complex than the previous example.</p>
<p style="text-align: left;">Well as luck would have it, this change serves a couple of purposes.  1) The data has been staged in a separate database.  That database has a different name in every environment (recall the aforementioned article).  So the synonym minimizes code changes when deploying the package.  2) The synonym allows us to confirm that there is data in the stage table and that the data matches a ClientCode in the destination table.  3) Lastly, the synonym reduces my dataset which reduces memory requirements and also gets the data loaded faster (because it is smaller).</p>
<p>In addition to this minor tweak, I can also do something like the following.</p>
<p><img loading="lazy" class="size-full wp-image-2401 aligncenter" alt="WithoutSynonym" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/WithoutSynonym.png" width="451" height="382" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/WithoutSynonym.png 451w, https://jasonbrimhall.info/wp-content/uploads/2014/07/WithoutSynonym-300x254.png 300w" sizes="(max-width: 451px) 85vw, 451px" /></p>
<p>In the preceding image, we see two datasources.  Each datasource is subsequently sorted and then eventually joined.  Much like the previous example, due to naming standards and an effort to try and minimize code changes during deployments, at least one datasource is pulling in too much data.  The data is filtered down due to the Join transformation, but this is not very efficient.</p>
<p><img loading="lazy" class="size-full wp-image-2402 aligncenter" style="text-align: center;" alt="WithSynonym" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/WithSynonym.png" width="364" height="241" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/WithSynonym.png 364w, https://jasonbrimhall.info/wp-content/uploads/2014/07/WithSynonym-300x198.png 300w" sizes="(max-width: 364px) 85vw, 364px" /></p>
<p>Through the use of a synonym, the datasources can be reduced to a single datasource.  This will eliminate the need for the Sort transformations and Join transformation.  Removing those three transformations reduced memory requirements.  And like the previous example, since we can trim down the number of records, the data flow will run a little bit faster too.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/07/BigSQLWith.png"><img loading="lazy" class="size-full wp-image-2396 aligncenter" alt="BigSQLWith" src="http://jasonbrimhall.info/wp-content/uploads/2014/07/BigSQLWith.png" width="474" height="407" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/07/BigSQLWith.png 474w, https://jasonbrimhall.info/wp-content/uploads/2014/07/BigSQLWith-300x257.png 300w" sizes="(max-width: 474px) 85vw, 474px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">As You can see, the code is simple.  It&#8217;s not a super TSQL trick or anything to add a synonym into an existing query.  It just gets referenced like any other table.  Once again, in this case, the synonym is pointing to a table in a staging database.  That table has been loaded as a part of an ETL process and now needs to be manipulated a little bit through some other transformations and then inserted eventually into a &#8220;target&#8221; database.</p>
<h2 style="text-align: left;">Conclusion</h2>
<p style="text-align: left;">As with tuning stored procedures or any TSQL, a similar technique was used here.  Reducing the datasets to contain <strong>JUST</strong> the data that is needed for the flow.  To facilitate that reduction in data to be just the <em>essential</em> data, I employed synonyms.</p>
<p style="text-align: left;">The reasons for using a synonym in this case were to: 1) restrict data to precisely what was needed, 2) ensure data being loaded was &#8220;constrained&#8221; by data in the destination table (e.g. only load for a specific client that does <span style="text-decoration: underline;">exist</span>), and 3) minimize code changes during deployments.</p>
<p style="text-align: left;">When dealing with databases that serve the same purpose but follow some absurd naming standard that changes the name between environments, it can become cumbersome to maintain code during deployments.  This is particularly true when dealing with cross database joins or lookups.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2395" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/">Using Synonyms to Extend SSIS</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/07/03/using-synonyms-to-extend-ssis/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Can you partition a temporary table?</title>
		<link>https://jasonbrimhall.info/2014/05/23/can-you-partition-a-temporary-table/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=can-you-partition-a-temporary-table</link>
					<comments>https://jasonbrimhall.info/2014/05/23/can-you-partition-a-temporary-table/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 23 May 2014 16:49:51 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[administration]]></category>
		<category><![CDATA[Partitioning]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Myth]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2382</guid>

					<description><![CDATA[<p>Reading that title, you might sit and wonder why you would ever want to partition a temporary table.  I too would wonder the same thing.  That withstanding, it is an interesting question that I wanted [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/05/23/can-you-partition-a-temporary-table/">Can you partition a temporary table?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Reading that title, you might sit and wonder why you would ever want to partition a temporary table.  I too would wonder the same thing.  That withstanding, it is an interesting question that I wanted to investigate.</p>
<p>The investigation started with a fairly innocuous venture into showing some features that do apply to temp tables which are commonly mistaken as limitations (i.e. don&#8217;t work with temp tables).  To show this I set off to create a script with reproducible results to demonstrate these features.  I have included all of those in the same script I will provide that demonstrates the answer to the partitioning question.</p>
<p>In fact lets just jump to that script now.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET NOCOUNT ON;
USE tempdb;
GO

IF OBJECT_ID('#hubbabubba','U') IS NOT NULL
BEGIN
	DROP TABLE #hubbabubba;
END

CREATE TABLE #hubbabubba (
	someint INT PRIMARY KEY NONCLUSTERED IDENTITY(1,1)
	,somechar VARCHAR(50)
	,somedate DATE
	,somebit BIT DEFAULT(0))

IF EXISTS (SELECT name FROM sys.partition_schemes WHERE name = 'PartitionToPrimary')
	BEGIN
		DROP PARTITION SCHEME PartitionToPrimary
	END
IF EXISTS (SELECT name FROM sys.partition_functions WHERE name = 'PartitionByMonth')
	BEGIN
		DROP PARTITION FUNCTION PartitionByMonth
	END

CREATE PARTITION FUNCTION PartitionByMonth (DATE)
	AS RANGE RIGHT 
	FOR VALUES ('2014/01/01', '2014/02/01', '2014/03/01', '2014/04/01', '2014/05/01','2014/06/01'
		, '2014/07/01', '2014/08/01', '2014/09/01', '2014/10/01', '2014/11/01', '2014/12/01');

CREATE PARTITION SCHEME PartitionToPrimary 
	AS PARTITION PartitionByMonth 
	ALL TO ([PRIMARY]);

CREATE CLUSTERED INDEX idx_hubba_somedate ON #hubbabubba (somedate)
	ON PartitionToPrimary (somedate);
GO

/* 
Establish a Date range to be used for Random date generation and table population
We only have the table partitioned for the current year so limiting the dates to this
year is essential
*/
DECLARE @BeginDate DATE = '2014-01-01'
		,@EndDate DATE = '2014-12-31'

/* Populate some data */
INSERT INTO #hubbabubba
        ( somechar,somedate )
VALUES  ( 'DidmyDefaultApply?'
	,DATEADD(DAY,RAND(CHECKSUM(NEWID())) * ( 1 + DATEDIFF(DAY, @EndDate,@BeginDate) ), @EndDate))
GO 5000

SELECT *
	FROM #hubbabubba;

USE tempdb;
GO

sp_help '#hubbabubba'
/* Demonstrates the existence of 
2 constraints on the temp table 
2 indexes on the temp table
	1 clustered (supports the partition)
	1 nonclustered

*/
/* Base query for the following attributed to Kendra Little 
This demonstrates that Partitions can be created on temp tables 
*/
SELECT  OBJECT_NAME(si.object_id) AS object_name ,
		pf.name AS pf_name ,
        ps.name AS partition_scheme_name ,
        p.partition_number ,
        rv.value AS range_value ,
        SUM(CASE WHEN si.index_id IN ( 1, 0 ) THEN p.rows
                    ELSE 0
            END) AS num_rows ,
        SUM(dbps.reserved_page_count) * 8 / 1024. AS reserved_mb_all_indexes ,
        SUM(CASE ISNULL(si.index_id, 0)
                WHEN 0 THEN 0
                ELSE 1
            END) AS num_indexes
FROM    sys.destination_data_spaces AS dds
        INNER JOIN sys.data_spaces AS ds 
			ON dds.data_space_id = ds.data_space_id
        INNER JOIN sys.partition_schemes AS ps 
			ON dds.partition_scheme_id = ps.data_space_id
        INNER JOIN sys.partition_functions AS pf 
			ON ps.function_id = pf.function_id
        LEFT OUTER JOIN sys.partition_range_values AS rv 
			ON pf.function_id = rv.function_id
            AND dds.destination_id = CASE pf.boundary_value_on_right
                                        WHEN 0 THEN rv.boundary_id
                                        ELSE rv.boundary_id + 1
                                    END
        LEFT OUTER JOIN sys.indexes AS si 
			ON dds.partition_scheme_id = si.data_space_id
        LEFT OUTER JOIN sys.partitions AS p 
			ON si.object_id = p.object_id
			AND si.index_id = p.index_id
			AND dds.destination_id = p.partition_number
        LEFT OUTER JOIN sys.dm_db_partition_stats AS dbps 
			ON p.object_id = dbps.object_id
            AND p.partition_id = dbps.partition_id
WHERE p.OBJECT_ID = OBJECT_ID('#hubbabubba','U')
GROUP BY p.partition_number ,pf.name,ps.name ,si.object_id ,rv.value;
GO</pre><p>In the beginning (after dropping objects if they exist), I start by creating a temp table that has a couple of mythical limitations.  These mythical creatures are that temp tables can&#8217;t have indexes or that they can&#8217;t have constraints.</p>
<p>In this script, I show that a temp table (#hubbabubba) can indeed have indexes created on it (clustered and nonclustered).  I also demonstrate the creation of two different kinds of constraints on the #hubbabubba table.  The two constraints are a primary key and a default constraint.  That stuff was easy!!</p>
<p>To figure out whether or not one could partition a temporary table, I needed to do more than simply create a &#8220;test&#8221; temp table.  I had to create a partitioning function and a partitioning scheme and then tie that partition scheme to a clustered index that I created after table creation.  Really, this is all the same steps as if creating partitioning on a standard (non-temporary) table.</p>
<p>With that partitioning scheme, function and the table created it was time to populate with enough random data to seem like a fair distribution.  You see, I created a partition function for each month of the year 2014.  To see partitioning in action, I wanted to see data in each of the partitions.</p>
<p>That brings us to the final piece of the whole script.  Kendra Little produced a <a href="http://www.brentozar.com/archive/2013/01/sql-server-table-partitioning-tutorial-videos-and-scripts/">script </a>for viewing distribution of data across the partitions so I used her script to demonstrate our data distribution.  If you run the entire script including the data distribution segment at the end, you will see that there are 13 partitions with each of the monthly partitions containing data.</p>
<p>The distribution of data into the different partitions demonstrates soundly that partitioning can not only be created on a temporary table, but that it can be used.  As for the secondary question today &#8220;Why would you do that?&#8221;, I still do not know.  The only reason that pops into my mind is that you would do it purely for demonstration purposes.  I can&#8217;t think of a production scenario where partitioning temporary data would be a benefit.  If you know of a use case, please let me know.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2382" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/05/23/can-you-partition-a-temporary-table/">Can you partition a temporary table?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/05/23/can-you-partition-a-temporary-table/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Missing Indexes Script v2</title>
		<link>https://jasonbrimhall.info/2014/05/15/missing-indexes-script-v2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=missing-indexes-script-v2</link>
					<comments>https://jasonbrimhall.info/2014/05/15/missing-indexes-script-v2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 15 May 2014 18:43:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[Index Maintenance]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2364</guid>

					<description><![CDATA[<p>As is the case for many DB professionals, I am always tweaking (not twerking) and refining the missing indexes script to try and make it more robust and a little more accurate.</p>
The post <a href="https://jasonbrimhall.info/2014/05/15/missing-indexes-script-v2/">Missing Indexes Script v2</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class=" wp-image-2365 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2014/05/missing_idx.png" alt="missing_idx" width="280" height="227" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/05/missing_idx.png 400w, https://jasonbrimhall.info/wp-content/uploads/2014/05/missing_idx-300x243.png 300w" sizes="(max-width: 280px) 85vw, 280px" /></p>
<p>Frequently we hear the analogy that &lt;insert item here&gt; is like opinions, everybody has one and not all of them are good (some may stink).</p>
<p>Well, this may just be another one of those &lt;items&gt;.  Whether it stinks or not may depend on your mileage.</p>
<p><a href="http://jasonbrimhall.info/2012/01/12/missing-indexes/">I had shared a similar script back in January 2012</a> and wanted to share something a little more current.  As is the case for many DB professionals, I am always tweaking (not twerking) and refining the script to try and make it more robust and a little more accurate.</p>
<p>This version does a couple of things differently than the previous version.  For one, this is a single database at a time (the prior version looped through all of the databases with a less refined query).  Another significant difference is that this query is designed to try and pull information from multiple places about the missing indexes and execution statistics.  I felt this could prove more advantageous and useful than to just pull the information from one place.</p>
<p>Here is the current working script.</p>
<p><em>The following script gets altered on display.  n.VALUE is displayed but in the code it is actually n.value.  The code display is wrong but it is correct in the code as presented in the editor.  If copying from this page, please change the U-cased &#8220;VALUE&#8221; in the XML segment to &#8220;value&#8221; so it will work.  A download of the script has been added at the end.</em></p><pre class="urvanov-syntax-highlighter-plain-tag">SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
IF OBJECT_ID('tempdb..#MissingIndexInfo', 'U') IS NOT NULL
    DROP TABLE #MissingIndexInfo;
IF OBJECT_ID('tempdb..#MissingIdxSuperInfo', 'U') IS NOT NULL
    DROP TABLE #MissingIdxSuperInfo;
IF OBJECT_ID('tempdb..#top20', 'U') IS NOT NULL
    DROP TABLE #top20;

SET NOCOUNT ON;

WITH XMLNAMESPACES  
   (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') 

SELECT query_plan, plan_handle,sql_handle,execution_count,
       n.value('(@StatementText)[1]', 'VARCHAR(4000)') AS sql_text, 
       --n.value('(//MissingIndexGroup/@Impact)[1]', 'FLOAT') AS impact, 
       DB_ID(REPLACE(REPLACE(n.value('(//MissingIndex/@Database)[1]', 'VARCHAR(128)'),'[',''),']','')) AS database_id, 
       OBJECT_ID(n.value('(//MissingIndex/@Database)[1]', 'VARCHAR(128)') + '.' + 
           n.value('(//MissingIndex/@Schema)[1]', 'VARCHAR(128)') + '.' + 
           n.value('(//MissingIndex/@Table)[1]', 'VARCHAR(128)')) AS OBJECT_ID, 
       n.value('(//MissingIndex/@Database)[1]', 'VARCHAR(128)') + '.' + 
           n.value('(//MissingIndex/@Schema)[1]', 'VARCHAR(128)') + '.' + 
           n.value('(//MissingIndex/@Table)[1]', 'VARCHAR(128)')  
       AS STATEMENT
INTO #MissingIndexInfo 
FROM  
( 
   SELECT query_plan,plan_handle,sql_handle,execution_count
   FROM (    
           SELECT DISTINCT plan_handle,sql_handle,execution_count
           FROM sys.dm_exec_query_stats
         ) AS qs 
       OUTER APPLY sys.dm_exec_query_plan(qs.plan_handle) tp     
   WHERE tp.query_plan.exist('//MissingIndex')=1 
) AS tab (query_plan,plan_handle,sql_handle,execution_count) 
CROSS APPLY query_plan.nodes('//StmtSimple') AS q(n) 
WHERE n.exist('QueryPlan/MissingIndexes') = 1 
	AND DB_ID(REPLACE(REPLACE(n.value('(//MissingIndex/@Database)[1]', 'VARCHAR(128)'),'[',''),']','')) = DB_ID()

CREATE CLUSTERED INDEX ci_sqlhandle ON #MissingIndexInfo(sql_handle)

SELECT  MII.database_id ,
        MII.OBJECT_ID ,
        MII.plan_handle ,
        MII.sql_handle ,
        MII.execution_count ,
        CA.equality_columns ,
        CA.inequality_columns ,
        CA.included_columns ,
        CA.Impact ,
        CA.unique_compiles ,
        CA.user_seeks ,
        CA.avg_total_user_cost ,
        CA.avg_user_impact ,
        CA.last_user_seek
INTO    #MissingIdxSuperInfo
FROM    #MissingIndexInfo MII
        CROSS APPLY ( SELECT    mid.database_id ,
                                mid.object_id ,
                                mid.equality_columns ,
                                mid.inequality_columns ,
                                mid.included_columns ,
                                migs.unique_compiles ,
                                migs.user_seeks ,
                                migs.avg_total_user_cost ,
                                migs.avg_user_impact ,
                                migs.last_user_seek ,
                                ( avg_total_user_cost * avg_user_impact )
                                * ( user_seeks + user_scans ) AS Impact
                      FROM      sys.dm_db_missing_index_group_stats AS migs
                                INNER JOIN sys.dm_db_missing_index_groups AS mig 
									ON migs.group_handle = mig.index_group_handle
                                INNER JOIN sys.dm_db_missing_index_details AS mid 
									ON mig.index_handle = mid.index_handle
                                    AND mid.database_id = DB_ID()
                    ) CA
WHERE   1 = 1
	AND CA.database_id = MII.database_id
	AND CA.object_id = MII.OBJECT_ID;

SELECT DISTINCT TOP 20
        plan_handle ,
        MAX(Impact) AS Impact
INTO    #top20
FROM    #MissingIdxSuperInfo
GROUP BY plan_handle
ORDER BY Impact DESC;

WITH    finalsel
          AS ( SELECT   SI.* ,
                        ROW_NUMBER() OVER ( PARTITION BY SI.equality_columns,
                                            SI.inequality_columns,
                                            SI.execution_count ORDER BY SI.Impact DESC ) AS RowNum
               FROM     #MissingIdxSuperInfo SI
                        INNER JOIN #top20 t 
							ON t.plan_handle = SI.plan_handle
             )
    SELECT  fs.* ,
            MII.query_plan ,
            MII.sql_text AS sql_text_inExecplan ,
            MII.STATEMENT AS DB_Schema_Obj ,
            sub.Name ,
            ROW_NUMBER() OVER ( PARTITION BY fs.plan_handle, sub.Name ORDER BY sub.Name ) AS InnerRowNum ,
            ( SELECT    COUNT(*)
              FROM      sys.dm_exec_query_stats s
              WHERE     s.query_hash = sub.query_hash
            ) AS SimilarQueries ,
            ( SELECT    COUNT(*)
              FROM      sys.dm_exec_query_stats s
              WHERE     s.query_plan_hash = sub.query_plan_hash
            ) AS SimilarQueryPlans ,
            ( SELECT    COUNT(qs.query_hash)
              FROM      sys.dm_exec_query_stats qs
              WHERE     qs.sql_handle = MII.sql_handle
              GROUP BY  qs.sql_handle
            ) AS QueriesRelatedtoPlan ,
            ( SELECT    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(CONVERT
					(NVARCHAR(MAX), N'--' + NCHAR(13) + NCHAR(10) + ist.text
                                                              + NCHAR(13)
                                                              + NCHAR(10)
                                                              + N'--' COLLATE Latin1_General_Bin2),
                                                              NCHAR(31), N'?'),
                                                              NCHAR(30), N'?'),
                                                              NCHAR(29), N'?'),
                                                              NCHAR(28), N'?'),
                                                              NCHAR(27), N'?'),
                                                              NCHAR(26), N'?'),
                                                              NCHAR(25), N'?'),
                                                              NCHAR(24), N'?'),
                                                              NCHAR(23), N'?'),
                                                              NCHAR(22), N'?'),
                                                              NCHAR(21), N'?'),
                                                              NCHAR(20), N'?'),
                                                              NCHAR(19), N'?'),
                                                              NCHAR(18), N'?'),
                                                              NCHAR(17), N'?'),
                                                              NCHAR(16), N'?'),
                                                              NCHAR(15), N'?'),
                                                              NCHAR(14), N'?'),
                                                              NCHAR(12), N'?'),
                                                              NCHAR(11), N'?'),
                                                              NCHAR(8), N'?'),
                                                              NCHAR(7), N'?'),
                                                              NCHAR(6), N'?'),
                                                              NCHAR(5), N'?'),
                                                              NCHAR(4), N'?'),
                                                        NCHAR(3), N'?'),
                                                NCHAR(2), N'?'), NCHAR(1),
                                        N'?'), NCHAR(0), N'') AS [processing-instruction(query)]
              FROM      sys.dm_exec_sql_text(fs.sql_handle) AS ist
            FOR
              XML PATH('') ,
                  TYPE
            ) AS QueryDef ,
            cp.objtype
    INTO    #finalsel
    FROM    finalsel fs
            INNER JOIN #MissingIndexInfo MII 
				ON fs.database_id = MII.database_id
                AND fs.OBJECT_ID = MII.OBJECT_ID
                AND fs.plan_handle = MII.plan_handle
            INNER JOIN sys.dm_exec_cached_plans cp 
				ON fs.plan_handle = cp.plan_handle
            CROSS APPLY ( SELECT TOP 1
                                    ISNULL(p.name, 'ADHOC') AS Name ,
                                    query_hash ,
                                    query_plan_hash
                          FROM      sys.dm_exec_query_stats qs
                                    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle)
                                    AS qt
                                    LEFT OUTER JOIN sys.procedures p 
										ON qt.objectid = p.object_id
                          WHERE     qs.plan_handle = fs.plan_handle
                        ) sub
    WHERE   RowNum = 1;

SELECT  fls.database_id,fls.OBJECT_ID,fls.DB_Schema_Obj,fls.Name,fls.objtype,fls.execution_count
		,fls.equality_columns,fls.inequality_columns,fls.included_columns,fls.Impact,fls.unique_compiles
		,fls.user_seeks,fls.avg_total_user_cost,fls.avg_user_impact,fls.last_user_seek
		,fls.query_plan,fls.sql_text_inExecplan,fls.QueryDef
		,fls.SimilarQueries,fls.SimilarQueryPlans,fls.QueriesRelatedtoPlan
	FROM    #finalsel AS fls
	WHERE   InnerRowNum = 1
	ORDER BY Impact DESC;

DROP TABLE #MissingIndexInfo;
DROP TABLE #MissingIdxSuperInfo;
DROP TABLE #top20;
DROP TABLE #finalsel;</pre><p>As has been the case in the past, this is not the end query.  I have a backlog of updates I want to make to the query and try to create something even more useful from it.</p>
<p>As a bit of fair caution, just because an index shows up as a recommended implementation from this script, it does not mean you should blanket implement it.  Also, like the previous script, the higher the impact value, the more probable the index will have a positive impact on your system.</p>
<p>In addition to the impact, I also look at the &#8220;Similar Queries&#8221; and &#8220;Similar Plans&#8221; numbers from the result set.  These values can sometimes lead to an understanding that their are other queries or other plans that could also benefit from the creation of the index.  Your mileage may vary.</p>
<p>Download script <a href="http://jasonbrimhall.info/wp-content/uploads/2014/05/Missing_Index.zip">Missing_Index</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2364" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/05/15/missing-indexes-script-v2/">Missing Indexes Script v2</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/05/15/missing-indexes-script-v2/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #54 &#8211; Interviews and Hiring</title>
		<link>https://jasonbrimhall.info/2014/05/13/t-sql-tuesday-54-interviews-and-hiring/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-54-interviews-and-hiring</link>
					<comments>https://jasonbrimhall.info/2014/05/13/t-sql-tuesday-54-interviews-and-hiring/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 14 May 2014 00:21:42 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2358</guid>

					<description><![CDATA[<p>This month’s T-SQL Tuesday is hosted by Boris Hristov (blog&#124;twitter) and his chosen topic is “Interviews and Hiring” – specifically interviewing and hiring of SQL Server Professionals. &#160; This is a pretty interesting topic from a few [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/05/13/t-sql-tuesday-54-interviews-and-hiring/">T-SQL Tuesday #54 – Interviews and Hiring</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://borishristov.com/blog/t-sql-tuesday-54-interview-invitation/" class="broken_link"><img loading="lazy" class="size-full wp-image-2309 alignleft" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" width="150" height="150" /></a></p>
<p>This month’s <a href="http://borishristov.com/blog/t-sql-tuesday-54-interview-invitation/" target="_blank" class="broken_link">T-SQL Tuesday</a> is hosted by Boris Hristov (<a href="http://borishristov.com/blog/" target="_blank" class="broken_link">blog</a>|<a href="https://web.archive.org/web/20160817032930/https://twitter.com/BorisHristov">twitter</a>) and his chosen topic is “Interviews and Hiring” – specifically interviewing and hiring of SQL Server Professionals.</p>
<p>&nbsp;</p>
<p>This is a pretty interesting topic from a few different angles.  Boris proposed a few topics such as the following list.</p>
<p>&nbsp;</p>
<ol>
<li>The story of how did you get hired on your latest position?</li>
<li>The most interesting interview you ever had?</li>
<li>How do you think an interview should be handled? What should it include?</li>
<li>Any “algorithms” of how to find the perfect candidate?</li>
<li>If you are the one that leads the technical interview – what do you focus on?</li>
<li>What are the most important questions to ask for the various SQL Server positions out there?</li>
</ol>
<p>Any one of these ideas would be good fodder for a blog article.  A combination of these topics might prove more interesting.  I think I will try something a little different.  I want to broach the topic of the use and abuse of interviews.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/05/infinte1.png"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/05/infinte1.png"><img loading="lazy" class="size-full wp-image-2360 aligncenter" alt="infinte" src="http://jasonbrimhall.info/wp-content/uploads/2014/05/infinte1.png" width="238" height="116" /></a></a></p>
<p style="text-align: center;">
<p style="text-align: left;">There are two interviews that come to mind that might be good examples.  The first is the infinite interview.</p>
<p style="text-align: left;">In the infinite interview, the candidate comes in for a full day of interviews (a surprise to the candidate).  If you were lucky you might have been informed in advance that the interview would be an all-day ordeal.</p>
<p style="text-align: left;">You arrive on-site and are shuttled from one interviewer to the next and so on throughout the day.  Most of these people will have absolutely nothing to do with your work queue or your job duties.  Most won&#8217;t be able to spell SQL other than maybe having a book that somebody might have given them.</p>
<p style="text-align: left;">In one such case, I had the opportunity to be grilled all day long.  The peak of the interview(s) occurred when their dev team sat down in an office, gave me chalk and eraser and required me to redesign their database that they took 6+ months to design and were still in the process of fixing bugs.  Lots of memorization based questions centered around developer (not database) terminology.</p>
<p style="text-align: left;">In short this pretty much felt like a free consultation session for them.  Once finished, I got to show my own way out the door.  Not by choice but by them being too busy for it.  And in the end not a word from the company.</p>
<p style="text-align: left;">The second kind of interview comes in the form of stump the chump.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/05/stump.jpg"><img loading="lazy" class=" wp-image-2361 aligncenter" alt="stump" src="http://jasonbrimhall.info/wp-content/uploads/2014/05/stump.jpg" width="480" height="331" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/05/stump.jpg 800w, https://jasonbrimhall.info/wp-content/uploads/2014/05/stump-300x206.jpg 300w" sizes="(max-width: 480px) 85vw, 480px" /></a>This is another fun type of interview.  It can come in many forms.  Sometimes it can be in the form of free consultation.  Sometimes, the interviewer just gets his rocks off trying to prove he is smarter or that you are not as qualified as you say you are.</p>
<p style="text-align: left;">In the type where it comes as free consultation, the interviewer has usually been trying to resolve a production issue for quite some time and just can&#8217;t figure it out.  They will present a partial scenario to you and see if you can figure it out on limited info.  If you can&#8217;t, they might come back with &#8220;We already tried that&#8221; or they may provide more info.  Again, this is all in an effort to try and resolve a problem that they couldn&#8217;t.  Sometimes  it is often to try and save face with the boss showing that even an expert couldn&#8217;t do it.</p>
<p style="text-align: left;">The alternate style, the interviewer knows from the start that you may be overqualified but really wants to just prove they are as smart or smarter.  Often times it just proves that they have some really erroneous understandings about SQL Server.  One such interview, the person seemed to have an explicit Oracle background and wanted to get into the internals of SQL Server.  He wanted to get into index trees and tried to go down the path of some io statistics for queries based on a bunch of unknowns.</p>
<p style="text-align: left;">There is really only one thing to do in these types of interviews.  Once you recognize what is going on (be it stump the chump or the never-ending interview), politely excuse yourself and look for a position somewhere else.</p>
<p style="text-align: center;">
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2358" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/05/13/t-sql-tuesday-54-interviews-and-hiring/">T-SQL Tuesday #54 – Interviews and Hiring</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/05/13/t-sql-tuesday-54-interviews-and-hiring/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Omaha BI/SQL User Group &#8211; What?</title>
		<link>https://jasonbrimhall.info/2014/05/07/omaha-bisql-user-group-what/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=omaha-bisql-user-group-what</link>
					<comments>https://jasonbrimhall.info/2014/05/07/omaha-bisql-user-group-what/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 07 May 2014 13:54:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2356</guid>

					<description><![CDATA[<p>I recently received an email from this guy named John Morehouse (blog &#124; twitter) about the Omaha SQL/BI User Group Meeting in May. Imagine my surprise when reading the email and discovering that I was presenting. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/05/07/omaha-bisql-user-group-what/">Omaha BI/SQL User Group – What?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I recently received an email from this guy named John Morehouse (<a href="http://sqlrus.com/">blog </a>| <a href="https://twitter.com/SqlrUs">twitter</a>) about the <b>Omaha SQL/BI User Group Meeting in May.</b></p>
<p>Imagine my surprise when reading the email and discovering that I was presenting.</p>
<p>Here are the guts of that email.</p>
<blockquote>
<div>Can you believe that it&#8217;s almost May?!  Time sure does fly!</div>
<div></div>
<div>Our next meeting will be on Wednesday May 7th, 2014 @ 6PM.  Food will be available approximately 20-30 minutes prior to the meeting.  We will be at the Farm Credit Services of America facility and our sponsor for the evening is QCI.</div>
<div></div>
<div><strong>Speaker</strong>: Jason Brimhall</div>
<div></div>
<div>Jason Brimhall has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2014. He has experience in performance tuning, high transaction environments, as well as large environments. He is currently a Principal Consultant and MCM. He is he VP of the Las Vegas User Group (SSSOLV).</div>
<div></div>
<div><strong>Topic</strong>: SQL 2012 Extended Events</div>
<div></div>
<div>Extended Events were introduced in SQL Server 2008. With SQL 2012, we have seen a significant upgrade to this feature. Join me for a little adventure into what extended events are. We will discuss how to use extended events to aid in performance tuning and in day to day administration. We will also explore some background and the architecture of extended events.</div>
<div></div>
<div><strong>Sponsor</strong>: QCI</div>
<div></div>
<div>QCI has a long history of attracting and retaining the best talent. Continuous investment in our consultants results in an immediate, positive impact on your projects.  Contact Information: <a href="mailto:Omaha@qci.com" target="_blank" rel="noopener">Omaha@qci.com</a> <a href="tel:402-981-4264" target="_blank" rel="noopener">402-981-4264</a></div>
<div></div>
<div>For further information and to RSVP please go here: http://omahamtg.com/<wbr />Events.aspx?ID=242</div>
<div></div>
<div>Please make sure to RSVP so that we have an accurate head count for food plus a chance to win some awesome SWAG!!</div>
<div></div>
<div>Thanks!</div>
<div></div>
<div>John Morehouse</div>
<div></div>
</blockquote>
<p>Ok, so it really was not a surprise.  John asked and I agreed to present.  If you are in the Omaha area &#8211; come join the group for a pleasant evening and to learn something (hopefully) about SQL Server.</p>
<p><strong>And yes &#8211; the meeting is tonight May 7, 2014.</strong></p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2356" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/05/07/omaha-bisql-user-group-what/">Omaha BI/SQL User Group – What?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/05/07/omaha-bisql-user-group-what/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQLSaturday Vegas Style</title>
		<link>https://jasonbrimhall.info/2014/04/03/sqlsaturday-vegas-style/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlsaturday-vegas-style</link>
					<comments>https://jasonbrimhall.info/2014/04/03/sqlsaturday-vegas-style/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 03 Apr 2014 17:11:14 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[communications]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2349</guid>

					<description><![CDATA[<p>We are mere moments from the inaugural SQL Saturday (announced a few short months ago) event in fabulous Las Vegas, Nevada.  Can you feel the excitement building? The SQLSat 295 team has been working hard [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/04/03/sqlsaturday-vegas-style/">SQLSaturday Vegas Style</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;">
<p style="text-align: center;">
<p style="text-align: center;">
<p style="text-align: center;">
<p style="text-align: center;">
<p><a style="color: #ff4500; line-height: 15.600000381469727px; text-align: center;" href="http://jasonbrimhall.info/wp-content/uploads/2013/12/sqlsat295_web.png"><img loading="lazy" class="alignright size-full wp-image-2221" alt="sqlsat295_web" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/sqlsat295_web.png" width="236" height="115" /></a></p>
<p style="text-align: left;">We are mere moments from the inaugural SQL Saturday (<a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">announced a few short months ago</a>) event in fabulous Las Vegas, Nevada.  Can you feel the excitement building?</p>
<p style="text-align: left;">The SQLSat 295 team has been working hard to bring together what we think will be a great event.  From the volunteers, to the speakers, to the vendors, and most importantly to the attendees.</p>
<p style="text-align: center;"><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg"><img loading="lazy" class=" wp-image-2223 aligncenter" alt="las-vegas-nv2" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg" width="430" height="323" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2-300x225.jpg 300w" sizes="(max-width: 430px) 85vw, 430px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">If you are in Vegas or nearby, we welcome you to come down and check out what we have for you.</p>
<p style="text-align: left;">This event will be held Apr 5 2014 at The InNEVation Center, 6795 Edmond St., Las Vegas, NV 89118.</p>
<p style="text-align: left;">Where else do you get an open invitation to learn about SQL Server for free combined with what Vegas has to offer for entertainment?</p>
<p style="text-align: left;">Just remember, what is learned in Vegas doesn&#8217;t have to stay in Vegas.  But what happens in Vegas is up to your discretion.</p>
<p style="text-align: center;">
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/04/sqlsat295_tokes.png"><img loading="lazy" class="alignright size-full wp-image-2350" alt="sqlsat295_tokes" src="http://jasonbrimhall.info/wp-content/uploads/2014/04/sqlsat295_tokes.png" width="542" height="344" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/04/sqlsat295_tokes.png 542w, https://jasonbrimhall.info/wp-content/uploads/2014/04/sqlsat295_tokes-300x190.png 300w" sizes="(max-width: 542px) 85vw, 542px" /></a></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2349" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/04/03/sqlsaturday-vegas-style/">SQLSaturday Vegas Style</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/04/03/sqlsaturday-vegas-style/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>New Backup Behavior in SQL 2014</title>
		<link>https://jasonbrimhall.info/2014/04/01/new-backup-behavior-in-sql-2014/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=new-backup-behavior-in-sql-2014</link>
					<comments>https://jasonbrimhall.info/2014/04/01/new-backup-behavior-in-sql-2014/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 01 Apr 2014 16:00:30 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[April 1]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2345</guid>

					<description><![CDATA[<p>As has been well publicized, today is the official Release To Manufacturing date for SQL Server 2014.  You can read more about all of that here. Something that hasn&#8217;t received much word is a new [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/04/01/new-backup-behavior-in-sql-2014/">New Backup Behavior in SQL 2014</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As has been well publicized, today is the official Release To Manufacturing date for SQL Server 2014.  You can read more about all of that <a href="http://blogs.technet.com/b/dataplatforminsider/archive/2014/03/18/sql-server-2014-releases-april-1.aspx">here</a>.</p>
<p>Something that hasn&#8217;t received much word is a new feature that is a game changer.  I&#8217;m not referring to the advancements with the In-Memory OLTP (aka Hekaton).  The real game changer in my opinion is the way backups will be treated in 2014.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/04/encryption.jpg"><img loading="lazy" class=" wp-image-2346 alignleft" alt="encryption" src="http://jasonbrimhall.info/wp-content/uploads/2014/04/encryption.jpg" width="339" height="339" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/04/encryption.jpg 692w, https://jasonbrimhall.info/wp-content/uploads/2014/04/encryption-150x150.jpg 150w, https://jasonbrimhall.info/wp-content/uploads/2014/04/encryption-300x300.jpg 300w" sizes="(max-width: 339px) 85vw, 339px" /></a>SQL Server 2014 brings the added functionality of encryption to the database backups.  This is a significant improvement to securing data at rest.  This functionality applies to databases that have been TDE enabled as well as those that are not TDE enabled.  This functionality also applies to backups that are compressed and backups that are not compressed.</p>
<p>The beauty of this functionality is that <em>all</em> backups will be encrypted now by default.  What this means is that you need not configure anything on your end to make it happen.  Despite it being enabled by default, you can change the encryption method should you choose.</p>
<p>Another interesting note with this new default behavior is that <em>all</em> of your database backups will fail out of the box.  You might ask why.  Well, there are some pre-requisites that must be met in order for the encrypted backup to succeed.</p>
<p>Here are those pre-reqs.</p>
<ol>
<li>Create a Database Master Key for the master database.</li>
<li>Create a certificate or asymmetric Key to use for backup encryption.</li>
</ol>
<p>If you have not created your DMK, your backups will fail and you will be none the wiser until you try to restore that backup.  That is really the way you want to conduct your duties as a DBA, right?  You guessed it, the backup shows that it succeeds yet it does nothing.</p>
<p>As you move forward with your SQL 2014 implementation, ensure you create those DMKs and ensure your backups are safe.</p>
<p>Oh and in case you haven&#8217;t noticed, pay attention to <strong><span style="color: #ffff00;"><a href="http://en.wikipedia.org/wiki/April_Fools%27_Day">today&#8217;s date</a></span></strong>.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2345" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/04/01/new-backup-behavior-in-sql-2014/">New Backup Behavior in SQL 2014</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/04/01/new-backup-behavior-in-sql-2014/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #051: Bets and Results</title>
		<link>https://jasonbrimhall.info/2014/02/18/t-sql-tuesday-051-bets-and-results/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-051-bets-and-results</link>
					<comments>https://jasonbrimhall.info/2014/02/18/t-sql-tuesday-051-bets-and-results/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 19 Feb 2014 06:58:52 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2321</guid>

					<description><![CDATA[<p>The line for this months TSQL Tuesday required wagers be made concerning the risks and bets that have either been made or not made. At close, we saw 17 people step up and place remarkable [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/02/18/t-sql-tuesday-051-bets-and-results/">T-SQL Tuesday #051: Bets and Results</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/?p=2299"><img loading="lazy" class="alignright" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" width="150" height="150" /></a></p>
<p>The<a href="http://jasonbrimhall.info/?p=2299"> line for this months TSQL Tuesday</a> required wagers be made concerning the risks and bets that have either been made or not made.</p>
<p>At close, we saw 17 people step up and place remarkable markers.  Today, we will recap the game and let you know who the overall winner from this week of game play in Vegas just happened to be.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/02/poker-hands.png"><img loading="lazy" class="aligncenter size-full wp-image-2322" alt="poker-hands" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/poker-hands.png" width="494" height="572" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/02/poker-hands.png 494w, https://jasonbrimhall.info/wp-content/uploads/2014/02/poker-hands-259x300.png 259w" sizes="(max-width: 494px) 85vw, 494px" /></a></p>
<p>&nbsp;</p>
<p>This is about some bets, so we needed to understand some of the hands that might have won, right?</p>
<p>Let&#8217;s see the hands dealt to each of our players this past week.</p>
<p><a href="http://nebraskasql.blogspot.com/2014/02/t-sql-tuesday-051-always-hedge-your-bets.html"><img loading="lazy" class=" wp-image-2323 alignleft" title="Andy Galbraith" alt="Andy Galbraith" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/fullhouse.png" width="192" height="131" /></a><strong>Andy Galbraith</strong> (<a href="http://nebraskasql.blogspot.com/2014/02/t-sql-tuesday-051-always-hedge-your-bets.html">b</a>|<a href="https://twitter.com/DBA_ANDY">t</a>) shared a full house of risk this month when talking about backups.  Do you have a backup if you haven&#8217;t tested it.</p>
<p><em>&#8220;without regular test restores, your backups do not provide much of a guarantee of recoverability.  (Even successful test restores don&#8217;t 100% guarantee recoverability, but it&#8217;s much closer to 100%).&#8221;</em></p>
<p>&nbsp;</p>
<p><a href="http://borishristov.com/blog/t-sql-tuesday-051-the-bet/" class="broken_link"><img loading="lazy" class="wp-image-2331 alignright" title="Boris Hristov" alt="Boris Hristov" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/flush.png" width="186" height="126" /></a><strong>Boris Hristov</strong> (<a href="http://borishristov.com/blog/t-sql-tuesday-051-the-bet/" class="broken_link">b</a>|<a href="https://web.archive.org/web/20160817032930/https://twitter.com/BorisHristov">t</a>) thought he was feeling lucky.  He couldn&#8217;t imagine things getting worse.  He even kept reminding himself that it couldn&#8217;t get worse.  He was dealt a hand and it was pretty good &#8211; and then everything just flushed down the drain.</p>
<p>A disaster with replication and with the storage system &#8211; ouch!</p>
<p>&nbsp;</p>
<p><strong><a href="http://chrisyatessql.wordpress.com/2014/02/11/t-sql-tuesday-051-place-your-bets/"><img loading="lazy" class=" wp-image-2330 alignleft" title="Chris Yates" alt="Chris Yates" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/straight.png" width="185" height="134" /></a>Chris Yates</strong> (<a href="http://chrisyatessql.wordpress.com/2014/02/11/t-sql-tuesday-051-place-your-bets/">b</a>|<a href="https://twitter.com/YatesSQL">t</a>) wanted to push his hand a little further than Andy this week.  Chris went all-in on his backups.  At least he went all-in early in his career.</p>
<p>The gamble you ask?  Chris didn&#8217;t test the backups until after he learned an important lesson.</p>
<p><em>&#8220;I’ve always been taught to work hard and hone your skill set; for me backups fall right into that line of thinking. Always keep improving, learn from your mistakes.&#8221;</em></p>
<p>&nbsp;</p>
<p><a href="https://sqlnikon.com/2014/02/11/t-sql-tuesday-51-dont-bet-against-checksum-when-performing-backups/"><img loading="lazy" class="wp-image-2330 alignright" title="Doug Purnell" alt="Doug Purnell" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/straight.png" width="185" height="134" /></a><strong>Doug Purnell</strong> (<a href="https://sqlnikon.com/2014/02/11/t-sql-tuesday-51-dont-bet-against-checksum-when-performing-backups/">b</a>|<a href="https://twitter.com/sqlnikon">t</a>) shares another risky move to make.  In this hand, Doug thought he could parlay maintenance plans into an enterprise level backup solution.</p>
<p>What Doug learned is that maintenance plans don&#8217;t offer a checksum for your backups.  After learning that, he decided to stay and get things straight.</p>
<p>&nbsp;</p>
<p><a href="http://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/"><img loading="lazy" class=" wp-image-2329 alignleft" title="Jason Brimhall" alt="Jason Brimhall" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/3kind.png" width="184" height="133" /></a><strong>Jason Brimhall</strong> (<a href="http://jasonbrimhall.info/">b</a>|<a href="https://twitter.com/sqlrnnr">t</a>) took a different approach.  I took the approach of how these career gambles may or may not impact home, family, health, and career in general.</p>
<p>There is a life balance to be sought and gained.  It shouldn&#8217;t be all about work all the time.  And if work is causing health problems, then it is time for a change.</p>
<p>It&#8217;s important to have good health and enjoy life away from work.</p>
<p>&nbsp;</p>
<p><a href="http://devjef.wordpress.com/2014/02/11/t-sql-tuesday-51-place-your-bets/"><img loading="lazy" class="wp-image-2332 alignright" title="Jeffrey Verheul" alt="Jeffrey Verheul" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/highcard.png" width="188" height="153" /></a><strong>Jeffrey Verheul</strong> (<a href="http://devjef.wordpress.com/2014/02/11/t-sql-tuesday-51-place-your-bets/">b</a>|<a href="https://twitter.com/DevJef">t</a>) had multiple hands that many of us have probably seen.  I&#8217;d bet we would even be able to easily relate.</p>
<p>In the end, what stuck with me was how more than once we saw Jeffrey up the ante with a story of somebody who was not playing with a full deck.  If you don&#8217;t have a full deck, sometimes the best hand is not a very good one overall.</p>
<p>&nbsp;</p>
<p><a style="line-height: 1.3em;" href="http://joedantoni.wordpress.com/2014/02/11/t-sql-tuesday-bad-bets/"><img loading="lazy" class=" wp-image-2329 alignleft" title="Joey D'Antoni" alt="Joey D'Antoni" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/3kind.png" width="184" height="133" /></a></p>
<p><strong>Joey D&#8217;Antoni</strong> (<a href="http://joedantoni.wordpress.com/2014/02/11/t-sql-tuesday-bad-bets/">b</a>|<a href="https://twitter.com/jdanton">t</a>) had a nightmare experience that he shared.  We have all seen too many employers like what he described.</p>
<p>The short of it is summed up really will by Joey.</p>
<p><em>&#8220;The moral of this story, is to think about your life ahead of your firms. The job market is great for data pros—if you are unhappy, leave.&#8221;</em></p>
<p>&nbsp;</p>
<p><a href="http://truthsolutions.wordpress.com/2014/02/11/tsql2sday-data-marts-across-a-shaky-wan-link/"><img loading="lazy" class="wp-image-2324 alignright" title="K. Brian Kelley" alt="K. Brian Kelley" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/4kind.png" width="179" height="131" /></a><strong>K. Brian Kelley</strong> (<a href="http://truthsolutions.wordpress.com/2014/02/11/tsql2sday-data-marts-across-a-shaky-wan-link/">b</a>|<a href="https://twitter.com/kbriankelley">t</a>) brought us the first four of a kind.  Not only did he risk life and limb with SQL 7, but he tried to do it over a WAN link that was out of his control.</p>
<p>When he bets, he bets BIG!  DTS failures, WAN failures, SQL 7, SQL 2000, low bandwidth and somebody playing with the nobs and shutting down the WAN links while laughing devishly at the frustration they were causing.</p>
<p>&nbsp;</p>
<p><a href="http://sqlstudies.com/2014/02/11/t-sql-tuesday-51-doubledown-disaster/"><img loading="lazy" class="alignleft  wp-image-2332" title="Kenneth Fisher" alt="Kenneth Fisher" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/highcard.png" width="188" height="153" /></a><strong>Kenneth Fisher</strong> (<a href="http://sqlstudies.com/2014/02/11/t-sql-tuesday-51-doubledown-disaster/">b</a>) thought he would try to one-up Jeffery by getting employers that would not play with a full deck either.</p>
<p>From one POS time tracking system to another POS time tracking system to yet another.  Apparently, time tracking was doomed to failure and isn&#8217;t really that important.</p>
<p>That seems to be a lot of hefty wagers somebody is willing to lay down.</p>
<p>&nbsp;</p>
<p><a href="https://web.archive.org/web/20140406160537/http://mattvelic.com:80/tsql-tuesday-51/"><img loading="lazy" class="wp-image-2325 alignright" title="Matt Velic" alt="Matt Velic" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/straightflush.png" width="180" height="131" /></a><strong>Matt Velic</strong> (<a href="https://web.archive.org/web/20140406160537/http://mattvelic.com:80/tsql-tuesday-51/">b</a>|<a href="https://twitter.com/mvelic">t</a>) brought his A-game.  He was in a no prisoner kind of mood.</p>
<p>Matt decided he was going to real you in, divert your attention, and then lay down the wood hard.  Don&#8217;t try to get anything past Matt &#8211; especially if it wreaks of shifty and illegal.</p>
<p>The way he parlayed his wagers this month was a riot.</p>
<p>&nbsp;</p>
<p><a href="http://mickeystuewe.com/2014/02/11/t-sql-tuesday-51-dont-crap-out-while-betting-on-table-functions/"><img loading="lazy" class="alignleft  wp-image-2328" title="Mickey Stuewe" alt="Mickey Stuewe" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/2pair.png" width="184" height="127" /></a><strong>Mickey Stuewe</strong> (<a href="http://mickeystuewe.com/2014/02/11/t-sql-tuesday-51-dont-crap-out-while-betting-on-table-functions/">b</a>|<a href="https://twitter.com/SQLMickey">t</a>) was the only person willing to Double-down and to even try to place a bet on snake-eyes.  With the two-pronged attack at doubles, she was able to come up with two pairs.</p>
<p>To compound her doubles kind of wagers, she was laying down markers on functions.  Check out her casino wizardry with her display of code and execution plans.</p>
<p>&nbsp;</p>
<p><a href="http://sqlblog.com/blogs/rob_farley/archive/2014/02/11/victims-of-success.aspx" class="broken_link"><img loading="lazy" class="wp-image-2332 alignright" title="Rob Farley" alt="Rob Farley" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/highcard.png" width="188" height="153" /></a><strong>Rob Farley</strong> (<a href="http://sqlblog.com/blogs/rob_farley/archive/2014/02/11/victims-of-success.aspx" class="broken_link">b</a>|<a href="https://twitter.com/rob_farley">t</a>) was a victim of his own early success.  He had a lucky run and then it seemed to peter out a bit.  In the end he was able to manage an Azure high hand</p>
<p>Rob reminds us of some very important things with his post.  You can get lucky every now and again and be successful without a whole lot of foresight.  Be careful and try to plan and test for the what-if moment.</p>
<p>&nbsp;</p>
<p><a href="https://www.sqlservercentral.com/blogs/t-sql-tuesday51-place-your-bets-in-place-upgrade"><img loading="lazy" class="alignleft  wp-image-2327" title="Bobby Tables" alt="Bobby Tables" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/pair.png" width="172" height="126" /></a><strong>Robert Pearl</strong> (<a href="https://www.sqlservercentral.com/blogs/t-sql-tuesday51-place-your-bets-in-place-upgrade">b</a>|<a href="https://twitter.com/PearlKnows">t</a>) rolled the dice in this card game.  He was hoping for a pair of kings with his pair of clusters and the planned but unplanned upgrade.</p>
<p>There is nothing like a last minute decision to upgrade an &#8220;active-active&#8221; cluster.  In the end Bobby Tables had an Ace up his sleeve and was able to pull it out for this sweet pair.</p>
<p>&nbsp;</p>
<p><a style="color: #ff4500; line-height: 15.600000381469727px;" href="http://sqljudo.wordpress.com/2014/02/11/t-sql-tue-51-i-see-your-bad-decision-and-raise-a-horrible-one/"><img loading="lazy" class=" wp-image-2331 alignright" title="Russ Thomas" alt="Russ Thomas" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/flush.png" width="186" height="126" /></a></p>
<p><strong>Russ Thomas</strong> (<a href="http://sqljudo.wordpress.com/2014/02/11/t-sql-tue-51-i-see-your-bad-decision-and-raise-a-horrible-one/">b</a>|<a href="https://twitter.com/SQLJudo">t</a>) ever have the business buy some software and then thrust it on IT to have it installed last minute?</p>
<p>That is almost what happened in this story that had some interesting yet eventual results.</p>
<p>Russ weaves the story very well, but take your eye of the game at hand!!</p>
<p>&nbsp;</p>
<p><a href="http://sqlity.net/en/2061/betting-on-sql-injection/"><img loading="lazy" class="alignleft  wp-image-2325" title="Sebastian Meine" alt="Sebastian Meine" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/straightflush.png" width="180" height="131" /></a></p>
<p>&nbsp;</p>
<p><strong>Sebastian Meine</strong> (<a href="http://sqlity.net/en/2061/betting-on-sql-injection/">b</a>|<a href="https://twitter.com/sqlity">t</a>) brought needles to the table.  That is wicked crazy and leaves quite the impression.</p>
<p>Maybe he thought he was going to inject some cards into the game to improve his hand.  I was almost certain he had nothing going, but magically he was able to produce some favorable data.</p>
<p>Oh, that was the point of his post!  Have a weakness? It will be found, injected and exploited.</p>
<p>&nbsp;</p>
<p><a style="color: #ff4500; line-height: 15.600000381469727px;" href="http://voiceofthedba.wordpress.com/2014/02/11/t-sql-tuesday-51-place-your-bets/"><img loading="lazy" class="alignright  wp-image-2323" title="Steve Jones" alt="Steve Jones" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/fullhouse.png" width="192" height="131" /></a></p>
<p><strong>Steve Jones</strong> (<a href="http://voiceofthedba.wordpress.com/2014/02/11/t-sql-tuesday-51-place-your-bets/">b</a>|<a href="https://twitter.com/way0utwest">t</a>) had a crazy house going.  Imagine 2000 or so people all trying to help you make your bets and play your hand.  That is a FULL house.</p>
<p>Of course, his full house was more to deal with a misunderstood risk with the application and causing performance problems in the database.</p>
<p>In the end, they fixed it and it started working better.  A little testing would have gone a long way on this one!</p>
<p>&nbsp;</p>
<p><a href="http://blog.waynesheffield.com/wayne/archive/2014/02/t-sql-tuesday-51-is-this-a-bet-worth-making/"><img loading="lazy" class="size-full wp-image-2333 alignleft" title="Wayne Sheffield" alt="Wayne Sheffield" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/FOLD.png" width="196" height="120" /></a><strong>Wayne Sheffield</strong> (<a href="http://blog.waynesheffield.com/wayne/archive/2014/02/t-sql-tuesday-51-is-this-a-bet-worth-making/">b</a>|<a href="https://twitter.com/DBAWayne">t</a>) in perhaps the most disappointing and surprising turn of events, Wayne ended up with a hand that could have won but he folded.</p>
<p>Well, Wayne didn&#8217;t fold but there were some bets that resulted in people folding and maybe worse in the story that Wayne shares.  This can happen when you are betting on something you know nothing about and really should get somebody to help make the correct bets for you.</p>
<p>&nbsp;</p>
<p><a style="color: #ff4500; line-height: 15.600000381469727px;" href="https://twitter.com/search?q=%23sqlfamily&amp;src=typd"><img loading="lazy" class="alignright size-full wp-image-2326" title="House = SQLFamily" alt="House" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/royalflush.png" width="207" height="142" /></a></p>
<p>And to recap, the overall winner was&#8230;</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>&#8230;</p>
<p>the <strong>HOUSE</strong>.  With a winning hand of a royal flush.</p>
<p>Thanks to all of the SQLFamily for participating this month.  There were some really great experiences shared.  The posts were great and it was a lot of fun.  I hope you got as much enjoyment out of the topic and articles this month as I did.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2321" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/02/18/t-sql-tuesday-051-bets-and-results/">T-SQL Tuesday #051: Bets and Results</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/02/18/t-sql-tuesday-051-bets-and-results/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Risking Health, Life and Family</title>
		<link>https://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=risking-health-life-and-family</link>
					<comments>https://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Feb 2014 23:02:17 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2308</guid>

					<description><![CDATA[<p>Since announcing the topic last week for T-SQL Tuesday, I have thought about many different possibilities for my post.  All of them would have been really good examples.  The problem has not been the quality [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/">Risking Health, Life and Family</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/?p=2299"><img loading="lazy" class="size-full wp-image-2309 alignright" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/TSQL2sDay150x150.png" width="150" height="150" /></a>Since announcing the topic last week for T-SQL Tuesday, I have thought about many different possibilities for my post.  All of them would have been really good examples.  The problem has not been the quality but in the end just settling on my wager for this hand.</p>
<p>You see, this month T-SQL Tuesday has the theme of risks, betting on a technology, solution or person, or flatly having had an opportunity and not taken it (that&#8217;s a bet too in a sense).  Sometimes we have to play it safe, and sometimes we have to take some degree of risk.</p>
<p>If you are interested, the invite for T-SQL Tuesday is <a href="http://jasonbrimhall.info/?p=2299">here</a> and the deadline for submission is not until Midnight GMT on 12 February.</p>
<h3>It&#8217;s a Crapshoot</h3>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/02/craps-0208.jpg"><img loading="lazy" class="aligncenter  wp-image-2310" alt="craps-0208" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/craps-0208.jpg" width="509" height="339" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/02/craps-0208.jpg 848w, https://jasonbrimhall.info/wp-content/uploads/2014/02/craps-0208-300x199.jpg 300w" sizes="(max-width: 509px) 85vw, 509px" /></a>When all the dice finally settled, I decided it would be best for me to talk about some recent experiences in this Past Post.</p>
<p style="text-align: left;">First a little dribble with the back story.  Just don&#8217;t lose your focus on the price with this PK*.  Readers, please don&#8217;t Press and be patient during this monologue.</p>
<p style="text-align: left;">Over the past year I have been pushing hard with work and SQL.  I was working for a firm as a part of their remote DBA services offering.  As time progressed and I became more and more tenured with the firm, I found that I was working harder and harder.  Not that the work was hard, but that there was a lot of it.</p>
<p style="text-align: left;">Stress rose higher and higher (I must have been oblivious to it).  At one point I started getting frequent migraines.  I went to the doctor to try and figure things out.  I visited the chiropractor to try and figure things out.  The chiropractor proved to be useful and had some profound advice.  He asked me how many hours I would sit in front of the computer on a daily basis (since that was my job).  My reply to him shocked him pretty good.  I was putting in regular 20 hour days.</p>
<p style="text-align: left;"><span style="line-height: 1.3em;">Having weekly chiropractor sessions helped somewhat with the migraines but it was not nearly enough.  I figured I would just have to deal with it since we couldn&#8217;t figure out what the root cause was (yeah we were trying to perf tune this DBA).</span></p>
<p style="text-align: left;">In addition to the chiropractor and traditional medicine to fight migraines, I also tried some homeopathic remedies.  Again, similar results.  It seemed to help but wasn&#8217;t an overall solution and not a consistent solution.</p>
<p style="text-align: left;">Later in the year I found something that seemed to help a little with the migraines too.  I started using <a href="http://www.gunnars.com/">Gunnars</a>.  Sitting in front of a computer for 20 hours a day on most days, it made sense there might be some eye strain.  Wearing the Gunnars, I immediately felt less eye strain.  That was awesome.  Too bad it did not reduce the migraines.</p>
<p style="text-align: left;">After more than a year of having regular migraines, I found that the migraines started occurring more regularly (yes there was a baseline).  Near the end of 2013, I found that there was a period that I had eight straight migraine days.  These migraines typically lasted the duration of the day and there wasn&#8217;t much I could do outside of just dealing with it and making sure work got done.</p>
<p style="text-align: left;">Notice the risk?  What are all of the risks that might be involved at this point?  Yes, I was risking my health, family and work.</p>
<h3 style="text-align: left;">Russian Roulette</h3>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/02/roulette.jpg"><img loading="lazy" class="aligncenter  wp-image-2311" alt="roulette" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/roulette.jpg" width="529" height="350" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/02/roulette.jpg 755w, https://jasonbrimhall.info/wp-content/uploads/2014/02/roulette-300x198.jpg 300w" sizes="(max-width: 529px) 85vw, 529px" /></a>Near the end of the year 2013, I made a very risky decision.  I decided to part ways with the firm and pursue a consulting career.  This was as scary as could possibly be.  I was choosing to leave a &#8220;Safe&#8221; job knowing that I had a job and secured income &#8211; so long as the company did well.</p>
<p style="text-align: left;">Not only was I choosing to gamble with the job change and risking whether or not I would have work flowing in to keep me busy, I was also risking the well-being of my family.  With a family, there is the added risk of ensuring you provide for them.  This was a huge gamble for me.  Not to mention the concern with the migraines and whether I would be able to work this day or that based on the frequency and history of these things.</p>
<p style="text-align: left;">In this case, the bet on Green came up GREEN!  Over two months into this decision I have yet to have a migraine.  For my health this was the right decision.  I have also been lucky enough to be able to get myself into the right consulting opportunity at the right time with the right people.  Because of that, we have been able to keep me busy the whole time.</p>
<p style="text-align: left;">With all of that said, thanks to Randy Knight (<a href="https://twitter.com/randy_knight">@randy_knight</a>) for bringing me in as a Principal Consultant at SQL Solutions Group.  With the change to consulting, Randy has helped to keep my hours down to less than 20 hours a day.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/02/ssg.png"><img loading="lazy" class="aligncenter size-full wp-image-2315" alt="ssg" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/ssg.png" width="313" height="54" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/02/ssg.png 313w, https://jasonbrimhall.info/wp-content/uploads/2014/02/ssg-300x51.png 300w" sizes="(max-width: 313px) 85vw, 313px" /></a></p>
<p style="text-align: left;">The thing about those 20 hour days is there were several people trying to get me to back off.  They&#8217;d say things like &#8220;leave it for tomorrow&#8221; or &#8220;the work will still be there.&#8221;  That may be true, but the firms clients had certain expectations.  Learning when to back off and keep the foot on the gas pedal is something everybody needs to learn.  For me, I felt I had to do it because it was promised to the client.  Now as a consultant, I feel I can better control when those deliverables are due.  Thanks to Wayne (<a href="https://twitter.com/DBAWayne">@DBAWayne</a>) for continuing to point this out as a symptom of &#8220;burnout.&#8221;</p>
<p style="text-align: left;">In the end, it took making a risky change to avoid the burnout and get my health back under control.</p>
<p style="text-align: left;"><em>*PK in this case is a term for a pick &#8217;em bet and not in reference to a Primary Key as is commonly used in SQL Server.</em></p>
<p style="text-align: center;">
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2308" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/">Risking Health, Life and Family</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/02/11/risking-health-life-and-family/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Murder in Richmond</title>
		<link>https://jasonbrimhall.info/2014/02/06/murder-in-richmond/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-in-richmond</link>
					<comments>https://jasonbrimhall.info/2014/02/06/murder-in-richmond/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 06 Feb 2014 23:18:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2304</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/02/06/murder-in-richmond/">Murder in Richmond</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://sqlsaturday.com/277/eventhome.aspx"><img loading="lazy" class="size-full wp-image-2305 alignright" alt="sqlsat277_web" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/sqlsat277_web.png" width="236" height="115" /></a>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p style="text-align: left;"><img loading="lazy" class="aligncenter" alt="loco_stoppedsailing" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/loco_stoppedsailing.jpg" width="448" height="336" />Time to sink or sail, so to speak.  <a href="http://sqlsaturday.com/277/eventhome.aspx">SQL Saturday 277</a> in Richmond will mark the second attempt at what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in our first all day pre-con event.  The session is one of three all day sessions for the event in Richmond VA.</p>
<p>If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3>Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="alignleft" alt="wayne" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" width="141" height="211" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at<a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft" alt="JasonBrimhall" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" width="141" height="211" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" class="aligncenter" alt="kaboom" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" width="301" height="167" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us.  You can find registration information and event details at the Richmond SQL site &#8211; <a href="http://richmondsql.org/cs2007/blogs/events/archive/2014/01/04/sqlsaturday-pre-con-with-wayne-sheffield-and-jason-brimhall.aspx" class="broken_link">here</a>.  There are only 30 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>The cost for the class is $99 if you register by February 20th, when they raise to $125.  <a title="Registration" href="https://www.raceit.com/Register/?event=24549" target="_blank" class="broken_link">When you register</a>, be sure to choose Wayne&#8217;s class.</p>
<h3>Wait, there&#8217;s more&#8230;</h3>
<p>Not only will I be in Richmond for the Precon, I will also be presenting as a part of the SQLSaturday event on Mar 22 2014 (the day after the precon which is Mar 21, 2014).  I have the distinct pleasure of presenting a really fun topic.  My session on table compression was selected for the main event.  So, if you can&#8217;t make it out for the precon, at least come out for the main event.</p>
<p>You can see more details about the topics lined up for this event &#8211; <a href="http://sqlsaturday.com/277/schedule.aspx">here</a>.</p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some pre-con sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2304" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/02/06/murder-in-richmond/">Murder in Richmond</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/02/06/murder-in-richmond/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #051: Place Your Bets</title>
		<link>https://jasonbrimhall.info/2014/02/04/t-sql-tuesday-051-place-your-bets/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-051-place-your-bets</link>
					<comments>https://jasonbrimhall.info/2014/02/04/t-sql-tuesday-051-place-your-bets/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 04 Feb 2014 17:34:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2299</guid>

					<description><![CDATA[<p>Place Your Bets All bets on the table please.  This is the last call for bets, no new bets will be allowed. This marks the 51st invitation for TSQL Tuesday.  This also marks what should [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/02/04/t-sql-tuesday-051-place-your-bets/">T-SQL Tuesday #051: Place Your Bets</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Place Your Bets</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/02/chips.png"><img loading="lazy" class=" wp-image-2300 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2014/02/chips.png" alt="chips" width="262" height="199" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/02/chips.png 437w, https://jasonbrimhall.info/wp-content/uploads/2014/02/chips-300x227.png 300w" sizes="(max-width: 262px) 85vw, 262px" /></a>All bets on the table please.  This is the last call for bets, no new bets will be allowed.</p>
<p>This marks the 51st invitation for TSQL Tuesday.  This also marks what should have been the month of the first SQL Saturday event in Las Vegas.  But the house lost on that event so it was pushed out to April 5th.</p>
<p>With that loss and the subsequent push, it is time for you to put on your <strong><a href="http://www.youtube.com/watch?v=bESGLojNYSo">Poker Face</a></strong>.  This month TSQL Tuesday is taking on a Vegas theme.  I want to know about the gambles within your databases or not within your databases that you have seen over the years.</p>
<p>When has somebody (a CTO, Developer, Business User) placed a bet that was far too risky in your opinion?  What kinds of gambles have been parlayed into catastrophes that could have been easily avoided?  Once you are all in on these dogs and the aggregate limit has been reached, I want to know the handicap and how you fixed it.</p>
<p>Here are some examples.</p>
<ol>
<li>I encountered a Sharepoint database server that had a 940 GB error log.  The log was locked by antivirus software and couldn&#8217;t be cycled.  Upon getting that resolved, I found the log was growing at about 500 MB an hour.  There was a problem with Sharepoint talking to Active Directory.</li>
<li>A developer wrote a cursor that ran for 36 hours.  Upon investigation, the cursor was re-written into a set-based script that ran in 42 seconds.</li>
<li>A 3rd party hosting service stopped SQL Server Services and deleted the system databases.  The line on this bet was that they would have less than 15 minutes of outage and minimal revenue loss.  The reality in this case was a sucker bet.  They lost 4hrs of uptime and nearly 2 million dollars for the client.</li>
</ol>
<p>I will leave it to you to offer up tokes and/or to discuss any trends this may have revealed to you while producing the rundown.  Have fun with it and remember, with databases a big bet is not necessarily worth the risk.</p>
<h3>What is T-SQL Tuesday?</h3>
<p><a href="http://jasonbrimhall.info/?p=2299"><img loading="lazy" class="size-full wp-image-1969 alignright" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a>T-SQL Tuesday is a monthly blog party hosted by a different blogger each month. This blog party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" class="broken_link">blog</a>|<a href="http://twitter.com/adammachanic" target="_blank">twitter</a>). You can take part by posting your own participating post that fits the topic of the month and follows the requirements below. Additionally, if you are interested in hosting a future T-SQL Tuesday, contact Adam Machanic on his blog.</p>
<h3>How to Participate</h3>
<ul>
<li>Your post must be published between 00:00 GMT Tuesday, Fevrier 11e, 2014, and 00:00 GMT Wednesday Fevrier 12e, 2014.</li>
<li>Your post must contain the T-SQL Tuesday logo from above and the image should link back to this blog post.</li>
<li>Trackbacks should work. But, please do add a link to your post in the comments section below so everyone can see your work.</li>
<li>Tweet about your post using the hash tag <a href="https://twitter.com/search?q=%23tsql2sday" target="_blank">#TSQL2sDay</a>.</li>
</ul>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2299" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/02/04/t-sql-tuesday-051-place-your-bets/">T-SQL Tuesday #051: Place Your Bets</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/02/04/t-sql-tuesday-051-place-your-bets/feed/</wfw:commentRss>
			<slash:comments>26</slash:comments>
		
		
			</item>
		<item>
		<title>Table Hierarchy updated</title>
		<link>https://jasonbrimhall.info/2014/01/21/table-hierarchy-updated/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=table-hierarchy-updated</link>
					<comments>https://jasonbrimhall.info/2014/01/21/table-hierarchy-updated/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 21 Jan 2014 20:42:31 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[FK Hierarchy]]></category>
		<category><![CDATA[Foreign Key]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2291</guid>

					<description><![CDATA[<p>Recently a need resurfaced to explore the foreign key tree (hierarchy/genealogy) as it related to a specific table within a database.  As I pulled out the script from the repository, I realized there was some [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/01/21/table-hierarchy-updated/">Table Hierarchy updated</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Recently a need resurfaced to explore the foreign key tree (hierarchy/genealogy) as it related to a specific table within a database.  As I pulled out the script from the repository, I realized there was some unfinished work to be done.  But there was also some polish that needed to be added.  This is an update to the most recent posting of that script.  You can see several revisions in the series at this <a href="http://jasonbrimhall.info/?s=hierarchy">link</a> or the group <a href="http://jasonbrimhall.info/tag/fk-hierarchy/">here</a>.</p>
<p>Some of the changes involve formatting and and labeling.  I added a new column called &#8220;Direction&#8221; to help understand the relationship of the key to the table in question.  I also changed up the FKGenealogy (formerly called SortCol) to reflect the source table more accurately in the case when the key comes from an ancestor rather than a descendant.  The Level of the FK was also modified to help understand a little better how far away the ancestor was in relationship to the origin table.</p>
<p>A final adjustment also comes from the Genealogy attribute.  Ancestors were all starting at the wrong point in the lineage.  I adjusted that so the lineage can be seen from the point in the tree that the ancestor is related rather than as a root direct from the origin table.</p>
<p>All in all, this script should make more sense to the user than the previous versions.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE    @StartParentTable    VARCHAR(256);

SELECT @StartParentTable = 'tblCampaignMain';

With Posterity (ParentTable,ParentColumn, ChildTable,ChildColumn, FKLevel, FKGenealogy) AS (
  SELECT OBJECT_NAME(sfk.referenced_object_id) AS ParentTable
          ,COL_NAME(sfkc.referenced_object_id,sfkc.referenced_column_id) AS ParentColumn
          ,OBJECT_NAME(sfk.Parent_object_id) AS ChildTable
          ,COL_NAME(sfkc.parent_object_id,sfkc.parent_column_id) AS ChildColumn
          ,0 AS FKLevel
          ,CAST('.'+CAST(OBJECT_NAME(sfk.referenced_object_id) AS VARCHAR(MAX))+'.' AS VARCHAR(MAX))
      FROM sys.foreign_key_columns sfkc
          INNER Join sys.foreign_keys sfk
              ON sfkc.constraint_object_id = sfk.OBJECT_ID
      WHERE OBJECT_NAME(sfk.referenced_object_id) = @StartParentTable
  UNION All
  SELECT OBJECT_NAME(sfk.referenced_object_id) AS ParentTable
          ,COL_NAME(sfkc.referenced_object_id,sfkc.referenced_column_id) AS ParentColumn
          ,OBJECT_NAME(sfk.Parent_object_id) AS ChildTable
          ,COL_NAME(sfkc.parent_object_id,sfkc.parent_column_id) AS ChildColumn
          ,FKLevel + 1
          ,STUFF(('.' + F.FKGenealogy + CAST(CAST(OBJECT_NAME(sfk.referenced_object_id) AS VARCHAR(MAX)) + '.' AS VARCHAR(MAX))
                      ),1,1,'')
      FROM sys.foreign_keys sfk
          INNER Join Posterity F
              ON OBJECT_NAME(sfk.referenced_object_id) = F.ChildTable
              And F.FKGenealogy NOT LIKE '%'+CAST(OBJECT_NAME(sfk.referenced_object_id) AS VARCHAR(MAX))+'%'
          INNER Join sys.foreign_key_columns sfkc
              ON sfkc.constraint_object_id = sfk.OBJECT_ID
      WHERE OBJECT_NAME(sfk.referenced_object_id) &lt;&gt; @StartParentTable
          And sfk.referenced_object_id &lt;&gt; sfk.parent_object_id
), Ancestry (ParentTable,ParentColumn, ChildTable,ChildColumn, FKLevel, FKGenealogy) AS (
  SELECT DISTINCT OBJECT_NAME(sfk.referenced_object_id) AS ParentTable
      ,COL_NAME(sfkc.referenced_object_id,sfkc.referenced_column_id) AS ParentColumn
      ,OBJECT_NAME(sfk.Parent_object_id) AS ChildTable
      ,COL_NAME(sfkc.parent_object_id,sfkc.parent_column_id) AS ChildColumn
      ,(FKLevel * -1)-1 AS FKLevel
      ,F.FKGenealogy + CAST(CAST(OBJECT_NAME(sfk.Parent_object_id) AS VARCHAR(MAX))+'.' AS VARCHAR(MAX))
  FROM Posterity F
      INNER Join sys.foreign_keys sfk
          ON F.ChildTable = OBJECT_NAME(sfk.parent_object_id)
          And F.ParentTable &lt;&gt; OBJECT_NAME(sfk.referenced_object_id)
      INNER Join sys.foreign_key_columns sfkc
          ON sfkc.constraint_object_id = sfk.OBJECT_ID
  UNION All
  SELECT OBJECT_NAME(sfk.referenced_object_id) AS ParentTable
      ,COL_NAME(sfkc.referenced_object_id,sfkc.referenced_column_id) AS ParentColumn
      ,OBJECT_NAME(sfk.Parent_object_id) AS ChildTable
      ,COL_NAME(sfkc.parent_object_id,sfkc.parent_column_id) AS ChildColumn
      ,F.FKLevel -1
      ,STUFF(('.' + FKGenealogy + CAST(CAST(OBJECT_NAME(sfk.referenced_object_id) AS VARCHAR(MAX)) + '.' AS VARCHAR(MAX))
                  ),1,1,'')
  FROM Ancestry F
      INNER Join sys.foreign_keys sfk
          ON F.ParentTable = OBJECT_NAME(sfk.parent_object_id)
      INNER Join sys.foreign_key_columns sfkc
          ON sfkc.constraint_object_id = sfk.OBJECT_ID
  WHERE F.ParentTable not in (SELECT ParentTable FROM Posterity)
      And sfk.referenced_object_id &lt;&gt; sfk.parent_object_id
      And F.ChildTable not IN (SELECT ChildTable FROM Posterity)
)

SELECT ParentTable,ParentColumn, ChildTable,ChildColumn, FKLevel, FKGenealogy
	,Case 
		When FKLevel &gt; 0 Then 'Descendant' 
		When FKLevel = 0 Then 'Root'
		End as Direction
FROM Posterity
UNION All
SELECT ParentTable,ParentColumn, ChildTable,ChildColumn, FKLevel, FKGenealogy
	,'Ancestor' as Direction
FROM Ancestry
  ORDER BY FKGenealogy ASC, Direction Desc
  OPTION (maxrecursion 500);</pre><p></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2291" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/01/21/table-hierarchy-updated/">Table Hierarchy updated</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/01/21/table-hierarchy-updated/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Day 12 &#8211; High CPU and Bloat in Distribution</title>
		<link>https://jasonbrimhall.info/2014/01/05/day-12-high-cpu-and-bloat-in-distribution/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-12-high-cpu-and-bloat-in-distribution</link>
					<comments>https://jasonbrimhall.info/2014/01/05/day-12-high-cpu-and-bloat-in-distribution/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 06 Jan 2014 06:32:55 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2273</guid>

					<description><![CDATA[<p>This is the final installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/01/05/day-12-high-cpu-and-bloat-in-distribution/">Day 12 – High CPU and Bloat in Distribution</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the final installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/30/day-6-lost-in-space">Lost in Space</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer">Command &#8216;n Conquer</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/01/day-8-ring-in-the-new/">Ring in The New</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom">Queries Going Boom</a></li>
<li><a href="https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/">Retention of XE Session Data in a Table</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy">Purging syspolicy</a></li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/01/distribution.png"><img loading="lazy" class="aligncenter  wp-image-2275" alt="distribution" src="http://jasonbrimhall.info/wp-content/uploads/2014/01/distribution-1024x768.png" width="448" height="336" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/01/distribution-1024x768.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/01/distribution-300x225.png 300w, https://jasonbrimhall.info/wp-content/uploads/2014/01/distribution.png 1502w" sizes="(max-width: 448px) 85vw, 448px" /></a></p>
<p style="text-align: left;">Working with replication quite a bit with some clients you might run across some particularly puzzling problems.  This story should shed some light on one particularly puzzling issue I have seen on more than one occasion.</p>
<p style="text-align: left;">In working with a multi-site replication and multi-package replication topology, the cpu was constantly running above 90% utilization and there seemed to be a general slowness even in Windows operations.</p>
<p style="text-align: left;">Digging into the server took some time to find what might have been causing the slowness and high CPU.  Doing an overall server health check helped point in a general direction.</p>
<p style="text-align: left;">Some clues from the general health check were as follows.</p>
<ol>
<li>distribution database over 20GB.  This may not have been a necessarily bad thing but the databases between all the publications weren&#8217;t that big.</li>
<li>distribution cleanup job taking more than 5 minutes to complete.  Had the job been cleaning up records, this might not have been an indicator.  In this case, 0 records were cleaned up on each run.</li>
</ol>
<p>The root cause seemed to be pointing to a replication mis-configuration.  The mis-configuration could have been anywhere from the distribution agent to an individual publication.  Generally, it seems that the real problem is more on a configuration of an individual publication more than any other setting.</p>
<p>When these conditions are met, it would be a good idea to check the publication properties for each publication.  Dive into the distribution database and try to find if any single publication is the root cause and potentially is retaining more replication commands than any other publication.  You can use sp_helppublication to check the publication settings for each publication.  You can check MSrepl_commands in the distribution database to find a correlation of commands retained to publication.</p>
<p>Once having checked all of this information, it&#8217;s time to put a fix in place.  It is also time to do a little research before actually applying this fix.  Why?  Well, because you will want to make sure this is an appropriate change for your environment.  For instance, you may not want to try this for a peer-to-peer topology.  In part because one of the settings can&#8217;t be changed in a peer-to-peer topology.  I leave that challenge to you to discover in a testing environment.</p>
<p>The settings that can help are as follows.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC sp_changepublication 
    @publication = 'somepub', -- put your publication name here 
    @property = 'allow_anonymous', 
    @value = 'false' 
GO 

EXEC sp_changepublication 
    @publication = 'somepub', -- put your publication name here 
    @property = 'immediate_sync', 
    @value = 'false' 
GO</pre><p>[/codesyntax]</p>
<p>These settings can have a profound effect on the distribution retention, the cleanup process and your overall CPU consumption.  Please <strong>test</strong> and <strong>research</strong> before implementing these changes.</p>
<p>Besides the potential benefits just described, there are other benefits to changing these commands.  For instance, changing replication articles can become less burdensome by disabling these settings.  The disabling of these settings can help reduce the snapshot load and allow a single article to be snapped to the subscribers instead of the entire publication.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2273" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/01/05/day-12-high-cpu-and-bloat-in-distribution/">Day 12 – High CPU and Bloat in Distribution</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/01/05/day-12-high-cpu-and-bloat-in-distribution/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Day 11 &#8211; Purging syspolicy</title>
		<link>https://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-11-purging-syspolicy</link>
					<comments>https://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 04 Jan 2014 13:00:28 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2270</guid>

					<description><![CDATA[<p>This is the eleventh installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/">Day 11 – Purging syspolicy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the eleventh installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/30/day-6-lost-in-space">Lost in Space</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer">Command &#8216;n Conquer</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/01/day-8-ring-in-the-new/">Ring in The New</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom">Queries Going Boom</a></li>
<li><a href="https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/">Retention of XE Session Data in a Table</a></li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/01/Garbage-Dump.jpg"><img loading="lazy" class="aligncenter  wp-image-2271" alt="Garbage-Dump" src="http://jasonbrimhall.info/wp-content/uploads/2014/01/Garbage-Dump.jpg" width="645" height="484" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/01/Garbage-Dump.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/01/Garbage-Dump-300x225.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">Did you know there is a default job in SQL Server that is created with the purpose of removing system health phantom records?  This job also helps keep the system tables ,that are related to policy based management, nice and trim if you have policy based management enabled.  This job could fail for one of a couple of reasons.  And when it fails it could be a little annoying.  This article is to discuss fixing one of the causes for this job to fail.</p>
<p style="text-align: left;">I want to discuss when the job will fail due to the job step related to the purging of the system health phantom records.  Having run into this on a few occasions, I found several proposed fixes, but only one really worked consistently.</p>
<p style="text-align: left;">The error that may be trapped is as follows:</p>
<p><strong><em>A job step received an error at line 1 in a PowerShell script. </em></strong><br />
<strong><em>The corresponding line is &#8216;(Get-Item SQLSERVER:\SQLPolicy\SomeServer\DEFAULT).EraseSystemHealthPhantomRecords()&#8217;. </em></strong><br />
<strong><em>Correct the script and reschedule the job. The error information returned by PowerShell is: </em></strong><br />
<strong><em>&#8216;SQL Server PowerShell provider error: Could not connect to &#8216;SomeServer\DEFAULT&#8217;. </em></strong><br />
<strong><em>[Failed to connect to server SomeServer. &#8211;&gt;</em></strong></p>
<p style="text-align: left;">The first proposed fix came from Microsoft at this <a href="http://support.microsoft.com/kb/955726">link</a>.  In the article it proposed the root cause of the problem being due to the servername not being correct.  Now that article is specifically for clusters, but I have seen this issue occur more frequently on non-clusters than on clusters.  Needless to say, the advice in that article has yet to work for me.</p>
<p style="text-align: left;">Another proposed solution I found was to try deleting the &#8220;\Default&#8221; in the agent job that read something like this.</p>
<p style="text-align: left;">(Get-Item SQLSERVER:\SQLPolicy\SomeServer\Default).EraseSystemHealthPhantomRecords()</p>
<p style="text-align: left;">Yet another wonderful proposal from the internet suggested using Set-ExecutionPolicy to change the execution policy to UNRESTRICTED.</p>
<p style="text-align: left;">Failed &#8220;fix&#8221; after failed &#8220;fix&#8221; is all I was finding.  Then it dawned on me.  I had several servers where this job did not fail.  I had plenty of examples of how the job should look.  Why not check those servers and see if something is different.  I found a difference and ever since I have been able to use the same fix on multiple occasions.</p>
<p style="text-align: left;">The server where the job was succeeding had this in the job step instead of the previously pasted code.</p>
<p>if (&#8216;$(ESCAPE_SQUOTE(INST))&#8217; -eq &#8216;MSSQLSERVER&#8217;) {$a = &#8216;\DEFAULT&#8217;} ELSE {$a = &#8221;};<br />
(Get-Item SQLSERVER:\SQLPolicy\$(ESCAPE_NONE(SRVR))$a).EraseSystemHealthPhantomRecords()</p>
<p>That, to my eyes, is a significant difference.  Changing the job step to use this version of the job step has been running successfully for me without error.</p>
<p>I probably should have referenced a different server instead of resorting to the internet in this case.  And that stands for many things &#8211; check a different server and see if there is a difference and see if you can get it to work on a different server.  I could have saved time and frustration by simply looking at local &#8220;resources&#8221; first.</p>
<p>If you have a failing syspolicy purge job, check to see if it is failing on the phantom record cleanup.  If it is, try this fix and help that job get back to dumping the garbage from your server.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2270" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/">Day 11 – Purging syspolicy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/01/04/day-11-purging-syspolicy/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Day 10 &#8211; Retention of XE Session Data in a Table</title>
		<link>https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-10-retention-of-xe-session-data-in-a-table</link>
					<comments>https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 03 Jan 2014 13:13:58 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Management Data Warehouse]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2266</guid>

					<description><![CDATA[<p>Gathering event information is a pretty good thing.  It can do wonders for helping to troubleshoot.  What do you do if you need or want to be able to review the captured information in 3 months or maybe 12 months from now?</p>
The post <a href="https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/">Day 10 – Retention of XE Session Data in a Table</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the tenth installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/30/day-6-lost-in-space">Lost in Space</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer">Command &#8216;n Conquer</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/01/day-8-ring-in-the-new/">Ring in The New</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom">Queries Going Boom</a></li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2014/01/food-storage.jpg"><img loading="lazy" class="aligncenter size-full wp-image-2268" src="http://jasonbrimhall.info/wp-content/uploads/2014/01/food-storage.jpg" alt="food-storage" width="400" height="261" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/01/food-storage.jpg 400w, https://jasonbrimhall.info/wp-content/uploads/2014/01/food-storage-300x195.jpg 300w" sizes="(max-width: 400px) 85vw, 400px" /></a></p>
<p>&nbsp;</p>
<p>Gathering event information is a pretty good thing.  It can do wonders for helping to troubleshoot.  What do you do if you need or want to be able to review the captured information in 3 months or maybe 12 months from now?</p>
<p>Retaining the session data for later consumption is often a pretty essential piece of the puzzle.  There is more than one way to accomplish that goal.  I am going to share one method that may be more like a sledgehammer for some.  It does require that Management Data Warehouse be enabled prior to implementing.</p>
<p>When using MDW to gather and retain the session data, you create a data collector pertinent to the data being collected and retained.  In the following example, I have a data collector that is created to gather deadlock information from the system health session.  In this particular case, I query the XML in the ring buffer to get the data that I want.  Then I tell the collector to gather that info every 15 minutes.  The collection interval is one of those things that needs to be adjusted for each environment.  If you collect the info too often, you could end up with a duplication of data.  Too seldom and you could miss some event data.  It is important to understand the environment and adjust accordingly.</p>
<p>Here is that example.</p><pre class="urvanov-syntax-highlighter-plain-tag">BEGIN TRANSACTION 
BEGIN Try 
DECLARE @collection_set_id_1 INT 
DECLARE @collection_set_uid_2 uniqueidentifier 
EXEC [msdb].[dbo].[sp_syscollector_create_collection_set] @name=N'system_health_deadlock', @collection_mode=1, 
@description=N'system_health_deadlock', @logging_level=1, @days_until_expiration=14, 
@schedule_name=N'CollectorSchedule_Every_15min', @collection_set_id=@collection_set_id_1 OUTPUT, 
@collection_set_uid=@collection_set_uid_2 OUTPUT 

SELECT @collection_set_id_1, @collection_set_uid_2 

DECLARE @collector_type_uid_3 uniqueidentifier 
SELECT @collector_type_uid_3 = collector_type_uid FROM [msdb].[dbo].[syscollector_collector_types] 
WHERE name = N'Generic T-SQL Query Collector Type'; 
DECLARE @collection_item_id_4 INT 
EXEC [msdb].[dbo].[sp_syscollector_create_collection_item] 
@name=N'system_health_deadlock'
, @parameters=N'&lt;ns:TSQLQueryCollector xmlns:ns="DataCollectorType"&gt;&lt;Query&gt;&lt;Value&gt;

SELECT CAST(
                  REPLACE(
                        REPLACE(XEventData.XEvent.value(''(data/value)[1]'', ''varchar(max)''), 
                        '''', ''''),
                  '''','''')
            AS XML) AS DeadlockGraph
FROM
(SELECT CAST(target_data AS XML) AS TargetData
from sys.dm_xe_session_targets st
join sys.dm_xe_sessions s on s.address = st.event_session_address
where name = ''system_health'') AS Data
CROSS APPLY TargetData.nodes (''//RingBufferTarget/event'') AS XEventData (XEvent)
where XEventData.XEvent.value(''@name'', ''varchar(4000)'') = ''xml_deadlock_report'' 

&lt;/Value&gt;&lt;OutputTable&gt;system_health_deadlock&lt;/OutputTable&gt;&lt;/Query&gt;&lt;/ns:TSQLQueryCollector&gt;', 
@collection_item_id=@collection_item_id_4 OUTPUT
, @frequency=900 --#seconds in collection interval
,@collection_set_id=@collection_set_id_1
, @collector_type_uid=@collector_type_uid_3 

SELECT @collection_item_id_4 

COMMIT TRANSACTION; 
END Try 
BEGIN Catch 
ROLLBACK TRANSACTION; 
DECLARE @ErrorMessage NVARCHAR(4000); 
DECLARE @ErrorSeverity INT; 
DECLARE @ErrorState INT; 
DECLARE @ErrorNumber INT; 
DECLARE @ErrorLine INT; 
DECLARE @ErrorProcedure NVARCHAR(200); 
SELECT @ErrorLine = ERROR_LINE(), 
@ErrorSeverity = ERROR_SEVERITY(), 
@ErrorState = ERROR_STATE(), 
@ErrorNumber = ERROR_NUMBER(), 
@ErrorMessage = ERROR_MESSAGE(), 
@ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-'); 
RAISERROR (14684, @ErrorSeverity, 1 , @ErrorNumber, @ErrorSeverity, @ErrorState, @ErrorProcedure, 
@ErrorLine, @ErrorMessage); 

END Catch; 

GO</pre><p>Looking this over, there is quite a bit going on.  The keys are the following paramaters: @parameters and @interval.  The @parameters parameter stores the XML query to be used when querying the ring buffer (in this case).  It is important to note that the XML query in this case needs to ensure that the values node is capped to a max of varchar(4000) like shown in the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">where XEventData.XEvent.value(''@name'', ''varchar(4000)'')</pre><p>With this data collector, I have trapped information and stored it for several months so I can compare notes at a later date.</p>
<p><em>This article predated the original XEvent Series. To find that series, please check it out <a href="http://bit.ly/XE60Days">here</a>.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2266" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/">Day 10 – Retention of XE Session Data in a Table</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/01/03/day-10-retention-of-xe-session-data-in-a-table/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Day 9 &#8211; Queries Going Boom</title>
		<link>https://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-9-queries-going-boom</link>
					<comments>https://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 02 Jan 2014 13:17:20 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2261</guid>

					<description><![CDATA[<p>This is the ninth installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom/">Day 9 – Queries Going Boom</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the ninth installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/30/day-6-lost-in-space">Lost in Space</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer">Command &#8216;n Conquer</a></li>
<li><a href="http://jasonbrimhall.info/2014/01/01/day-8-ring-in-the-new/">Ring in The New</a></li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2014/01/Kaboom.png"><img loading="lazy" class="aligncenter  wp-image-2262" alt="Kaboom" src="http://jasonbrimhall.info/wp-content/uploads/2014/01/Kaboom.png" width="645" height="484" srcset="https://jasonbrimhall.info/wp-content/uploads/2014/01/Kaboom.png 1024w, https://jasonbrimhall.info/wp-content/uploads/2014/01/Kaboom-300x225.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Ever see an error like this??</p>
<p><em><strong>The query processor ran out of internal resources and could not produce a query plan. </strong></em><em><strong>This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions. Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.</strong></em></p>
<p><em><strong>Error 8623</strong></em><br />
<em><strong>Severity 16</strong></em></p>
<p>That is a beautiful error.  The message is replete with information and gives you everything needed to fix the problem, right?  More than a handful of DBAs have been frustrated by this error.  It&#8217;s not just DBAs that this message seems to bother.  I have seen plenty of clients grumble about it too.</p>
<p>The obvious problem is that we have no real information as to what query caused the error to pop.  The frustrating part is that the error may not be a persistent or consistent issue.</p>
<p>Thanks to the super powers of XE (extended events), we can trap that information fairly easily now.  Bonus is that to trap that information, it is pretty lightweight as far as resource requirements go.</p>
<p>Without further ado, here is a quick XE session that could be setup to help trap this bugger.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE EVENT SESSION
    overly_complex_queries
ON SERVER
ADD EVENT sqlserver.error_reported
(
    ACTION (sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.database_id, sqlserver.username)
    WHERE ([severity] = 16
		AND [error_number] = 8623)
)
ADD TARGET package0.asynchronous_file_target
(set filename = 'C:\Database\XE\overly_complex_queries.xel' ,
    metadatafile = 'C:\Database\XE\overly_complex_queries.xem',
    max_file_size = 10,
    max_rollover_files = 5)
WITH (MAX_DISPATCH_LATENCY = 5SECONDS)
GO

-- Start the session
ALTER EVENT SESSION overly_complex_queries
    ON SERVER STATE = START
GO</pre><p>[/codesyntax]</p>
<p>And now for the caveats.  This session will only work on SQL 2012.  The second caveat is that there are two file paths defined in this session that must be changed to match your naming and directory structure for the output files etc.</p>
<p>Should you try to create this session on SQL Server 2008 (or 2008 R2) instead of SQL Server 2012, you will get the following error.</p>
<p><span style="color: #ff0000;">Msg 25706, Level 16, State 8, Line 1</span><br />
<span style="color: #ff0000;">The event attribute or predicate source, &#8220;error_number&#8221;, could not be found.</span></p>
<p>Now that you have the session, you have a tool to explore and troubleshoot the nuisance &#8220;complex query&#8221; error we have all grown to love.  From here, the next step would be to explore the output.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2261" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom/">Day 9 – Queries Going Boom</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2014/01/02/day-9-queries-going-boom/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Day 7 &#8211; Command &#8216;n Conquer</title>
		<link>https://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-7-command-n-conquer</link>
					<comments>https://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 31 Dec 2013 17:09:30 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2255</guid>

					<description><![CDATA[<p>This is the seventh installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer/">Day 7 – Command ‘n Conquer</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the seventh installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/30/day-6-lost-in-space">Lost in Space</a></li>
</ol>
<p>As a DBA, we sometimes like to shortcut things.  Not shortcutting a process or something of importance.  The shortcuts are usually in the realm of trying to shortcut time, or shortcut the number of steps to perform a task or shortcutting by automating a process.</p>
<p>We seldom like to perform the same task over and over and over again.  Click here, click there, open a new query window, yadda yadda yadda.  When you have 100 or so servers to run the same script against &#8211; it could be quite tedious and boring.  When that script is a complete one-off, there probably isn&#8217;t much sense in automating it either.</p>
<p>To do something like I just described, there are a few different methods to get it done.  The method I like to use is via SQLCMD mode in SSMS.  Granted, if I were to use it against 100 servers, it would be a self documenting type of script.  I like to use it when setting up little things like replication.</p>
<p>How many times have you scripted a publication and the subscriptions?  How many times have you read the comments?  You will see that the script has instructions to run certain segments at the publisher and then other segments at the subscriber.  How many times have you handed that script to somebody else to run and they just run it on the one server?</p>
<p>Using SQLCMD mode and then adding a CONNECT command in the appropriate places could solve that problem.  The only thing to remember is to switch to SQLCMD mode in SSMS.  Oh and switching to SQLCMD mode is really easy.  The process to switch to SQLCMD mode is even documented.  You can read all about that <a href="http://technet.microsoft.com/en-us/library/ms174187.aspx">here</a>.</p>
<p>And there you have it, yet another simple little tidbit to take home and play with in your own little lab.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2255" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer/">Day 7 – Command ‘n Conquer</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/31/day-7-command-n-conquer/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Day 6 &#8211; Lost in Space</title>
		<link>https://jasonbrimhall.info/2013/12/30/day-6-lost-in-space/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-6-lost-in-space</link>
					<comments>https://jasonbrimhall.info/2013/12/30/day-6-lost-in-space/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 30 Dec 2013 17:47:34 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2251</guid>

					<description><![CDATA[<p>This is the sixth installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/30/day-6-lost-in-space/">Day 6 – Lost in Space</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the sixth installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Peer Identity</a></li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/bluemarble.png"><img loading="lazy" class="aligncenter  wp-image-2252" alt="Credit: NASA/JPL" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/bluemarble.png" width="486" height="486" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/bluemarble.png 540w, https://jasonbrimhall.info/wp-content/uploads/2013/12/bluemarble-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2013/12/bluemarble-300x300.png 300w" sizes="(max-width: 486px) 85vw, 486px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">One of the more frequently recurring themes I see in my travel and work is the perpetual lack of space.</p>
<p style="text-align: left;">For instance, every time I fly there is inevitably a handful of people that have at least three carry-on items and at least one of those items is larger than the person trying to &#8220;carry&#8221; it on the plane.  Imagine watching these people trying to lift 100+ pound bags over their heads to put them into these small confined overhead storage compartments.  We are talking bags that are easily 2-3 times larger than the accepted dimensions, yet somehow this person made it on the plane with such a huge bag for such a tiny space.</p>
<p style="text-align: left;">Another favorite of mine is watching what appears to be a college student driving home in a <a href="http://en.wikipedia.org/wiki/File:95-97_Geo_Metro_3door.jpg">GEO Metro</a>.  A peek inside the vehicle might reveal 5 or 6 baskets of soiled laundry and linens.  A look at the vehicle as a whole might reveal a desert caravan&#8217;s worth of supplies packed onto the vehicle.  Watching the vehicle for a while you might notice that it can only lumber along at a top speed of 50 mph going downhill and good luck getting back up the hill.  It is just far too over-weighted and over-packed.  The vehicle obviously does not have enough room internally.</p>
<p style="text-align: left;">In both of these examples we have a limited amount of storage space.  In both of these examples we see people pushing the boundaries of those limitations.  Pushing those boundaries could lead to some unwanted consequences.  The GEO could break down leaving the college student stranded with dirty laundry.  The air-traveler just may have to check their dog or leave it home.</p>
<p style="text-align: left;">But what happens when people try to push the boundaries of storage with their databases?  The consequences can be far more dire than either of the examples just shared.  What if pushing those boundaries causes an outage and your database is servicing a hospital full of patient information (everything from diagnostics to current allergies &#8211; like being allergic to dogs on planes)?  The doctor needs to give the patient some medication immediately or the patient could die.  The doctor only has two choices and one of those could mean death the other could mean life.  All of this is recorded in the patient records but the doctor can&#8217;t access those records because the server is offline due to space issues.</p>
<p style="text-align: left;">Yeah that would pretty much suck.  But we see it all the time.  Maybe nothing as extreme as that case, but plenty of times I have seen business lose money, revenue, and sales because the database was offline due to space.  The company wants to just keep pushing those boundaries.</p>
<p style="text-align: left;">In one case, I had a client run themselves completely out of disk space.  They wouldn&#8217;t allocate anymore space so it was time to start looking to see what could be done to alleviate the issue and get the server back online.</p>
<p style="text-align: left;">In digging about, I found that this database had 1Tb of the 1.8TB allocated to a single table.  That table had a clustered index built on 6 columns.  The cool thing about this clustered index is that not a single query ever used that particular combination.  Even better was that the database was seldom queried.  I did a little bit of digging and found that there really was a much better clustered index for the table in question.  Changing to the new clustered index reduced the table size by 300GB.  That is a huge chunk of waste.</p>
<p style="text-align: left;">Through similar exercises throughout the largest tables in the database, I was able to reduce index space waste by 800GB.  Disk is cheap until you can&#8217;t have anymore.  There is nothing wrong with being sensible about how we use the space we have been granted.</p>
<p style="text-align: left;">Thinking about that waste, I was reminded of a great resource that Paul Randal has shared.  You can find a script he wrote, to explore this kind of waste, from this <a href="http://www.sqlskills.com/blogs/paul/code-to-list-potential-cluster-key-space-savings-per-table/">link</a>.  You can even read a bit of background on the topic from this <a href="http://www.sqlskills.com/blogs/paul/survey-results-how-cluster-key-size-can-lead-to-gbs-of-wasted-space/">link</a>.</p>
<p style="text-align: left;">
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2251" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/30/day-6-lost-in-space/">Day 6 – Lost in Space</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/30/day-6-lost-in-space/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Day 5 &#8211; Peer Identity</title>
		<link>https://jasonbrimhall.info/2013/12/29/day-5-peer-identity/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-5-peer-identity</link>
					<comments>https://jasonbrimhall.info/2013/12/29/day-5-peer-identity/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sun, 29 Dec 2013 12:49:36 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2246</guid>

					<description><![CDATA[<p>This is the fifth installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Broken Broker [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Day 5 – Peer Identity</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the fifth installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Reviewing Peers</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Broken Broker</a></li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/identity1.png"><img loading="lazy" class="wp-image-2249 alignleft" alt="identity" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/identity1.png" width="296" height="347" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/identity1.png 470w, https://jasonbrimhall.info/wp-content/uploads/2013/12/identity1-256x300.png 256w" sizes="(max-width: 296px) 85vw, 296px" /></a>In the digital age it seems we are constantly flooded with articles about identity crises.  From identity theft to mistaken identity.  SQL server is not immune to these types of problems and stories.  Whether SQL Server was housing the data that was stolen ,leading to identity theft, or if SQL Server is having an identity management issue of its own &#8211; SQL Server is definitely susceptible to the identity issues.</p>
<p>The beauty of SQL Server is that these identity issues seem to be most prevalent when trying to replicate data.  Better yet is when the replication multiple peers setup in a <a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Peer-to-Peer topology</a>.</p>
<p>When these Identity problems start to crop up there are a number of things that can be done to try and resolve them.  One can try to manually manage the identity ranges or one can flip the &#8220;Not for Replication&#8221; attribute on the table as two possible solutions.</p>
<p>The identity crisis in replication gets more fun when there are triggers involved.  The triggers can insert into a table that is not replicated or can insert into a table that is replicated.  Or even better is when the trigger inserts back into the same table it was created on.  I also particularly like the case when the identity range is manually managed but the application decides to reseed the identity values (yeah that is fun).</p>
<p>In one particular peer-to-peer topology I had to resort to a multitude of fixes depending on the article involved.  In one case we flipped the &#8220;Not for Replication&#8221; flag because the tables acted on via trigger were not involved in replication.  In another we disabled a trigger because we determined the logic it was performing was best handled in the application (it was inserting a record back into the table the trigger was built on).  And there was that case were the table was being reseeded by the application.</p>
<p>In the case of the table being reseeded we threw out a few possible solutions but in the end we felt the best practice for us would be to extend the schema and extend the primary key.  Looking back on it, this is something that I would suggest as a first option in most cases because it makes a lot of sense.</p>
<p>In our case, extending the schema and PK meant adding a new field to the PK and assigning a default value to that field.  We chose for the default value to be @@ServerName.  This gave us a quick location identifier for each location and offered us a quick replication check to ensure records were getting between all of the sites (besides relying on replication monitor).</p>
<p>When SQL Server starts throwing a tantrum about identities, keep in mind you have options.  It&#8217;s all about finding a few possible solutions or mix of solutions and proposing those solutions and then testing and implementing them.</p>
<p>One of the possible errors you will see during one of these tantrums is as follows.</p>
<p><em>Explicit value must be specified for identity column in table &#8216;blah&#8217; either when IDENTITY_INSERT is set to ON or when a <strong>replication</strong> user is inserting into a NOT FOR REPLICATION identity column.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2246" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/29/day-5-peer-identity/">Day 5 – Peer Identity</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/29/day-5-peer-identity/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Day 4 &#8211; Broken Broker</title>
		<link>https://jasonbrimhall.info/2013/12/28/day-4-broken-broker/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-4-broken-broker</link>
					<comments>https://jasonbrimhall.info/2013/12/28/day-4-broken-broker/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 28 Dec 2013 13:01:42 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Service Broker]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2243</guid>

					<description><![CDATA[<p>This is the fourth installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Reviewing Peers Brokers &#160; [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Day 4 – Broken Broker</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the fourth installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/ ‎">Reviewing Peers</a></li>
</ol>
<p><img loading="lazy" class="wp-image-2244 alignright" alt="mini-Broker" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/mini-Broker.bmp" width="346" height="229" /></p>
<h3>Brokers</h3>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="line-height: 1.3em;">On a recent opportunity to restore a database for a client, I experienced something new.  </span></p>
<p>I thought it was intriguing and it immediately prompted some questions.  First, let&#8217;s take a look at the message that popped up during the restore and then on to what was done to resolve the problem.</p>
<p>&nbsp;</p>
<p><strong>Query notification delivery could not send message on dialog ‘{someguid}.’. Delivery failed for notification ‘anotherguid;andanotherguid‘ because of the following error in service broker: ‘The conversation handle “someguid″ is not found.’</strong></p>
<p>My initial reaction was &#8220;Is Service Broker enabled?&#8221;  The task should have been a relatively easy straight forward database restore and then to setup replication after that.  My next question that popped up was &#8220;Is SB necessary?&#8221;</p>
<p>Well the answers that came back were &#8220;Yes&#8221; and &#8220;YES!!!&#8221;  Apparently without SB, the application would break in epic fashion.  That is certainly not something that I want to do.  There are enough broke brokers and broke applications without me adding to the list.</p>
<p>Occasionally when this problem arises it means that the Service Broker needs a &#8220;reset.&#8221;  And in this case it makes a lot of sense.  I had just restored the database and there would be conversations that were no longer valid.  Those should be ended and the service broker &#8220;reset.&#8221;</p>
<p>The &#8220;reset&#8221; is rather simple.  First a word of warning &#8211; do not run this on your production instance or any instance without an understanding that you are resetting SB and it could be that conversations get hosed.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER DATABASE  &amp;lt;dbname&amp;gt; SET NEW_BROKER WITH ROLLBACK IMMEDIATE</pre><p>[/codesyntax]</p>
<p>For me, this worked like a charm.  There was also substantial reason to proceed with it.  If you encounter this message, this is something you may want to research and determine if it is an appropriate thing to do.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2243" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/28/day-4-broken-broker/">Day 4 – Broken Broker</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/28/day-4-broken-broker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Day 3 &#8211; Reviewing Peers</title>
		<link>https://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day-3-reviewing-peers</link>
					<comments>https://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 27 Dec 2013 12:53:58 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2228</guid>

					<description><![CDATA[<p>This is the third installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Burning Time Remember back in the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Day 3 – Reviewing Peers</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the third installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">SQL Sat LV announcement</a></li>
<li><a href="http://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">Burning Time</a></li>
</ol>
<p>Remember back in the day when <a href="http://en.wikipedia.org/wiki/Napster">Napster </a>was really popular?  I&#8217;m sure it is still popular now &#8211; just not in the same league as the early years.  Napster pretty much made some revolutionary changes in file-sharing across the internet.  Now the algorithms and the method have become more advanced and use a hive approach, but it still pretty much boils down to the setup that Napster used &#8211; Peer to Peer.</p>
<p style="text-align: center;"><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2013/12/peer-pressure.jpg"><img loading="lazy" class="aligncenter  wp-image-2237" alt="peer-pressure" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/peer-pressure-1024x724.jpg" width="448" height="316" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/peer-pressure-1024x724.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2013/12/peer-pressure-300x212.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2013/12/peer-pressure.jpg 1296w" sizes="(max-width: 448px) 85vw, 448px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">In the P2P file-share world, every node had a part to play.  If you downloaded a file, your machine could also upload that file or other files to the network for other users.  This approach required full files in order to work.</p>
<p style="text-align: center;">
<p style="text-align: center;">
<p style="text-align: center;">
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/p2p_net.gif"><img loading="lazy" class="aligncenter size-full wp-image-2235" alt="p2p_net" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/p2p_net.gif" width="400" height="386" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">In the Hive approach, the files are broken up into chunks.  So you still participate on a P2P basis, but you no longer need to have the complete file to participate.  (I am probably over-generalizing, but that is ok &#8211; the point is coming soon.)  This helped transfers be quicker and the P2P network/hive to be larger (in case you were wondering).</p>
<p style="text-align: left;">Now, let&#8217;s take that idea and move it down to a smaller chunk of data.  What if we did that with a database and only sent a record at a time to a partner and that partner could send a few records back to the first partner/peer?  Now we have something that could be pretty usable in many scenarios.  One such scenario could be to sync data from the same database at ten different locations (or maybe 100 different locations) so all locations would have current information.</p>
<p style="text-align: left;">Well, SQL Server does have that technology available for use.  Coincidentally enough, it is called Peer-to-Peer replication.  Truth be told, it is really more of a two transactional replication on steroids.  In SQL 2008, you had to setup transactional replication in order to create the P2P.  But in SQL 2012, there is now an option on the publication types for Peer-to-Peer.</p>
<p style="text-align: left;">Setting up P2P replication in SQL 2012 is pretty easy to do.  Here is a quick step-through on doing just that.  I will bypass the setup of the distributor and jump straight into setting up the publication through to the point of adding peers.  From that point, it will be left to you to determine what kind of subscription (push/pull) you use and to figure out how to configure those types.</p>
<h3 style="text-align: left;">Step-through</h3>
<p style="text-align: left;">The first step is to expand the tree in SSMS until you see replication and then to expand that to see &#8220;Local Publications.&#8221;  From &#8220;Local Publications,&#8221; right click and select &#8220;New Publication.&#8221;</p>
<p style="text-align: left;"><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2013/12/menu.png"><img loading="lazy" class="aligncenter size-full wp-image-2234" alt="menu" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/menu.png" width="355" height="257" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/menu.png 355w, https://jasonbrimhall.info/wp-content/uploads/2013/12/menu-300x217.png 300w" sizes="(max-width: 355px) 85vw, 355px" /></a></p>
<p style="text-align: left;">
<p style="text-align: left;">Then it is almost as easy as following the prompts as I will show in the following images.  You need to select the database you wish to be included in the P2P publication.</p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;"><img loading="lazy" class="aligncenter size-full wp-image-2232" alt="db_selection" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/db_selection.png" width="501" height="453" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/db_selection.png 501w, https://jasonbrimhall.info/wp-content/uploads/2013/12/db_selection-300x271.png 300w" sizes="(max-width: 501px) 85vw, 501px" /></p>
<p style="text-align: left;">
<p style="text-align: left;">Then it is a matter of selecting the publication type.  Notice here that Peer to Peer has been highlighted.</p>
<p style="text-align: left;"><img loading="lazy" class="aligncenter size-full wp-image-2239" alt="repl_selection" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/repl_selection.png" width="501" height="453" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/repl_selection.png 501w, https://jasonbrimhall.info/wp-content/uploads/2013/12/repl_selection-300x271.png 300w" sizes="(max-width: 501px) 85vw, 501px" /></p>
<p style="text-align: left;">Of course, no replication is complete without some articles to include in the replication.  In this case, I have chosen to just replicate a few of the articles and not every article in the database.  When replicating data, I recommend being very picky about what articles (objects) get included in the replication.  No sense in over-replicating and sending the entire farm across the wire to Beijing, London, Paris and Moscow.</p>
<p style="text-align: left;"><img loading="lazy" class="aligncenter size-full wp-image-2240" alt="table_selection" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/table_selection.png" width="501" height="453" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/table_selection.png 501w, https://jasonbrimhall.info/wp-content/uploads/2013/12/table_selection-300x271.png 300w" sizes="(max-width: 501px) 85vw, 501px" /></p>
<p style="text-align: left;">Once the articles are selected, it will be time to setup the agent security.  Again, this is pretty straight forward.  And in my contrived setup, I am just going to rely on the SQL Server Agent Service account.  The screen will inform you that it is not best practice.  I will leave that as a exercise for you to explore.</p>
<p style="text-align: left;"><img loading="lazy" class="aligncenter size-full wp-image-2231" alt="agent_security" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/agent_security.png" width="501" height="453" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/agent_security.png 501w, https://jasonbrimhall.info/wp-content/uploads/2013/12/agent_security-300x271.png 300w" sizes="(max-width: 501px) 85vw, 501px" /><img loading="lazy" class="aligncenter size-full wp-image-2233" alt="log_reader_security" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/log_reader_security.png" width="538" height="465" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/log_reader_security.png 538w, https://jasonbrimhall.info/wp-content/uploads/2013/12/log_reader_security-300x259.png 300w" sizes="(max-width: 538px) 85vw, 538px" /></p>
<p style="text-align: left;">With that last piece of configuration, the publication is ready.  Just click your way through to finish.</p>
<p style="text-align: left;">Once the publication is complete, it is time to add a subscriber to the publication.  That is easily accomplished by right clicking the publication.  Since this is a P2P publication, we need to select &#8220;Configure Peer-To-Peer Topology&#8230;&#8221;</p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;"><img loading="lazy" class="aligncenter size-full wp-image-2236" alt="p2p_topology_menu" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/p2p_topology_menu.png" width="370" height="273" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/p2p_topology_menu.png 370w, https://jasonbrimhall.info/wp-content/uploads/2013/12/p2p_topology_menu-300x221.png 300w" sizes="(max-width: 370px) 85vw, 370px" /></p>
<p style="text-align: left;">Selecting that menu option will bring up the Wizard.  First step in the new wizard is to pick the publisher and the publication at that publisher that needs to be have the topology configured.</p>
<p style="text-align: left;">
<p style="text-align: left;"><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2013/12/publication_selection.png"><img loading="lazy" class="aligncenter size-full wp-image-2238" alt="publication_selection" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/publication_selection.png" width="501" height="453" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/publication_selection.png 501w, https://jasonbrimhall.info/wp-content/uploads/2013/12/publication_selection-300x271.png 300w" sizes="(max-width: 501px) 85vw, 501px" /></a></p>
<p style="text-align: left;">
<p style="text-align: left;">After selecting the publisher and publication then I can add nodes to the P2P topology by right-clicking the &#8220;map&#8221; (as I like to call it) area.  Select &#8220;Add a New Peer Node&#8221; from the menu and then enter the appropriate details for the new subscriber.</p>
<p style="text-align: left;">
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/add_node.png"><img loading="lazy" class="aligncenter size-full wp-image-2230" alt="add_node" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/add_node.png" width="503" height="455" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/add_node.png 503w, https://jasonbrimhall.info/wp-content/uploads/2013/12/add_node-300x271.png 300w" sizes="(max-width: 503px) 85vw, 503px" /></a></p>
<p style="text-align: left;">
<p style="text-align: left;">It is here that I will conclude this short tutorial.  Configuring the topology is an exercise best left to each individual circumstance.  Configuring where the pull subscribers will be and where the push subscribers will be is almost an art.  Have fun with it.</p>
<p style="text-align: left;">I have had the opportunity to use this kind of setup on a large multi-node setup across several sites.  It runs pretty smoothly.  Sometimes it can get to be a hair-raising event when a change gets introduced that borks the schema.  But those are the events that permit you to learn and grow and document what has happened and how to best handle the issues in your environment.</p>
<p style="text-align: left;">I have even taken a multi-site P2P setup and just added a 1 direction subscriber (as if it were a transactional publication) so the subscriber could just get the information and run reports without pushing changes back up into the rest of the topology.  That also works pretty well.  Document the design and be willing to change it up in case there appears to be latency and too much peer pressure.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2228" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/">Day 3 – Reviewing Peers</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/27/day-3-reviewing-peers/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>12 Days of Christmas 2013 Day 2</title>
		<link>https://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=12-days-of-christmas-2013-day-2</link>
					<comments>https://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 26 Dec 2013 12:58:48 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[communications]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2225</guid>

					<description><![CDATA[<p>This is the second installment in the 12 day series for SQL tidbits during this holiday season. Previous articles in this mini-series on quick tidbits: SQL Sat LV announcement Recently I was able to observe [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">12 Days of Christmas 2013 Day 2</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the second installment in the 12 day series for SQL tidbits during this holiday season.</p>
<p>Previous articles in this mini-series on quick tidbits:</p>
<ol>
<li>SQL Sat LV announcement</li>
</ol>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/burningtime.jpg"><img loading="lazy" class="aligncenter  wp-image-2226" alt="burningtime" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/burningtime.jpg" width="461" height="614" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/burningtime.jpg 768w, https://jasonbrimhall.info/wp-content/uploads/2013/12/burningtime-225x300.jpg 225w" sizes="(max-width: 461px) 85vw, 461px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">Recently I was able to observe an interesting exchange between a couple of key people at a client.  That exchange gave me a bit to ponder.  I wanted to recount a bit of that exchange here.  All names have been, well you know how that goes.</p>
<p style="text-align: left;">Accountant Joe came in early one wintry morning.  He was gung-ho and ready for the day ahead.  Joe had huge plans to finish counting all of the beans and get his task list done for the day.  You see, taskmaster Judy had been harping on him significantly over the past week to get his beans counted.</p>
<p style="text-align: left;">On this frosty morning, Joe was zipping along.  As more and more people filed into the office from the various departments, Joe was still contentedly counting his beans.  That only lasted for a few fleeting moments with everybody in the office though.</p>
<p style="text-align: left;">Suddenly Joe could no longer count the beans.  The beans Joe was counting were served up via the backend database.  And since the beans were running too sow, Joe called the helpdesk to have them fix the database.  A few moments later, Sally called the helpdesk too.  Sally was complaining about things being horribly slow too.  Sally was trying to open the company calendar (Sally is the executive secretary).</p>
<p style="text-align: left;">More and more calls were coming in to the helpdesk from various departments and every user-base in the company.  The helpdesk was busy fighting this fire or that fire.  Finally news of the slowness is escalated to the DBA Dillon so he could investigate why the beans were so slow on this frosty day.  As Dillon investigated, he noticed that IO stalls were off the charts.  He was seeing IO stalls in the hundred second range instead of the milli-second range like normal.</p>
<p style="text-align: left;">Like a dilligent DBA, Dillon immediately escalated the issue to the sysops team who was responsible for the SAN (yeah he notified his manager too).  Bill from sysops promptly responded.  Sadly the response was &#8220;<strong>I am too busy at the moment.</strong>&#8220;</p>
<p style="text-align: left;"><em>After much pestering, Bill finally became available and was ready to help &#8211; 4 hours later.</em></p>
<p style="text-align: left;">As it turns out, the SAN that housed all company shares, applications, databases and even Exchange was down to about 30GB free space.  Due to the lack of free space, the SAN degraded performance automatically to try and prevent it from filling up entirely.  Bill knew about this pending failure and had ordered extra storage &#8211; which sat on his desk for 2+ weeks.</p>
<p style="text-align: left;">The entire company was essentially down because Bill ended up being <em>too busy</em> (in a meeting).  Though the issue was eventually resolved &#8211; the sting has yet to fade.</p>
<p style="text-align: left;">When faced with an outage situation, let this story be your gift to remind you of how not to treat the outage.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2225" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/">12 Days of Christmas 2013 Day 2</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/26/12-days-of-christmas-2013-day-2/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>12 Days of Christmas 2013 Day 1</title>
		<link>https://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=12-days-of-christmas-2013-day-1</link>
					<comments>https://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 25 Dec 2013 12:58:54 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2220</guid>

					<description><![CDATA[<p>Last year I did a mini-series themed around the 12 Days of Christmas.  I am going to do a similar series this year.  Over the next 12 days, I will share short tidbits on an [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">12 Days of Christmas 2013 Day 1</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Last year I did a mini-series themed around the <a href="http://en.wikipedia.org/wiki/Twelve_Days_of_Christmas">12 Days of Christmas</a>.  I am going to do a similar series this year.  Over the next 12 days, I will share short tidbits on an array of topics.  The tidbit may be a tip to help with SQL Server, or it could be an announcement that is SQL related.  As an example, the announcement could be a short bit of information on how to get SQL training.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg"><img loading="lazy" class="aligncenter  wp-image-2223" alt="las-vegas-nv2" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg" width="614" height="461" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2013/12/las-vegas-nv2-300x225.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>To kick things off, there is a pretty cool announcement from the Desert.  Down in Vegas we have been working pretty hard to bring some free SQL learning to the area.  And we have finally done it.  The inaugural SQL Saturday in Las Vegas is confirmed.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/12/sqlsat295_web.png"><img loading="lazy" class="aligncenter size-full wp-image-2221" alt="sqlsat295_web" src="http://jasonbrimhall.info/wp-content/uploads/2013/12/sqlsat295_web.png" width="236" height="115" /></a></p>
<p>&nbsp;</p>
<p>The first SQL Saturday in Las Vegas is to be held on April 5, 2014.  You can register for the event and submit presentations via this <a href="http://sqlsaturday.com/295/eventhome.aspx">link</a>.</p>
<p>It was great to hear that we could get the venue on a good date.  The people at InNEVation are stoked to have this event in their building.</p>
<p>Many thanks to the Stacia Misner and Pat Wright for pulling this together.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2220" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/">12 Days of Christmas 2013 Day 1</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/25/12-days-of-christmas-2013-day-1/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>To DBA or Not to DBA (DBA Jumpstart)</title>
		<link>https://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=to-dba-or-not-to-dba-full</link>
					<comments>https://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 10 Dec 2013 13:00:31 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Professional Development]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2169</guid>

					<description><![CDATA[<p>This post is part of the SQL Community Project started by John Sansom called #DBAJumpStart. &#8220;If you could give a DBA just one piece of advice, what would it be?&#8221; John asked 20 successful and [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/">To DBA or Not to DBA (DBA Jumpstart)</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<div>This post is part of the SQL Community Project started by John Sansom called #DBAJumpStart.</div>
<div></div>
<div>&#8220;If you could give a DBA just one piece of advice, what would it be?&#8221;</div>
<div></div>
<div>John asked 20 successful and experienced SQL Server professionals this exact question. I share my own thoughts with you below and you can find all our answers together inside <a href="http://www.johnsansom.com/dba-jumpstart/" target="_blank">DBA JumpStart</a>, a unique collection of inspiring content just for SQL Server DBAs. Be sure to get your free copy of <a href="http://www.johnsansom.com/dba-jumpstart/" target="_blank">DBA JumpStart</a>.</div>
<div></div>
<p>In my day to day operations I have the opportunity to work with people in various capacities in regards to data.  Sometimes it is in the capacity of a mentor, sometimes in the capacity of a consultant, and sometimes just in the capacity of the dude that fixes the problem.</p>
<p>I enjoy working as a database professional.  There may be times when I want to scream or yell or pull out my teeth and hair.  Then there are times when I just bounce off the walls with joy and pleasure.  Some may call that a manic-depressive disorder.  They just don&#8217;t understand the true life of a data professional.</p>
<p><b>Reminiscing</b></p>
<p>In becoming a data professional, I took the long route to get where I am.  I made the decision to work with SQL and learn about SQL 17 years ago.  I made the decision to learn about SQL because I viewed it as a really difficult thing to learn.  I wanted that challenge.  Then again, back then I also enjoyed the challenge of learning to configure Cisco routers.</p>
<p>Early on, I passed the Microsoft exams for SQL 6.5.  A couple of years later, I finally landed a job where I got to touch a database.  That was part of my duties with being in one man shops.  I worked in a few of those one man shops for a while where I had to be the exchange admin, domain admin, DBA, and even janitor at one shop.  I don&#8217;t miss the days of having to fix the plumbing in between troubleshooting performance issues and checking the router for DoS attacks.</p>
<p>Eventually I got an opportunity with a larger enterprise to be a production DBA.  All I had to do was work with SQL Server all day long.  It was fun designing metrics and monitors to alert on various thresholds while saving the company oodles of money.  I really thought I was learning something cool.  I thought I was doing pretty good too.</p>
<p>Fast forward a little more and a couple of job changes and I found myself living in Las Vegas and getting more involved in the community.  Boy did I learn quickly how little I actually knew about SQL Server.  Sure, there was reading of posts, books and forums before that.  But that just didn&#8217;t quite open my eyes like becoming involved.</p>
<p>I soon started applying myself even more so I could learn more about SQL Server and then be able to try and teach those things to the developers where I worked.  I also started working on trying be good enough to be able to teach people at User Group meetings.  Throw in the efforts to answer questions on forums and writing articles &#8211; and it was an explosion of learning.</p>
<p>Now I present pretty regularly at User Group meetings.  I travel around the world to present at SQL Saturdays.  I have contributed articles and co-authored a book.  I also had (still have) the sweet opportunity to participate in the Mentoring project hosted by Andy Warren.  I even went so far as to challenge myself and attained the MCM.  Yet, I know that I have really only scratched the tip of the iceberg with SQL Server.  There is so much to learn about SQL Server still.  If I were to compare myself past to present, I would rate my skills in various areas lower now than I probably did back in the day.</p>
<p>Through the years, and more particularly the more recent years, I have observed many teammates and DBAs for clients.  These observations have revealed some good and some bad.  When I notice certain behaviors that need to be changed, I try to use it as a teaching opportunity.</p>
<p><b>Price of Rice</b></p>
<p>One thing I find myself doing on a frequent basis is to try and gauge if I might be treating my work as a 9-5 J O B or if I am treating it like a career?  Am I just punching the clock or am I investing in myself and improving my skills?  Am I helping others improve their skills or am I hording the knowledge like an Oracle DBA?</p>
<p>As I observe others, I can&#8217;t help to ponder some of those same questions.  For instance, if I encounter a veteran DBA of 10 or so years that can&#8217;t perform a transaction log backup, I will wonder if being a DBA is just a J O B for that person.  The way you treat your work duties is often transparent about how much you care for the quality of work you do and is also revealing in how much one values their skills.</p>
<p>Taken that same DBA that can&#8217;t perform a log backup, I might start to wonder if their is a time investment outside of work to better their skills.  I might wonder why I have to show that person five or six times how to perform that log backup.  This may sound a tad judgmental, but it is not meant in that way.  Let&#8217;s call it an informal assessment to try and figure out how to help that person become more efficient at performing their job duties.</p>
<p>As a data professional, I think it is an important thing to do.  Spend some time on introspection and try to determine just how much of a career the job is.  Find out if it is a career or if it is on the short end of the spectrum that points to it being just a J O B.</p>
<p>As a team lead, I like to give everybody on the team the task of taking 15-30 minutes each day (on the clock) to improve their skill-set in some way.  This is a tactic that does not work in all environments and with all employers &#8211; I get that.  But if that 15 minutes a day means that the teammate will be more efficient down the road, it is a good investment.  If that 15 minutes means there will be less time redoing some work, then it is time well spent.</p>
<p>As I mentioned earlier, there is plenty about SQL Server that I still need to learn.  An important component of learning is to invest some time.  It&#8217;s a matter of finding a topic and then taking the time to research.  I do my research by reading and then experimenting.  Once I feel comfortable with that research, I will typically write about the topic.  Why?  It helps to solidify or to disprove some of the principles just learned.  It also helps to cement that research into memory.  I also like to do it because it serves as a personal archive that I can refer back to at some future point (I have done that plenty of times).</p>
<p>Another thing I like to do after learning about something different in SQL Server is to present it to a group of people.  That group can be co-workers, a user group, or at a SQL Saturday (as a few examples).  The beauty of presenting on the topic is that it helps me to embed that knowledge a little further.  It also helps me to try and gain an even deeper understanding of the topic to be able to answer questions that may arise. Best of all is that it helps to disseminate knowledge to others.</p>
<p><b>Recap</b></p>
<p>For me, being a data professional equates to a career.  I get that for some it is just a J O B &#8211; and that is fine.  For some, it may just be a J O B because they have not figured out how to advance it into a meaningful career.  Those people don&#8217;t want to just be a clock puncher and want to make something more of their chosen profession.</p>
<p>As a data professional, I suggest the following practices to help turn your profession into a career.</p>
<ol>
<li>Regular introspection &#8211; check in with yourself on occasion to keep yourself headed in the right direction.</li>
<li>Learn something new &#8211; Treat this like a cursor. Keep finding something new to learn and act on it.</li>
<li>Give Back and Get Involved &#8211; When you learn something new, teach it to somebody or post it on a blog. This helps give back to the community and more people can learn and grow.</li>
</ol>
<p>These three simple steps can help turn a J O B into a career.  Better yet is that these steps can help to invest in yourself.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2169" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/">To DBA or Not to DBA (DBA Jumpstart)</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/12/10/to-dba-or-not-to-dba-full/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Cloud Nirvana</title>
		<link>https://jasonbrimhall.info/2013/11/12/cloud-nirvana/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cloud-nirvana</link>
					<comments>https://jasonbrimhall.info/2013/11/12/cloud-nirvana/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 Nov 2013 23:58:15 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2189</guid>

					<description><![CDATA[<p>T-SQL Tuesday is a recurring blog party, that is started by Adam Machanic (Blog &#124; @AdamMachanic). Each month a blog will host the party, and everyone that want’s to can write a blog about a specific subject. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/11/12/cloud-nirvana/">Cloud Nirvana</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://www.sqlchicken.com/2013/11/t-sql-tuesday-48-cloud-atlas/"><img loading="lazy" class="size-full wp-image-1969 alignleft" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" width="150" height="150" /></a>T-SQL Tuesday is a recurring blog party, that is started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" target="_blank" class="broken_link">Blog</a> | <a href="http://twitter.com/adammachanic" target="_blank">@AdamMachanic</a>). Each month a blog will host the party, and everyone that want’s to can write a blog about a specific subject.</p>
<p>This month the subject is “Cloud Atlas”. If you want to read the invite, please click the image below to go to the party-starter: Jorge Segarra (<a href="http://www.sqlchicken.com/" target="_blank">Blog</a> | <a href="https://twitter.com/sqlchicken" target="_blank">@SQLChicken</a>).</p>
<p>For me, this will be a quick entry on my part to participate.  I have a mixed bag of feelings about the Cloud and the buzz-wordiness that implies.</p>
<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/mushroom.jpg"><img loading="lazy" class="size-full wp-image-2190 alignright" alt="mushroom" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/mushroom.jpg" width="259" height="194" /></a>Disaster Struck</h3>
<p>One of my biggest concerns with the cloud is the gloom and doom that has been felt by a client after a bout of corruption struck their database.  The person on staff responsible for backups did a fantastic job of ensuring the database was backed up on a daily basis.  That is not the doom and gloom sadly.</p>
<p>This particular case turned sour after corruption hit the database.  The web application no longer connected to the database.  The data was corrupt.  The database was inaccessible.  The client was distraught and sweating bullets.  The client and the employee new not what to do so they sought me out to get some help.</p>
<p>After an assessment, we determined that the database needed to restored from backup.  All of the backups were done fastidiously &#8211; to the cloud.  The backups were only accessible through a specific application and the process required copying the backup from the cloud down to the server via the application.  The process is pretty easy, right?</p>
<p>The recovery of the database took an entire week!  The copy down through the application from the cloud was destructive to the business to say the least.  The company had little to no chance of surviving being out of business for the outage caused by this scenario.</p>
<h3 style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/thunder-cloud.jpg"><img loading="lazy" class="aligncenter  wp-image-2191" alt="thunder-cloud" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/thunder-cloud.jpg" width="480" height="319" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/11/thunder-cloud.jpg 800w, https://jasonbrimhall.info/wp-content/uploads/2013/11/thunder-cloud-300x199.jpg 300w" sizes="(max-width: 480px) 85vw, 480px" /></a>Nirvana</h3>
<p style="text-align: left;">On the more positive side, there may be a silver lining to the cloud for many people.  I have done more than my share of successful Cloud migrations.  I have also seen many applications work very well from the Cloud.</p>
<p style="text-align: left;">One benefit to me personally about the Cloud is the ability to quickly spin up resources or even servers.  Much like a VM farm, I can request more resources for a Server during specific workload times.  And I can also dial down the gauges a bit when the workload is less intense.</p>
<p style="text-align: left;">I really like the idea of spinning up a machine in a matter of a few clicks and minutes.  When SQL 2014 released CTP2, this was fantastic.  I know several people took advantage of this ability and began playing with CTP2 almost immediately after the announcement of the CTP2 release.</p>
<p style="text-align: left;">Is the cloud right for you?  I can&#8217;t say.  I have had success and failure related specifically to the cloud that might not have happened in a less &#8220;nimble&#8221; environment.  The decision to move to the Cloud is frequently the decision made by somebody other than the technologist that must support the technology and the decision.  If you are moving to the Cloud, you may succeed and enjoy it or you may fail and hate it.  Your mileage will vary.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2189" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/11/12/cloud-nirvana/">Cloud Nirvana</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/11/12/cloud-nirvana/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Murder They Wrote</title>
		<link>https://jasonbrimhall.info/2013/11/05/murder-they-wrote/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=murder-they-wrote</link>
					<comments>https://jasonbrimhall.info/2013/11/05/murder-they-wrote/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 05 Nov 2013 19:00:05 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[Training]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2179</guid>

					<description><![CDATA[<p>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/11/05/murder-they-wrote/">Murder They Wrote</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://sqlsaturday.com/233/eventhome.aspx"><img loading="lazy" class="alignright size-full wp-image-2180" alt="sqlsat233_web" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/sqlsat233_web.png" width="236" height="115" /></a>I am about to set sail on a new venture with my next official whistle stop.  This year has been plenty full of whistle stops and I plan on continuing.  You can read (in full) about previous whistle stops and why they are called whistle stops <a href="http://jasonbrimhall.info/?s=whistle+stop">here</a>.</p>
<p>Suffice it to say at this point that it all started with a comment about a sailing train a few months back.</p>
<p style="text-align: left;"><img loading="lazy" class="wp-image-2181 aligncenter" alt="loco_stoppedsailing" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/loco_stoppedsailing.jpg" width="448" height="336" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/11/loco_stoppedsailing.jpg 640w, https://jasonbrimhall.info/wp-content/uploads/2013/11/loco_stoppedsailing-300x225.jpg 300w" sizes="(max-width: 448px) 85vw, 448px" />Time to sink or sail, so to speak.  <a href="http://sqlsaturday.com/233/eventhome.aspx">SQL Saturday 233</a> in Washington DC will mark the premier of what I hope to be a repeat performance &#8211; many times.  I will be tag-teaming with Wayne Sheffield in our first all day pre-con event.  The session is one of three all day sessions for the event in Chevy Chase, MD.</p>
<p style="text-align: left;">If you are a DBA or a database developer, this session is for you.  If you are managing a database and are experiencing performance issues, this session is a must.  We will chat with attendees about a horde of performance killers and other critical issues we have seen in our years working with SQL Server.  In short, some of these issues are pure murder on your database, DBA, developer and team in general.  We will work through many of these things and show some methods to achieve a higher state of database Zen.</p>
<h3 style="text-align: left;">Description</h3>
<p>Join Microsoft Certified Masters, Wayne Sheffield and Jason Brimhall, as they examine numerous crazy implementations they have seen over the years, and how these implementations can be murder on SQL Server.  No topic is off limits as they cover the effects of these crazy implementations from performance to security, and how the &#8220;Default Blame Acceptors&#8221; (DBAs) can use alternatives to keep the developers, DBAs, bosses and even the end-users happy.</p>
<p>Presented by:</p>
<p><strong><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg"><img loading="lazy" class="wp-image-2183 alignleft" alt="wayne" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg" width="141" height="211" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/11/wayne-682x1024.jpg 682w, https://jasonbrimhall.info/wp-content/uploads/2013/11/wayne.jpg 1066w" sizes="(max-width: 141px) 85vw, 141px" /></a>Wayne Sheffield,</strong> a Microsoft Certified Master in SQL Server, started working with xBase databases in the late 80&#8217;s. With over 20 years in IT, he has worked with SQL Server (since 6.5 in the late 90&#8217;s) in various dev/admin roles, with an emphasis in performance tuning. He is the author of several articles at<a href="http://www.sqlservercentral.com/" target="_blank">www.sqlservercentral.com</a>, a co-author of SQL Server 2012 T-SQL Recipes, and enjoys sharing his knowledge by presenting at SQL PASS events and blogging at <a href="http://blog.waynesheffield.com/wayne" target="_blank">http://blog.waynesheffield.com/wayne</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="wp-image-2182 alignleft" alt="JasonBrimhall" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg" width="141" height="211" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-682x1024.jpg 682w, https://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall-200x300.jpg 200w, https://jasonbrimhall.info/wp-content/uploads/2013/11/JasonBrimhall.jpg 1526w" sizes="(max-width: 141px) 85vw, 141px" /></p>
<p><strong>Jason Brimhall</strong> has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments.  Jason also has 18 years experience in IT working with the hardware, OS, network and even the plunger (ask him sometime about that). He is currently a Consultant and a Microsoft Certified Master(MCM). Jason is the VP of the Las Vegas User Group (SSSOLV).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Course Objectives</h3>
<ol>
<li>Recognize practices that are performance pitfalls</li>
<li>Learn how to Remedy the performance pitfalls</li>
<li>Recognize practices that are security pitfalls</li>
<li>Learn how to Remedy the security pitfalls</li>
<li>Demos Demos Demos &#8211; scripts to demonstrate pitfalls and their remedies will be provided</li>
<li>Have fun and discuss</li>
<li>We might blow up a database</li>
</ol>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png"><img loading="lazy" class="aligncenter size-full wp-image-2184" alt="kaboom" src="http://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png" width="301" height="167" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom.png 301w, https://jasonbrimhall.info/wp-content/uploads/2013/11/kaboom-300x166.png 300w" sizes="(max-width: 301px) 85vw, 301px" /></a></p>
<p>&nbsp;</p>
<p>There will be a nice mix of real world examples and some painfully contrived examples. All will have a good and useful point.</p>
<p>If you will be in the area, and you are looking for high quality content with a good mix of enjoyment, come and join us by registering at this <a href="https://www.sqlsaturday.com/233/eventhome.aspx">eventbrite site event site is removed)</a>.  There are only 30 seats available for this murder mystery theater.  Reserve yours now.</p>
<p>Between now and <strong>November 8th</strong>, the registration is discounted to <strong>$99</strong> (plus transaction fees).  Use this code for the discount: <strong>SQLSATDC.</strong></p>
<h3>Shameless plug time</h3>
<p>I present regularly at SQL Saturdays.  Wayne also presents regularly at SQL Saturdays.  If you are organizing an event and would like to fill some pre-con sessions, please contact either Wayne, myself or both of us for this session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2179" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/11/05/murder-they-wrote/">Murder They Wrote</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/11/05/murder-they-wrote/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Scaring a Database Near you</title>
		<link>https://jasonbrimhall.info/2013/10/31/scaring-a-database-near-you/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scaring-a-database-near-you</link>
					<comments>https://jasonbrimhall.info/2013/10/31/scaring-a-database-near-you/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 31 Oct 2013 17:52:03 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2171</guid>

					<description><![CDATA[<p>Something I have a hard time by-passing is a good R2 unit.  I have R2 units in so many different forms, including a standing R2 cake one year for my birthday.  So when I cam [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/10/31/scaring-a-database-near-you/">Scaring a Database Near you</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="wp-image-2172 alignleft" alt="r2" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/r2.png" width="283" height="382" /></p>
<p>Something I have a hard time by-passing is a good R2 unit.  I have R2 units in so many different forms, including a standing R2 cake one year for my birthday.  So when I cam across this R2 unit, I just had to share it.</p>
<p>That is a pumpkin carved into the resemblance of R2-D2.  I think it is a mighty fine job too.  It&#8217;s amazing how many good Star Wars related pumpkin carvings there are out there.  You probably wouldn&#8217;t have too difficult a time finding three or four hundred if you tried a little google-fu.</p>
<p>Each year I try to have something for the Halloween Holiday such as this <a href="http://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/">one </a>or this <a href="http://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/">one</a>.  I failed to provide something in 2012, and this is getting back on the right track.</p>
<p>Despite the ease to find haunting Halloween effects related to SQL Server, I am amazed at how few have even heard of &#8220;Halloween Protection&#8221; which stems from the &#8220;Halloween Problem.&#8221;</p>
<p>I am not going to dive into the problem or the protection of it.  I think that has been covered plenty and even quite masterfully by Paul White (<a href="http://sqlblog.com/blogs/paul_white/default.aspx" class="broken_link">blog </a>| <a href="http://twitter.com/SQL_Kiwi">twitter</a>).  I recommend that you read his four part series on the topic starting <a href="http://www.sqlperformance.com/2013/02/t-sql-queries/halloween-problem-part-1">here</a>.</p>
<p>With all of the COSPLAY going about here in the States, I find some of the scarier things to be about either stuff I have previously fixed or about which I have written or tweeted or all of the above.</p>
<p>Take for instance this <a href="http://jasonbrimhall.info/2011/12/20/public-role-and-security/">article </a>about the blatant disregard by some vendors and clients in regards to security.  I still can&#8217;t figure out why the public role would ever need to be dbo for a database &#8211; at least not a legitimate reason.</p>
<p>Or we can take on the recent time I tweeted about a cursor that I fixed.  I took that scary cursor down from a 30+ hour run time to a mere 50 seconds.  Here is a segment of the execution plan (plan is roughly 4mb in size to give a little scale) zoomed out to 1/5th.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/optimized_segment.png"><img loading="lazy" class="aligncenter  wp-image-2173" alt="optimized_segment" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/optimized_segment.png" width="522" height="702" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/10/optimized_segment.png 653w, https://jasonbrimhall.info/wp-content/uploads/2013/10/optimized_segment-223x300.png 223w" sizes="(max-width: 522px) 85vw, 522px" /></a></p>
<p>&nbsp;</p>
<p>The query was much uglier than that originally.  Imagine that beast looping through on your server for 30 hrs, and that is not even the entire thing.  It is little wonder why things started to drag on the server.</p>
<p>Another scary item I like is the effect of implicit conversions.  That is a topic that can be viewed pretty easily through the use of google-fu.  Here is a short demo on the implications of implicit conversions.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #T1 (SomeInt INT, SomeReal REAL)
CREATE CLUSTERED INDEX T1_SomeReal ON #T1(SomeReal)

CREATE TABLE #T2 (SomeInt INT, SomeReal REAL)
CREATE CLUSTERED INDEX T2_SomeInt ON #T2(SomeInt)

CREATE TABLE #T3 (SomeInt Int, SomeReal NVarchar(Max))
--name mismatch and datatype are intentional
CREATE CLUSTERED INDEX T3_SomeInt ON #T3(SomeInt)
GO

SET NOCOUNT ON
DECLARE @I INT
SET @I = 0
WHILE @I &amp;lt; 10000
  BEGIN
    INSERT #T1 VALUES (@I, @I)
    INSERT #T2 VALUES (@I, @I)
    INSERT #T3 VALUES (@I, @I)
    SET @I = @I + 1
  END

SET STATISTICS TIME ON

/* Query 1 
No implicit Conversion */
SELECT COUNT(*)
FROM #T1 T1 INNER LOOP JOIN #T2 T2 ON T1.SomeInt = T2.SomeInt
OPTION(MAXDOP 1);
GO

/* Query 2 
Pretty bad implicit Conversion */
SELECT COUNT(*)
FROM #T1 T1 INNER LOOP JOIN #T3 T3 ON T1.SomeInt = T3.SomeReal
OPTION(MAXDOP 1);
GO
SET STATISTICS TIME OFF</pre><p>[/codesyntax]</p>
<p>In this demo I have created three temp tables.  Each is pretty simple in nature and each is to receive 10,000 records.  The insert statement just inserts an integer into each field of each table through the while loop.  Notice that I intentionally named a column in #T3 to be SomeReal but the datatype is an NVARCHAR.  This is to underscore a pet peeve of mine that I have seen over and over again &#8211; naming the field in the table after the datatype and the datatype doesn&#8217;t even match.</p>
<p>When this query runs, I get the following timing results.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/timing.png"><img loading="lazy" class="aligncenter size-full wp-image-2174" alt="timing" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/timing.png" width="377" height="182" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/10/timing.png 377w, https://jasonbrimhall.info/wp-content/uploads/2013/10/timing-300x144.png 300w" sizes="(max-width: 377px) 85vw, 377px" /></a></p>
<p>&nbsp;</p>
<p>The thing that stands out to me is the huge difference in time between the implicit-free query and the query replete with an implicit conversion.  The implicit conversion query</p>
<p><a style="color: #ff4500; line-height: 15.59375px;" href="http://jasonbrimhall.info/wp-content/uploads/2013/10/grim.png"><img loading="lazy" class="wp-image-2175  alignright" alt="grim" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/grim.png" width="294" height="294" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/10/grim.png 420w, https://jasonbrimhall.info/wp-content/uploads/2013/10/grim-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2013/10/grim-300x300.png 300w" sizes="(max-width: 294px) 85vw, 294px" /></a></p>
<p>was about 930 times slower than the query free of implicit conversions.  Granted that query was against a cold cache, so let&#8217;s see what happens to an average of five runs each against a warm cache.</p>
<p>With a warm cache I see an average of 51ms for the implicit free query.  On the other hand, the implicit conversion query runs at an average of 84525ms.  That equates to about 1644 times slower.</p>
<p>Sure this was a contrived example.  But keep in mind the table sizes, the datatypes and the number of records in each table.  Had this been a more true to life example with larger tables and millions of records, we could be seeing a query that is far more devastating due to the implicit conversions.  Let&#8217;s just call it the grim reaper of your database. (<em>Grim Reaper from www.mysticalpassage.com/grim_reaper.html</em>)</p>
<p>With these horrifying things to haunt your database, I leave you with this new hope as you battle the dark side and grim that is in your database.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/swbattle.png"><img loading="lazy" class="wp-image-2176 alignleft" alt="swbattle" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/swbattle.png" width="480" height="362" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/10/swbattle.png 600w, https://jasonbrimhall.info/wp-content/uploads/2013/10/swbattle-300x226.png 300w" sizes="(max-width: 480px) 85vw, 480px" /></a></p>
<p style="text-align: center;">
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2171" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/10/31/scaring-a-database-near-you/">Scaring a Database Near you</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/10/31/scaring-a-database-near-you/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Carolina Whistle Stops</title>
		<link>https://jasonbrimhall.info/2013/10/10/carolina-whistle-stops/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=carolina-whistle-stops</link>
					<comments>https://jasonbrimhall.info/2013/10/10/carolina-whistle-stops/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 11 Oct 2013 04:12:55 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[PASS SUMMIT]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2151</guid>

					<description><![CDATA[<p>The SQL Crazy train continues chugging along this month.  The next two whistle stops are back to back in the Carolinas. The first stop is coming up in just a few short hours.  I will [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/10/10/carolina-whistle-stops/">Carolina Whistle Stops</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>The <a href="http://jasonbrimhall.info/2013/09/13/join-the-sql-crazy-train/">SQL Crazy train</a> continues chugging along this month.  The next two whistle stops are back to back in the Carolinas.</p>
<p>The first stop is coming up in just a few short hours.  I will be stopping in for <a href="http://sqlsaturday.com/227/eventhome.aspx">SQL Saturday in Charleston South Carolina</a>.  I have been selected to present on the topic of Compression.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/sqlsat227_web.png"><img loading="lazy" class="aligncenter size-full wp-image-2152" alt="sqlsat227_web" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/sqlsat227_web.png" width="236" height="115" /></a></p>
<p>&nbsp;</p>
<p>The <a href="http://sqlsaturday.com/227/schedule.aspx">lineup </a>is pretty rock solid for this event.  And nothing like extending a bit of training to encompass the SQL Saturday events if it just so happens you had intended to be in town for the next whistle stop &#8211; Summit 13.  I&#8217;ll talk about that in a bit.</p>
<p>There are a lot of speakers for this single day event that I would really like to see.  Looking at the schedule, I don&#8217;t know how I am going to pick which session to attend.  Every single time slot has at least two sessions that I would like to attend.  There are <em>only</em> 3 tracks!  At least this will give me practice in selecting which sessions to attend for Summit.</p>
<p>The next whistle stop is in Charlotte North Carolina.  Charlotte is the home of <a href="http://www.sqlpass.org/summit/2013/Home.aspx">PASS Summit 2013</a>.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/logo_header.png"><img loading="lazy" class="aligncenter size-full wp-image-2153" alt="logo_header" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/logo_header.png" width="252" height="73" /></a></p>
<p>&nbsp;</p>
<p>Even better is that this year, the summit really does have a train &#8211; of sorts.</p>
<p><img loading="lazy" class="alignnone" alt="" src="http://lh5.ggpht.com/-dJUWorMnUpk/Uio1gsYYuGI/AAAAAAAAA5A/Qc5asjzol1k/trolley_thumb%25255B14%25255D.png?imgmax=800" width="483" height="375" /></p>
<p>(Image is a link to the actual source at SQL Sentry &#8211; the sponsors of the trolley.)</p>
<p>SQL Sentry has been kind enough to sponsor the SQL Sentry Shuttle to help Summit attendees get around and see some of Charlotte while in town.  You can read all about it <a href="http://greg.blogs.sqlsentry.net/2013/09/pass-summiteers-guide-to-charlotte-part.html">here</a>.</p>
<p>Yeah &#8211; I will be boarding that train/trolley.</p>
<p>I have a busy schedule coming up at Summit 2013.  But, I am looking forward to meeting people and talking about whatever may come up.</p>
<p>Will you be at any of these whistle stops?  If see, say Hi.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2151" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/10/10/carolina-whistle-stops/">Carolina Whistle Stops</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/10/10/carolina-whistle-stops/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Coast to Coast with SQL Saturday</title>
		<link>https://jasonbrimhall.info/2013/10/10/coast-to-coast-with-sql-saturday/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=coast-to-coast-with-sql-saturday</link>
					<comments>https://jasonbrimhall.info/2013/10/10/coast-to-coast-with-sql-saturday/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 10 Oct 2013 19:56:05 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2148</guid>

					<description><![CDATA[<p>Last month I blogged about the SQL Crazy train making a whistle stop in Providence Rhode Island.  A couple of weeks prior to that, you may have read this article about the Salt Lake City [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/10/10/coast-to-coast-with-sql-saturday/">Coast to Coast with SQL Saturday</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Last month I blogged about the <a href="http://jasonbrimhall.info/2013/09/13/join-the-sql-crazy-train/">SQL Crazy train making a whistle stop in Providence Rhode Island</a>.  A couple of weeks prior to that, you may have read <a href="http://jasonbrimhall.info/2013/09/05/sqlsaturday-salt-lake-city-246/">this article about the Salt Lake City event</a>.</p>
<p>What you have not seen is a recap of either of those two events.  I just want to give a quick bit of feedback on both events at this time.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/09/sqlsat246.png"><img loading="lazy" class="aligncenter size-full wp-image-2121" alt="sqlsat246" src="http://jasonbrimhall.info/wp-content/uploads/2013/09/sqlsat246.png" width="236" height="115" /></a></p>
<p>&nbsp;</p>
<p>The <a href="http://sqlsaturday.com/246/eventhome.aspx">SLC </a>event was held at the Adobe building down south in Utah county &#8211; just outside of Salt Lake City.  We&#8217;ll let it slide that it wasn&#8217;t even in the same county as the event name.</p>
<p>Overall, the event was good.  A lot of people attended.  The food was good (catered BBQ and Pizza as reserve in case there wasn&#8217;t enough BBQ).  The speakers were good, the facilities were mostly good, and the topics presented were good.</p>
<p>Above all of the good of the event comes the great stuff.  I particularly enjoyed the opportunity I had to chat with people like Kevin Boles and Argenis Fernandez.  I also had the great time to mingle with people like Andre Dubois, Keith Tate, Aaron Cutshall, Jason Kassay and Reeves Smith.</p>
<p>I had met each of these people at one event or another and I had time to chat with them all over again.  It is always nice to reconnect with other community volunteers.</p>
<p>If you ever have the chance to attend the session about SysInternals Tools by Argenis, then DO IT!  I particularly enjoyed that session.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/09/logo.png"><img loading="lazy" class="aligncenter size-full wp-image-2136" alt="logo" src="http://jasonbrimhall.info/wp-content/uploads/2013/09/logo.png" width="236" height="115" /></a></p>
<p>&nbsp;</p>
<p>Much like SQL Saturday in Salt Lake City, I enjoyed the <a href="http://sqlsaturday.com/213/eventhome.aspx">Providence </a>event.  I found myself bailing on some of the sessions more in Providence than in SLC so I could tech talk.</p>
<p>I really enjoyed pulling off to a quiet corner to answer tech questions and to try and help resolve problems.  The questions were in part about my presentations, and in part had nothing to do with anything that I presented.</p>
<p>One thing that I thought worked rather well was the scheduling of my second session.  The session preceding mine was about a framework for SSIS.  My session was essentially about a framework for SSRS.</p>
<p>I left both of my sessions feeling that both audiences during my sessions were engaged.  When I present, I monitor the group to try and determine if they are engaged and it seemed like the attendees were there and wanting more.</p>
<p>After the event, the speakers and volunteers gathered for a social evening at a local restaurant.  I thought that the concept worked out really well.  I have to admit that I was a bit skeptical at first with the layout.  I am happy to admit that the skepticism was squashed promptly.  The chance to meet with the volunteers and other speakers in a more informal gathering was ideal.  I enjoyed it even more than a formal dinner &#8211; in this particular occasion.  It is this kind of informal get together for speakers and volunteers to mix and socialize that I would be interested in seeing more frequently at SQL Saturdays.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2148" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/10/10/coast-to-coast-with-sql-saturday/">Coast to Coast with SQL Saturday</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/10/10/coast-to-coast-with-sql-saturday/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #47: SWAG SWAG SWAG</title>
		<link>https://jasonbrimhall.info/2013/10/07/t-sql-tuesday-47-swag-swag-swag/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-47-swag-swag-swag</link>
					<comments>https://jasonbrimhall.info/2013/10/07/t-sql-tuesday-47-swag-swag-swag/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Oct 2013 00:30:09 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2144</guid>

					<description><![CDATA[<p>This month we probably have the easiest topic I have ever seen for a TSQL Tuesday blog party.  That isn&#8217;t a slight, but rather is something of a good thing. This is a very hectic [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/10/07/t-sql-tuesday-47-swag-swag-swag/">T-SQL Tuesday #47: SWAG SWAG SWAG</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="line-height: 1.3em;" href="http://www.kendalvandyke.com/2013/10/t-sql-tuesday-47-your-best-sql-server.html"><img loading="lazy" class="size-full wp-image-1969 alignleft" alt="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" width="150" height="150" /></a>This month we probably have the easiest topic I have ever seen for a TSQL Tuesday blog party.  That isn&#8217;t a slight, but rather is something of a good thing.</p>
<p>This is a very hectic time of year in the SQL Community.  Add the usual stresses of work, family and life &#8211; few people have a lot of free time.</p>
<p>It just so happens, that to start this month, I am trying once again to get back on the ball and blog more consistently.</p>
<p>Kendall Van Dyke (<a href="http://www.kendalvandyke.com/">blog </a>| <a href="http://twitter.com/SQLDBA">twitter</a>) has accepted the challenge of hosting the blog party this month.  You can read his invitation <a href="http://www.kendalvandyke.com/2013/10/t-sql-tuesday-47-your-best-sql-server.html">here</a>.</p>
<p>The topic chosen is all about the SWAG.  This particular SWAG is the kind of freebies you might get from various SQL Activities.  This is not the SWAG that is associated with a Guess.</p>
<p>There are a lot of SWAG items that I have liked over the years.  I have received Bucky Balls, stuffed animals (from Horton), stuffed Cats (from SQLCat), usb drives, and even a Lava Lamp or two. The interesting thing about some of these things is that SQLCAT has been rebranded  (so probably no more plush SQL Cats) and Bucky Balls is <a href="http://gizmodo.com/5929064/buckyballs-have-been-banned-by-the-feds">extinct due to a ban on sales by the CPSC</a>.</p>
<p>I am not surprised by the extinction of Bucky Balls.  That was one of the best geek SWAG items I ever got.  But I had to lock mine up (and not just in my office) due to a certain child decided to find them (in my office) and swallow a few.  It just so happens to be the same child that sneezed an <a href="http://jasonbrimhall.info/2011/11/21/sql-family-an-update/">almond into her nose</a>.  And yes, we did successfully retrieve all of the Bucky Balls (four swallowed).</p>
<p>But none of that SWAG compares to the <a href="http://www.apple.com/ipad/">IPAD </a>that I won.  Of course, the children would say that it is their IPAD.  At this point it serves a great purpose in trying to keep the children somewhat calm.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/10/ipad.png"><img loading="lazy" class="aligncenter size-full wp-image-2145" alt="ipad" src="http://jasonbrimhall.info/wp-content/uploads/2013/10/ipad.png" width="536" height="353" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/10/ipad.png 536w, https://jasonbrimhall.info/wp-content/uploads/2013/10/ipad-300x197.png 300w" sizes="(max-width: 536px) 85vw, 536px" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2144" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/10/07/t-sql-tuesday-47-swag-swag-swag/">T-SQL Tuesday #47: SWAG SWAG SWAG</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/10/07/t-sql-tuesday-47-swag-swag-swag/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MCM on Life Support</title>
		<link>https://jasonbrimhall.info/2013/09/11/mcm-on-life-support/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mcm-on-life-support</link>
					<comments>https://jasonbrimhall.info/2013/09/11/mcm-on-life-support/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 11 Sep 2013 19:31:27 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[MCM]]></category>
		<category><![CDATA[SQL MCM]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2130</guid>

					<description><![CDATA[<p>Good news everybody.  October 1st is no longer the day that the MCM was prescribed to die.  The Microsoft Certified Master is now on life support until December 31st, 2013.  Which means that the Jan [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/09/11/mcm-on-life-support/">MCM on Life Support</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Good news everybody.  October 1st is no longer the day that the MCM was prescribed to die.  The Microsoft Certified Master is now on life support until December 31st, 2013.  Which means that the Jan 1st (for any interested in New Years resolutions), the Advanced Certifications at Microsoft will have been terminated and any who possess the certification will instantly become myths, legends, and items of folklore.  Ok so that last bit might be a bit of an exaggeration.</p>
<p>Here is a screen grab from the Advanced Certification Site <a href="https://web.archive.org/web/20140517151647/https://fast.omnisocial.mzinga.com/content/ss/eda339aac39b4c42a7f089442bfd62a8/newhomepage/index.html">here</a>.  I added the nice red boxes and underline for emphasis.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/09/MCM_exam_extended.png"><img loading="lazy" class="aligncenter  wp-image-2131" alt="MCM_exam_extended" src="http://jasonbrimhall.info/wp-content/uploads/2013/09/MCM_exam_extended.png" width="717" height="279" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/09/MCM_exam_extended.png 896w, https://jasonbrimhall.info/wp-content/uploads/2013/09/MCM_exam_extended-300x116.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">While this bodes well for those that had committed to training rotations, or who had committed to hours of study and only had the Lab Exam remaining, the program is still being terminated.  Many are still unhappy.  Many have moved on through the <a href="http://ozar.me/2013/09/the-sqlmcm-is-dead-experiments-go-on/">grief cycle</a>.  <a href="http://www.sqlskills.com/blogs/paul/death-of-the-mcm-program/">Polls </a>have been taken, articles (<a href="http://jasonbrimhall.info/2013/09/02/rare-species-extinction-and-the-mcm/">here</a>, <a href="https://web.archive.org/web/20150511122734/http://sqlmag.com/blog/microsofts-retirement-certified-master-program">here</a>, and <a href="http://www.theregister.co.uk/2013/09/02/redmonds_certification_chief_explains_death_of_mcm_and_mca/">here</a>) written and meetings held.  In the end, Microsoft sort of acknowledged that they alienated a huge faction of their supporting community.  Bumping the death date back to December 31st is a sign of that.</p>
<p style="text-align: left;">I am happy that a meeting was held after the community outcry.  It is far better than nothing at all.  I am also happy that the date has been bumped back.  I was not happy with the initial announcement and the manner it was done.  I am not yet satisfied that Microsoft will do anything to promote a Master level with their products.  In fact, as others have <a href="http://www.sqlskills.com/blogs/joe/we-can-handle-the-truth/">said </a>(and I am sure many more have silently supported), I am uncertain I could advocate an advanced certification for Microsoft again.  I am uncertain that I could support an advanced certification for Microsoft from a 3rd party vendor.</p>
<p style="text-align: left;">If there is ever to be an advanced certification for Microsoft SQL Server, I will have to think long and hard about the value and worth of pursuing it.  All of that said, I value learning and I reiterate something that Paul Randal wrote on his <a href="http://www.sqlskills.com/blogs/paul/death-of-the-mcm-program/">survey results</a> post:</p>
<blockquote><p>Although the MCM has been removed as the focus point for learning goals, learning still goes on, and people will still aspire to make themselves better SQL Server professionals.</p>
<p>Don’t give up learning – it’s always worth it.</p></blockquote>
<p style="text-align: left;">If you have passed your Knowledge Exam, I say go for the lab exam.  Test yourself and see if you can tame the beast.  If for nothing else other than to measure yourself and provide a bit of a self-evaluation.  Don&#8217;t hesitate and leave yourself wondering if you could have accomplished that goal.</p>
<p style="text-align: left;">I know one person that has been pondering if he should do it.  He had been planning on attempting the MCM exams next year.  Obviously the change from Microsoft has changed his plans and made him question the value of attempting.  My advice to him was to take the exams, and especially now that the MCM is on Life Support.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/04/MCMrgb_1262.png"><img loading="lazy" class="aligncenter size-full wp-image-2025" alt="MCM_SQL" src="http://jasonbrimhall.info/wp-content/uploads/2013/04/MCMrgb_1262.png" width="246" height="60" /></a></p>
<p style="text-align: left;">
<p style="text-align: left;">It is far better to attempt the exams (for those that are still on the fence), than it is to live in regret and doubt.  Worst case, you fail the exam and have a fair amount of introspect that will happen because of it.  Best case is you will pass the exams, be an MCM for life, and still have a fair amount of introspect that will happen because of it.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2130" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/09/11/mcm-on-life-support/">MCM on Life Support</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/09/11/mcm-on-life-support/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #45 Follow the Yellow Brick Road</title>
		<link>https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-45-follow-the-yellow-brick-road</link>
					<comments>https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 13 Aug 2013 00:15:37 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2077</guid>

					<description><![CDATA[<p>We have the distinct pleasure once again to have a party full of SQL enthusiasts.  The best part is that few if any of us are even in the same room or building for this [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/">T-SQL Tuesday #45 Follow the Yellow Brick Road</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://mickeystuewe.com/2013/08/05/t-sql-tuesday-45-invitationfollow-the-yellow-brick-road/"><img loading="lazy" class="size-full wp-image-1969 alignleft" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="TSQL2sDay150x150" width="150" height="150" /></a></p>
<p>We have the distinct pleasure once again to have a party full of SQL enthusiasts.  The best part is that few if any of us are even in the same room or building for this party.</p>
<p>The party is known as TSQL Tuesday and this month is hosted by Mickey Stuewe (<a href="http://mickeystuewe.com/">Blog </a>| <a href="http://twitter.com/SQLMickey">Twitter</a>).  This month Mickey has come up with the notion that for some reason or another you may want to have something audited, tracked, traced or otherwise followed.  To quote Mickey from the invitation (which you can read <a href="http://mickeystuewe.com/2013/08/05/t-sql-tuesday-45-invitationfollow-the-yellow-brick-road/">here</a>): &#8220;So, it is time to follow Dorothy and Toto down the yellow brick road and to share your experience with auditing data.&#8221;</p>
<p>Mickey did provide some viable options for auditing.  And I didn&#8217;t see any restrictions on what the topic of auditing couldn&#8217;t be.  So I have a slightly different spin on the topic than what appeared to be the direction that Mickey was headed with her examples and description in the invite.</p>
<p>That said, I will be discussing a topic along the vein of &#8220;finding out who did something stupid last week.&#8221;  And the TSQL Tuesday topic once again works out well this month for me because I have a back log of blog topics for this subject that I have been meaning to write.  So let&#8217;s get at least one of them knocked out of the way with this entry into the blog party of the month.</p>
<h2 style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/08/Ozcurt.png"><img loading="lazy" class="aligncenter  wp-image-2078" src="http://jasonbrimhall.info/wp-content/uploads/2013/08/Ozcurt.png" alt="Ozcurt" width="556" height="215" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/08/Ozcurt.png 695w, https://jasonbrimhall.info/wp-content/uploads/2013/08/Ozcurt-300x116.png 300w" sizes="(max-width: 556px) 85vw, 556px" /></a>Behold the Great and Powerful Audit</h2>
<p>Have you ever come into work and been blasted first thing with &#8220;everything is slow!&#8221;</p>
<p>Then you start to dig and see your email reports and you begin to wonder why you have 50% of your clustered indexes jacked up to 99% fragmentation?  You know that sort of thing never happens suddenly in your environment because you have your finger on the pulse of all things DB related &#8211; or so you thought.</p>
<p>You check your index defrag log and see that it ran perfectly fine last night and you even see the report on fragmentation from after the defrag process was completed.  You begin to really scratch your head.  You know that you have no process that does any bulk loads or ETL batches after the index defrag process.  Nothing is really making any sense.  Then a lightbulb goes off and you check your report on database sizes.  You see that the database is now several hundred GB smaller and there is no free space left in the data files.  Free space that you had left in the data file intentionally.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/08/300px-Steam_eruption.jpg"><img loading="lazy" class="aligncenter size-full wp-image-2079" src="http://jasonbrimhall.info/wp-content/uploads/2013/08/300px-Steam_eruption.jpg" alt="300px-Steam_eruption" width="300" height="197" /></a>Now you are steamed and about to blow your top like this geyser.  Who has done something so stupid as to mess around with your data files?  We Senior DBA&#8217;s are somewhat territorial with the databases we support and we don&#8217;t like people making changes they haven&#8217;t discussed with us.  So it is perfectly understandable if you are a bit steamed by an event such as this.</p>
<p>The question now is: What are you going to do about it?  How are you going to find who jacked up your data files?</p>
<p>The answer is in the default trace.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
	T.DatabaseName,
	T.TextData,
	T.HostName,
	T.ApplicationName,
	T.LoginName,
	T.StartTime,
    CASE T.IsSystem
		WHEN 1 THEN 'YES'
		ELSE 'NO'
		END AS IsSystem
    /* Check IsSystem to help ensure Autoshrink didn't cause the shrink 
       MSDN indicates 1=system and 0=user
       My testing shows Null = user and 0 did not occur */
FROM sys.fn_trace_gettable(CONVERT(VARCHAR(150), 
	( SELECT TOP 1 f.[value]                                                 
		  FROM    sys.fn_trace_getinfo(NULL) f
		  WHERE   f.property = 2
		)), DEFAULT) T
WHERE T.TextData LIKE '%SHRINKFILE%'
	AND T.EventClass = 116
	/* Event Class 116 occurs when a DBCC command is issued */
	;</pre><p>The optimal solution may not be to have to rely on the default trace to capture an event that occurred in the past, but rather to proactively monitor it through other means (perhaps an extended event for example).  But in the event you need to capture the information because you were caught off-guard, you may be able to trap the information from the default trace.</p>
<p>When I run the above query, I get the following results (yes I intentionally shrunk my msdb  database explicitly for this example).</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/08/results.png"><img loading="lazy" class="aligncenter  wp-image-2080" src="http://jasonbrimhall.info/wp-content/uploads/2013/08/results.png" alt="results" width="610" height="66" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/08/results.png 969w, https://jasonbrimhall.info/wp-content/uploads/2013/08/results-300x32.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p style="text-align: left;">Now when you have a sysadmin or a junior DBA (or that manager with too many permissions) doing things they shouldn&#8217;t be doing, you have some evidence to show them.  You also can go to the person that &#8220;did something really stupid&#8221; and offer them a chance to learn why it might have been a bad thing &#8211; but do it nicely.  You don&#8217;t want to be the one that looks like a jerk.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2077" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/">T-SQL Tuesday #45 Follow the Yellow Brick Road</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/08/12/t-sql-tuesday-45-follow-the-yellow-brick-road/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Lost that Single-User Connection?</title>
		<link>https://jasonbrimhall.info/2013/05/06/lost-that-single-user-connection/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lost-that-single-user-connection</link>
					<comments>https://jasonbrimhall.info/2013/05/06/lost-that-single-user-connection/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 06 May 2013 12:00:44 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=2032</guid>

					<description><![CDATA[<p>You have changed your database to single_user mode to do a task.  As you go about your business, you lose track of which connection was the single_user connection.  You start closing connections and mistakenly close [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/05/06/lost-that-single-user-connection/">Lost that Single-User Connection?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>You have changed your database to single_user mode to do a task.  As you go about your business, you lose track of which connection was the single_user connection.  You start closing connections and mistakenly close the session that was your single_user connection.  Now you are unable to start a new single_user session.  It would seem that somebody or something has taken your connection.</p>
<p>Today, I am going to discuss some things you may do to get around this problem.</p>
<p>The first thing that may come to mind when you encounter this is &#8220;Oh crap!&#8221;  Well, no need to get too terribly worried (not unless you really hosed something up and you are trying to fix it real quick before the boss notices).</p>
<p>The next thing you may think of trying is how to circumvent the single_user mode.  And during that thought process you may be thinking that single_user does not really mean single_user so you might try something like start a DAC session.  Well, let&#8217;s go through that and see what would happen in a DAC session if your single_user session is stolen.</p>
<p>I am going to skip the part of setting a database into single_user mode because we are presuming that the condition already exists.  To start a DAC session, I am going to point you to a previous article I did on the topic &#8211; <a href="http://jasonbrimhall.info/2012/01/19/dedicated-administrator-connection/">here</a>.</p>
<p>To ensure I am using a DAC session, I am going to issue the following query.  This will ensure I am in the right session and that DAC is in use.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT s.group_id,e.name, CAST(g.name as nvarchar(20)) AS ResourceGroup, s.session_id 
		, s.login_time, CAST(s.host_name as nvarchar(20)) AS HostName 
		, CAST(s.program_name AS nvarchar(20)) AS ProgramName 
		,s.original_login_name 
		,s.is_user_process 
		,s.STATUS 
	FROM sys.dm_exec_sessions s 
		INNER JOIN sys.dm_resource_governor_workload_groups g 
			ON g.group_id = s.group_id 
		INNER JOIN sys.dm_exec_connections ec 
			ON s.session_id = ec.session_id 
		LEFT OUTER JOIN sys.endpoints e  
			ON ec.[endpoint_id]=e.[endpoint_id] 
WHERE s.session_id = @@SPID 
ORDER BY g.NAME; 
GO</pre><p>[/codesyntax]</p>
<p>In my case, this results in an endpoint with the name &#8220;Dedicated Admin Connection&#8221; and a spid of 84.  Good, I am in the correct session for the rest of this test.  Next, I will issue a Use database statement.  I have created a test database called ClinicDB.  So I will issue the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">USE ClinicDB;
GO</pre><p>[/codesyntax]</p>
<p>I get the following result.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Msg 924, Level 14, State 1, Line 1
Database 'ClinicDB' is already open and can only have one user at a time.</pre><p>[/codesyntax]</p>
<p>So, that blows that idea right out of the water.  It shouldn&#8217;t really have been a consideration in the first place because single_user really means just that &#8211; single_user.</p>
<h3>Now What?</h3>
<p>Well, what do you think we could do now to circumvent this little problem and get that single_user session back?</p>
<p>That requires a little investigative work.  It is time to find out who has taken the single_user session and politely ask them to give it up.  To make that task a little easier, we could modify the previous query to find out who has that single_user session (thus limiting how many people we have to ask).  I have modified the following query to use sys.sysprocesses so I could limit the results to the ClinicDB.  This is a limitation of SQL 2008 R2 and older versions.  Getting the database reliably means using sysprocesses.  Despite the database_id being available in other related DMVs, it&#8217;s just not that easy.  One would think you could use sys.dm_exec_requests.  But if a request is not active, an entry won&#8217;t exist for that session.  This problem is fixed in SQL 2012 since the sys.dm_exec_connections DMV now has the database_id field.  Enough of that birdwalk and on to the query.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT s.group_id,e.name, CAST(g.name as nvarchar(20)) AS ResourceGroup, s.session_id ,DB_NAME(r.dbid) AS DBName
		, s.login_time, CAST(s.host_name as nvarchar(20)) AS HostName
		, CAST(s.program_name AS nvarchar(20)) AS ProgramName 
		,s.original_login_name 
		,s.is_user_process 
		,s.STATUS 
	FROM sys.dm_exec_sessions s 
		INNER JOIN sys.dm_resource_governor_workload_groups g 
			ON g.group_id = s.group_id 
		INNER JOIN sys.dm_exec_connections ec 
			ON s.session_id = ec.session_id 
		INNER JOIN sys.sysprocesses r
			ON r.spid = s.session_id
		LEFT OUTER JOIN sys.endpoints e  
			ON ec.[endpoint_id]=e.[endpoint_id]
	WHERE DB_NAME(r.dbid) = 'ClinicDB'
ORDER BY g.NAME; 
GO</pre><p>[/codesyntax]</p>
<p>I chose not to do an entirely new query to simply demonstrate that it was possible with a very small tweak to what has been already used.</p>
<p>Now that you know (in my case I can see that I have a session open with ID = 80 that is connected to that single_user database), I can walk over to the person (knowing his/her login id and computer name) and politely ask them to disconnect.</p>
<p>In the end, this is really an easy thing to resolve.  Sure it may take some people skills &#8211; but that doesn&#8217;t make the task too terribly difficult.  Next time this happens to you, just remember you can run a quick query to find who has sniped that single_user session.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=2032" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/05/06/lost-that-single-user-connection/">Lost that Single-User Connection?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/05/06/lost-that-single-user-connection/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MCM Road Less Traveled</title>
		<link>https://jasonbrimhall.info/2013/04/16/mcm-road-less-traveled/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mcm-road-less-traveled</link>
					<comments>https://jasonbrimhall.info/2013/04/16/mcm-road-less-traveled/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 16 Apr 2013 12:00:26 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[SQL MCM]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1748</guid>

					<description><![CDATA[<p>I began this post back in October of 2012 after learning that I had passed the SQL Server 2008 MCM Knowledge exam.  I had set it aside in hopes of polishing it off after my [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/04/16/mcm-road-less-traveled/">MCM Road Less Traveled</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I began this post back in October of 2012 after learning that I had passed the SQL Server 2008 MCM Knowledge exam.  I had set it aside in hopes of polishing it off after my first lab attempt at Summit 2012.  Notice I said first attempt?  I failed that first attempt.  This is a bit of a story about the journey through the exams and the results.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/04/longuphillbw.png"><img loading="lazy" class="aligncenter  wp-image-2026" alt="longuphillbw" src="http://jasonbrimhall.info/wp-content/uploads/2013/04/longuphillbw.png" width="540" height="545" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/04/longuphillbw.png 600w, https://jasonbrimhall.info/wp-content/uploads/2013/04/longuphillbw-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2013/04/longuphillbw-297x300.png 297w" sizes="(max-width: 540px) 85vw, 540px" /></a></p>
<p>The first attempt was a little crushing.  A mix of emotions concerning the lab came over me because I felt I knew the technology.  While the results were not desirable &#8211; the end effect was desirable and I am glad I did not succeed on that first attempt.</p>
<p>When I took the knowledge exam, I took my time going through the questions and examined the questions.  I think that was a good method for that exam &#8211; I was trying to ensure I understood the question and didn&#8217;t miss anything that was stated.  Though I took it slowly, that is not an indictment to difficulty for the exam.  I was well prepared and did not want to make any invalid assumptions.</p>
<p>Fast forward a little bit to the first attempt at the lab exam.  I had a plan going into the exam.  I felt confident in my skills.  I felt relaxed with the technology.  Then the exam started and my plan went out the window.  I started making assumptions about the exam that I really should not have done.  I rushed a few scenarios that I should not have rushed because I could have done them better.  In the end, I was my own worst enemy during the exam.  This is not a characteristic of an MCM.  Even when the pressure is on, doing what you know and being methodical is a wonderful asset.</p>
<p>Having failed the first time, I wondered if I was ready to be an MCM.  In retrospect, I was not.  Leading up to the exam, I did feel that I was ready for the exam.  I had read several articles such as the following to try and figure out if I was ready.  In the end, it&#8217;s more of a gut check and a leap of faith for some.</p>
<p>Gavin Payne <a href="https://web.archive.org/web/20160318134318/http://gavinpayneuk.com/2012/05/01/knowing-when-youre-ready-to-attempt-to-become-an-mcm-of-sql-server/">http://gavinpayneuk.com/2012/05/01/knowing-when-youre-ready-to-attempt-to-become-an-mcm-of-sql-server/</a></p>
<p>Joe Sack <a href="http://blogs.msdn.com/b/joesack/archive/2010/11/21/how-do-you-know-if-you-re-ready-for-sql-mcm.aspx">http://blogs.msdn.com/b/joesack/archive/2010/11/21/how-do-you-know-if-you-re-ready-for-sql-mcm.aspx</a></p>
<p>I even perused some of the resource type of articles such as the following.</p>
<p>Nick Haslam <a href="https://blog.nhaslam.com/2011/11/19/mcmprep-88-970-sql-mcm-knowledge-exam-sqlmcm/" class="broken_link">http://nhaslam.com/blog/2011/11/19/mcmprep-88-970-sql-mcm-knowledge-exam-sqlmcm/</a></p>
<p>MCM Blog <a href="http://blogs.technet.com/b/themasterblog/archive/tags/sql+server+mcm/">http://blogs.technet.com/b/themasterblog/archive/tags/sql+server+mcm/</a></p>
<p>Robert Davis Amazon MCM Reading List <a href="https://web.archive.org/web/20131228104319/http://www.amazon.com/Official-Server-Certified-Master-Readiness/lm/R3RB13PQ7D8TKB">http://www.amazon.com/Official-Server-Certified-Master-Readiness/lm/R3RB13PQ7D8TKB</a></p>
<p>Brent Ozar MCM Articles <a href="http://www.brentozar.com/sql-mcm/">http://www.brentozar.com/sql-mcm/</a></p>
<p>In the end, this post by Rob Farley sums it up nicely for me (<a href="http://sqlblog.com/blogs/rob_farley/archive/2012/12/23/the-mcm-lab-exam-two-days-later.aspx" class="broken_link">http://sqlblog.com/blogs/rob_farley/archive/2012/12/23/the-mcm-lab-exam-two-days-later.aspx</a>).  Rob references an article by Tom LaRock and some of what Tom did and didn&#8217;t do.  As well as some theory on how to approach the exam at certain stages.  Of all those things, I think the best advice I read as well as I could recommend is to get a study buddy.</p>
<p>It&#8217;s not sooo much to have somebody to bounce ideas off of, as it is to have somebody to try and teach.  I worked with Wayne Sheffield as we prepped for our retakes.  The biggest benefit was, as I said, in that I could pick a topic and try to teach Wayne.  He did the same to me.  And then, we could question each other on what-if type questions about our selected topics.  Another benefit is to have a heat-check so to speak.  Having a study buddy can help you from straying too far off into tangents or maybe keeping you from wasting too much time on a topic they might feel you understand exceptionally well.</p>
<p>If you are reading this far, you probably have figured that I have taken the Lab a second time.  I was debating whether to do it this soon due to life and family.  My wife continued to push me to do it (much as Nic Cain experienced here &#8211; <a href="https://sirsql.net/2012/03/26/2012326achievement-unlockedmcm-sql-server-2008-html/">http://sirsql.net/blog/2012/3/26/achievement-unlockedmcm-sql-server-2008.html</a>).  Without Krista pushing me, I might have delayed even longer.  It was also helpful to have a co-worker and friend pushing me along too (I&#8217;m a little competitive).  Thanks again Wayne!  You can read his experiences <a href="http://blog.waynesheffield.com/wayne/archive/2013/04/the-bucket-list-item-1-is-finally-finished">here</a>.</p>
<p>I received my notification email while driving home from Vegas last week.  Seeing that email pop up from boB Taylor gets your heart racing a little bit &#8211; especially after you have failed the lab previously.  I glanced at the email and only need to go to the first word &#8211; &#8220;CONGRATULATIONS!&#8221;</p>
<p><a style="color: #ff4500; line-height: 15.59375px;" href="http://jasonbrimhall.info/wp-content/uploads/2013/04/MCMrgb_1262.png"><img loading="lazy" class="size-full wp-image-2025 alignleft" alt="MCM_SQL" src="http://jasonbrimhall.info/wp-content/uploads/2013/04/MCMrgb_1262.png" width="246" height="60" /></a></p>
<p>Oh yeah!  Vindication, satisfaction, elation, joy and general happiness set in quickly.  Memories of that old &#8220;<a href="http://www.youtube.com/watch?v=P2AZH4FeGsc">Wide World of Sports</a>&#8221; show from a long time ago spilled in with the words &#8220;Agony of Defeat, Thrill of Victory.&#8221;</p>
<p>I am glad I took the time to pursue this certification.  This adventure has helped me to learn and grow as a DBA.  I am also grateful to those that helped or pushed in some way or another &#8211; whether they knew it or not at the time.  Last but not least, I am thankful for my employer Ntirety.  They understood the importance of this for me and were very supportive in this endeavor.</p>
<p>As one final take away, I was recently shown this <a href="http://blogs.prodata.ie/post/So-you-think-youre-a-SQL-MCM-Part-IVe28093-waits-and-Extended-Events.aspx">link</a> with some interesting questions to help you decide if you feel you are ready to take the exams.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1748" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/04/16/mcm-road-less-traveled/">MCM Road Less Traveled</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/04/16/mcm-road-less-traveled/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Is your LOG backed up?</title>
		<link>https://jasonbrimhall.info/2013/02/11/is-your-log-backed-up/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=is-your-log-backed-up</link>
					<comments>https://jasonbrimhall.info/2013/02/11/is-your-log-backed-up/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 11 Feb 2013 08:58:20 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Backup]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1992</guid>

					<description><![CDATA[<p>You have been doing a fantastic job of late.  You have all of your databases being backed up on a regular schedule.  Now you get an alert that your transaction log just keeps growing.  Why [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/02/11/is-your-log-backed-up/">Is your LOG backed up?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>You have been doing a fantastic job of late.  You have all of your databases being backed up on a regular schedule.  Now you get an alert that your transaction log just keeps growing.  Why is that?</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2013/02/MissingDB_Link.png"><img loading="lazy" class="aligncenter  wp-image-1994" title="MissingDB_Link" src="http://jasonbrimhall.info/wp-content/uploads/2013/02/MissingDB_Link.png" alt="" width="553" height="280" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/02/MissingDB_Link.png 767w, https://jasonbrimhall.info/wp-content/uploads/2013/02/MissingDB_Link-300x152.png 300w" sizes="(max-width: 553px) 85vw, 553px" /></a>You decide to do a little investigation and find that you have your recovery model set to full and you are performing full backups.  That should cover it right?  No, that is not right!</p>
<p>What is this?  Now you have to do something more?  Yes, that is correct.  Performing full backups is not always enough to recover your critical data.  You need to know the recovery requirements for the database / server in question.  But since you have the recovery model set to full, let&#8217;s just talk about what else you should be doing.</p>
<p>The first step should be to run a quick script to determine what databases you have in full recovery and which of those databases do not have a LOG backup.  You see, when a database is in full recovery, you should also backup your transaction log on a regular schedule too.  That schedule is to be determined as a part of the second step (and I will only talk about the first two and only briefly about the second step).</p>
<p>In that first step, you can query your msdb database to help generate a report of which databases have had a transaction log backup.  That should be easy enough to do.  Despite the ease, it should not lessen the importance by any degree.  Here is the script that I wrote recently to help determine which databases were in need of a log backup.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT T1.Name AS DatabaseName
		,ISNULL(t2.database_name, 'No Backup Taken') AS LogBackupAvail
		,T1.recovery_model_desc
		,'Log' AS BackupType 
		,ISNULL(CONVERT(VARCHAR(23), CONVERT(DATETIME, Max(T2.backup_finish_date), 131))
				, CASE WHEN T1.recovery_model_desc = 'Simple'
						THEN 'N/A'
						ELSE 'Backup Not Taken'
						END
		) AS LastBackUpTaken
	FROM sys.databases T1
		LEFT OUTER JOIN msdb.dbo.backupset T2
			ON t1.name = t2.database_name
			AND t2.type = 'L'
	GROUP BY T1.Name,T2.database_name,T1.recovery_model_desc</pre><p>[/codesyntax]</p>
<p>You will likely notice that I am querying both sys.databases out of the master database as well as dbo.backupset out of msdb.  Look more closely and you will see the employ of a Left Outer Join with two conditions on the Join.  In this case, both conditions are required to produce the Outer Join effect that I was seeking.  Had I used a script like the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT T1.Name AS DatabaseName
		,ISNULL(t2.database_name, 'No Backup Taken') AS LogBackupAvail
		,T1.recovery_model_desc
		,'Log' AS BackupType 
		,ISNULL(CONVERT(VARCHAR(23), CONVERT(DATETIME, Max(T2.backup_finish_date), 131))
				, CASE WHEN T1.recovery_model_desc = 'Simple'
						THEN 'N/A'
						ELSE 'Backup Not Taken'
						END
		) AS LastBackUpTaken
	FROM sys.databases T1
		LEFT OUTER JOIN msdb.dbo.backupset T2
			ON t1.name = t2.database_name
		WHERE t2.type = 'L'
	GROUP BY T1.Name,T2.database_name,T1.recovery_model_desc</pre><p>[/codesyntax]</p>
<p>You would see a considerably different result set.  The reason for this different result set is tied to the predicate used and the Join conditions.  And when one examines the execution plan, the difference becomes a little more evident.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/02/ExecPlan.png"><img loading="lazy" class="aligncenter size-full wp-image-1993" title="ExecPlan" src="http://jasonbrimhall.info/wp-content/uploads/2013/02/ExecPlan.png" alt="" width="535" height="171" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/02/ExecPlan.png 535w, https://jasonbrimhall.info/wp-content/uploads/2013/02/ExecPlan-300x95.png 300w" sizes="(max-width: 535px) 85vw, 535px" /></a></p>
<p>That <em>WHERE</em> predicate converted our Left Outer Join to an Inner Join.  Now, if I had only wanted to return results for databases that had log backups, that might be fine.  I want to report on all databases and find not only the last log backup for a database, but I also want to find if a log backup is missing.  Therefore, I need to ensure that both conditions are declared as part of my Left Outer Join.</p>
<p>Running a query such as this will now provide us with some knowledge as to the database recovery models as well as which databases have had a log backup, have not had a log backup, and which do not need a log backup (based on recovery model).</p>
<p>Armed with this information, it is imperative to do a bit more digging now.  Knowing what the business deems as an acceptable data loss is important.  Find that out and then create transaction log backups accordingly so the business can recover appropriately in the event of a disaster.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1992" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/02/11/is-your-log-backed-up/">Is your LOG backed up?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/02/11/is-your-log-backed-up/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Audit Configuration Changes</title>
		<link>https://jasonbrimhall.info/2013/01/24/audit-configuration-changes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=audit-configuration-changes</link>
					<comments>https://jasonbrimhall.info/2013/01/24/audit-configuration-changes/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 24 Jan 2013 20:49:01 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1981</guid>

					<description><![CDATA[<p>Do you know the last time a Server Property was changed on your instances of SQL Server? Are you wondering when the setting for max degree of parallelism was changed? Do you know who changed [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/24/audit-configuration-changes/">Audit Configuration Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2013/01/configaudit.png"><img loading="lazy" class="alignright size-full wp-image-1984" title="configaudit" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/configaudit.png" alt="" width="160" height="200" /></a>Do you know the last time a Server Property was changed on your instances of SQL Server?</p>
<p>Are you wondering when the setting for max degree of parallelism was changed?</p>
<p>Do you know who changed the setting?</p>
<p>In some environments there are a lot of hands trying to help mix the pot.  Sometimes more hands can make light work.  This is not always the case though.  More hands in the mix can be a troublesome thing.  Especially when things start changing and the finger pointing starts but nobody really knows for sure who made the change or when the change was made.</p>
<p>I know, that is why there is this concept called change management.  If you make a change to a setting, it should be documented, approved and communicated.  Unfortunately the process does not always dictate the work flow and it may be circumvented.  This is why auditing is a tool that is in place and should be in place &#8211; like it or not.</p>
<p>Auditing can be a very good tool.  Like many things &#8211; too much of a good thing is not a good thing.  Too much auditing can be more of a hindrance than help.  You don&#8217;t want to cause interference by auditing too many things.  You also don&#8217;t want too much data that the facts get blurred.  I hope that this script strikes more of a balance with just the right amount of data being captured to be of use.</p>
<p>The basic principle to auditing server configs is to find what values changes, when they were changed and by whom.  There are ancillary details that can be helpful in tracking the source of the change such as the hostname of the source computer making the change.  These are all things that we should capture.  But if a setting hasn&#8217;t changed &#8211; then we need not necessarily report that the setting was unchanged (it should go without saying).</p>
<p>So for this, I created a couple of tables and then a script that I can add to a job to run on a regular basis.  I can put the script in a stored procedure should I desire.  I&#8217;ll leave that to you as an exercise to perform.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">USE AdminDB;
GO
SET NOCOUNT ON;

DECLARE @ConfigLastUpdateDate	DATETIME
		,@PreviousPollDate		DATETIME
		,@MaxPollDate			DATETIME
		,@path					NVARCHAR(260);

SELECT @path = REVERSE(SUBSTRING(REVERSE([path]), 
						CHARINDEX('\', REVERSE([path])), 260)) + N'log.trc'
	FROM sys.traces 
	WHERE is_default = 1;

IF OBJECT_ID('tempdb..#DBCCConfig') IS NOT NULL DROP TABLE #DBCCConfig;
	CREATE TABLE #DBCCConfig(
		[ParentObject] VARCHAR (100),
		[Object]       VARCHAR (100),
		[Field]        VARCHAR (100),
		[Value]        VARCHAR (100)); 

INSERT INTO #DBCCConfig (ParentObject, Object, Field, Value)
	EXECUTE ('DBCC CONFIG WITH TABLERESULTS');

WITH cte AS
(
SELECT cfgupddate = MAX(CASE WHEN t1.Field = 'cfgupddate' THEN t1.Value ELSE NULL END),
        cfgupdtime = MAX(CASE WHEN t1.Field = 'cfgupdtime' THEN t1.Value ELSE NULL END)
FROM #DBCCConfig t1
WHERE   Field IN ('cfgupddate', 'cfgupdtime')
)
SELECT  @ConfigLastUpdateDate = CONVERT(DATETIME,t3.configure_upd_dt)
FROM    cte t1
        CROSS APPLY (SELECT cfgupddate = DATEADD(DAY, CONVERT(INT, t1.cfgupddate), '1900-01-01')) t2
        CROSS APPLY (SELECT configure_upd_dt = DATEADD(ms, CONVERT(INT, t1.cfgupdtime)*3.3, t2.cfgupddate)) t3;

IF NOT EXISTS (SELECT Name 
					FROM sys.objects 
					WHERE name = 'SysConfigAudit')
	CREATE TABLE SysConfigAudit (
		configuration_id	int
		,name	NVARCHAR(256)
		,value	sql_variant
		,minimum	sql_variant
		,maximum	sql_variant
		,value_in_use	sql_variant
		,description	NVARCHAR(MAX)
		,is_dynamic	bit
		,is_advanced	BIT
		,PollDate		DATE
		,LastConfigUpdtDate	DATETIME)

IF NOT EXISTS (SELECT Name 
					FROM sys.objects 
					WHERE name = 'SysConfigChangeLog')
	CREATE TABLE SysConfigChangeLog (
		configuration_id	int
		,name	NVARCHAR(256)
		,CurrValue	SQL_VARIANT
		,PrevValue	SQL_VARIANT
		,description	NVARCHAR(MAX)
		,PollDate		DATE
		,LastConfigUpdtDate	DATETIME
		,PrevConfigUpdtDate	DATETIME
		,ChangeDate	DATETIME
		,ChangeBy	NVARCHAR(256)
		,HostName	NVARCHAR(256)
		,ChangeSPID	SQL_VARIANT
		,Changedata	NVARCHAR(2000)
		,ApplicationName NVARCHAR(256)
		,Severity INT
		,ERROR SQL_VARIANT
		,ChangeBySessionLogin	NVARCHAR(256))
IF NOT EXISTS (SELECT Name 
					FROM sys.key_constraints 
					WHERE name ='PK_SysConfigChangeLog' 
						AND OBJECT_NAME(parent_object_id) = 'SysConfigChangeLog')
BEGIN
ALTER TABLE dbo.SysConfigChangeLog ADD CONSTRAINT
	PK_SysConfigChangeLog PRIMARY KEY CLUSTERED 
	(
	configuration_id,
	ChangeDate DESC
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
		ON Admin_Data

END

SET @MaxPollDate = ISNULL((SELECT TOP 1 PollDate
								FROM dbo.SysConfigAudit 
								ORDER BY PollDate DESC),'1/1/1900')

/* Write the configurations out to audit table 
*/
IF CONVERT(DATE,GETDATE()) &amp;lt;&amp;gt; @MaxPollDate
BEGIN
	INSERT INTO SysConfigAudit
			( configuration_id ,
			  name ,
			  value ,
			  minimum ,
			  maximum ,
			  value_in_use ,
			  description ,
			  is_dynamic ,
			  is_advanced,
			  PollDate,
			  LastConfigUpdtDate
			)
	SELECT configuration_id,name
			,value
			,minimum,maximum
			,value_in_use
			,description
			,is_dynamic,is_advanced
			,GETDATE(),@ConfigLastUpdateDate
		FROM master.sys.configurations;
END

/* Recast MaxPollDate */
SET @MaxPollDate = ISNULL((SELECT TOP 1 PollDate
								FROM dbo.SysConfigAudit 
								ORDER BY PollDate DESC),'1/1/1900')

SET @PreviousPollDate = ISNULL((SELECT TOP 1 PollDate 
									FROM dbo.SysConfigAudit 
									WHERE Polldate &amp;lt;&amp;gt; @MaxPollDate 
									ORDER BY PollDate DESC),'1/1/1900');

/*	A configuration has changed and a reboot has occurred 
	causing the updtdate to be written to the config block of the page 10
	The configuration may not be written to the page, but we will write it to
	the table anyway and then compare to the default trace file in all cases.
	If there are any values changed, then write those to the change log with
	the login of the person who changed the value
*/

BEGIN

WITH presel AS (
SELECT df.LoginName,df.TextData,df.StartTime,df.HostName,df.Severity,df.DatabaseName,df.SPID,df.ERROR
		,df.SessionLoginName,df.ApplicationName
		,SUBSTRING(df.TextData
					,CHARINDEX('''',df.TextData)+1
					,CHARINDEX('''',df.TextData
								,CHARINDEX('''',df.TextData)+1)-CHARINDEX('''',df.TextData)-1)
				AS ConfigName
		,ROW_NUMBER() OVER (PARTITION BY SUBSTRING(df.TextData
													,CHARINDEX('''',df.TextData)+1
													,CHARINDEX('''',df.TextData
															,CHARINDEX('''',df.TextData)+1)-CHARINDEX('''',df.TextData)-1) 
								ORDER BY df.StartTime DESC) AS RowNum
	FROM ::fn_trace_gettable( @path, DEFAULT )  df
	WHERE 1=1
		AND df.TextData LIKE '%Configuration option%'
		AND df.ApplicationName NOT IN ('SQLAgent - Initial Boot Probe','SQLAgent - Enabling/disabling Agent XPs')
		AND df.Severity IS NOT NULL
)

INSERT INTO SysConfigChangeLog (configuration_id,name,CurrValue,PrevValue,description,PollDate	
							,LastConfigUpdtDate	,PrevConfigUpdtDate	,ChangeDate,ChangeBy
							,HostName,ChangeSPID,Changedata,ApplicationName,Severity
							,ERROR,ChangeBySessionLogin)
SELECT CUR.configuration_id,cur.NAME,cur.VALUE AS CurrValue,Prev.VALUE AS PrevValue,cur.description
		,cur.polldate, cur.LastConfigUpdtDate,prev.LastConfigUpdtDate AS PrevConfigUpdtDate
		,df.StartTime AS ChangeDate,df.LoginName AS ChangeBy,df.HostName,df.SPID AS ChangeSPID
		,df.TextData AS ChangeData,df.ApplicationName,df.Severity,df.ERROR
		,df.SessionLoginName AS ChangeBySessionLogin
	FROM AdminDB.dbo.SysConfigAudit CUR
		INNER JOIN AdminDB.dbo.SysConfigAudit Prev
			ON CUR.configuration_id = Prev.configuration_id
			AND CUR.PollDate = @MaxPollDate
			AND Prev.PollDate = @PreviousPollDate
		CROSS APPLY presel  df
	WHERE df.RowNum = 1
		AND df.ConfigName = CUR.NAME
		AND CUR.VALUE &amp;lt;&amp;gt; Prev.VALUE	
		AND NOT EXISTS (SELECT configuration_id
							FROM SysConfigChangeLog
							WHERE Name = Cur.NAME
								AND CurrValue = CUR.VALUE
								AND PrevValue = Prev.VALUE
								AND ChangeDate = df.StartTime
								AND ChangeBy = df.LoginName)
		;
END

SELECT *
	FROM dbo.SysConfigChangeLog
	ORDER BY ChangeDate DESC;</pre><p>[/codesyntax]</p>
<p>Here I am trapping the config settings on a daily basis (as the script is written for now). I then cross reference the current settings against the previous settings.  Then I check the default trace to see if any of those settings exist in the trace file.</p>
<p>The default trace captures the data related to configuration changes.  On busy systems, it is still possible for these settings to roll out of the trace files.  For those systems, we may need to make some alterations to the script (such as running more frequently and changing the comparisons to account for smaller time intervals than a day break).</p>
<p>To ensure proper comparison between the audit tables and the trace file, note the substring function employed.  I can capture the configuration name and then join to the audit tables on configuration name.</p>
<p>This has proven useful to me so far in tracking who did what to which setting and when they did it.</p>
<p>I hope you will find good use for it as well.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1981" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/24/audit-configuration-changes/">Audit Configuration Changes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/24/audit-configuration-changes/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #38 Recap</title>
		<link>https://jasonbrimhall.info/2013/01/15/t-sql-tuesday-38-recap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-38-recap</link>
					<comments>https://jasonbrimhall.info/2013/01/15/t-sql-tuesday-38-recap/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 15 Jan 2013 08:00:54 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1968</guid>

					<description><![CDATA[<p>This is the wrap up for TSQL Tuesday #38.  We had a good turnout this month with some new faces and with some regulars.  In total, we had 22 entries.  All of the entries this [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/15/t-sql-tuesday-38-recap/">T-SQL Tuesday #38 Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/"><img loading="lazy" class="alignleft size-full wp-image-1969" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1502.jpg" alt="" width="150" height="150" /></a>This is the wrap up for TSQL Tuesday #38.  We had a good turnout this month with some new faces and with some regulars.  In total, we had 22 entries.  All of the entries this month were very good.</p>
<p>The topic was on &#8220;Standing Firm&#8221; and can be found by clicking the image to the left.</p>
<p>Stay tuned to twitter for future TSQL Tuesday announcements and news via the #tsql2sday hash tag.</p>
<p>&nbsp;</p>
<p><strong>Rob Farley</strong> (<a href="http://sqlblog.com/blogs/rob_farley/default.aspx" class="broken_link">blog </a>| <a href="http://twitter.com/rob_farley">twitter</a>) &#8211; <a href="http://sqlblog.com/blogs/rob_farley/archive/2013/01/08/running-goals.aspx" class="broken_link">Running Goals</a>: In his opening paragraph Rob says &#8220;Peer pressure can be useful at times, but I also find that it can make me even more stubborn.&#8221;  WOW!  I can really relate to that.  Then he proceeds to recount a story from his past that would be hard for a lot of people to overcome.  I know I would have a hard time with not being able to lift my children.  Now Rob is running and plans to keep going and improving.  Excellent story!</p>
<p><strong>Jim McLeod</strong> (<a href="http://www.jimmcleod.net/blog">blog </a>| <a href="http://www.twitter.com/Jim_McLeod">twitter</a>) &#8211; <a href="http://www.jimmcleod.net/blog/index.php/2013/01/08/t-sql-tuesday-38-standing-firm/">Environment</a>: Jim also decided to write about fitness and exercise, specifically cycling.  Jim ties planning into his goal to cycle more and stick with it.  Then he ties that into SQL Server.  &#8220;Put together an environment that supports and encourages you to stick to your resolution.&#8221;  Plan ahead whether it be with certification or cycling, and not just for the happy times but for the rough times as well.</p>
<p><strong>Thomas Stringer</strong> (<a href="http://sqlsalt.com/">blog </a>| <a href="http://twitter.com/SQLife">twitter</a>) &#8211; <a href="http://sqlsalt.com/t-sql-tuesday-38-the-lucky-2013/">Lucky 13</a>:  Like many cross country runners, Thomas wants to hit it hard.  Then he wants to maintain the pace.  The principle is to set out to do something and build up a routine.  Routine becomes habit &#8211; and eventually becomes easier.  Thomas is setting out to learn something new every day.  That is a good goal.</p>
<p><strong>Robert Davis</strong> (<a href="http://www.sqlsoldier.com/" class="broken_link">blog </a>| <a href="http://twitter.com/SQLSoldier">twitter</a>) &#8211; <a href="http://www.sqlsoldier.com/wp/sqlserver/day8of31daysofdisasterrecoverytsqltuesday38resolutionsforalldbas" class="broken_link">Disaster Recovery Resolutions</a>:  This month Robert happens to be providing a month long series on Disaster Recovery.  In keeping with that theme, he has offered up several resolutions every DBA should make.</p>
<p><strong>Koen Verbeeck</strong> (<a href="https://blogs.lessthandot.com/author/koen-verbeeck">blog </a>| <a href="http://twitter.com/Ko_Ver">twitter</a>) &#8211; <a href="https://blogs.lessthandot.com/index.php/datamgmt/dbprogramming/mssqlserver/t-sql-tuesday-38-resolving/">Resolving an SSIS Performance Problem</a>:  Koen reached Defcon 2 (not really &#8211; but you should read it) when presented an opportunity to troubleshoot performance problems in an SSIS package.  The problem seems pretty typical &#8211; package works and then starts slowing down over time.  Part of the reason for that is due to four bullet points that Koen discusses.</p>
<p><strong>John Sansom</strong> (<a href="http://www.johnsansom.com/">blog </a>| <a href="http://twitter.com/SqlBrit">twitter</a>) &#8211; <a href="http://www.johnsansom.com/step-up-and-take-more-ownership/">Take More Ownership</a>:  John hits on a big button in his contribution this month.  There are problems within our database environments.  Often times these problems are allowed to coexist.  While they cost time and money and raise frustration levels, how many times do we step up and offer a solution to the real problem?  It&#8217;s a good story &#8211; check it out.</p>
<p><strong>Matt Velic</strong> (<a href="http://mattvelic.com/">blog </a>| <a href="http://twitter.com/mvelic">twitter</a>) &#8211; <a href="https://web.archive.org/web/20130121232914/http://mattvelic.com/tsql-tuesday-38/">Stuck</a>:  Matt is a thinker and he was stuck in a rut of late.  Matt enjoys thinking about decisions &#8211; a lot.  This was contributing to him being stuck.  He reveals some quick tips about how to get unstuck and to enjoy life just a bit more.</p>
<p><strong>Steve Jones</strong> (<a href="http://voiceofthedba.com/">blog </a>| <a href="http://twitter.com/way0utwest">twitter</a>) &#8211; <a href="http://voiceofthedba.wordpress.com/2013/01/08/t-sql-tuesday-38-standing-firm/">Resolute</a>:  Many people have a hard time standing up for what they want or believe.  They have a hard time saying &#8220;no.&#8221;  We sometimes joke about DBAs being a stop in the flow in work because we say &#8220;no&#8221; too much.  I think we probably do not say &#8220;no&#8221; enough.  And Steve points out plenty of ways that we need to learn to say no more often.  It is all about life balance.  How many times do you say &#8220;no&#8221; to a new project when you already have a full plate?</p>
<p><strong>Julie Koesmarno</strong> (<a href="http://www.mssqlgirl.com/">blog </a>| <a href="http://twitter.com/MsSQLGirl">twitter</a>) &#8211; <a href="http://www.mssqlgirl.com/standing-firm-story-of-a-wit.html">Tribute to Mum</a>:  Julie, like her mother, is a WIT/Engineering.  We learn   about some of the personal life of Julie as she gives credit to her mother for being a role model as she grew up.  Now, Julie wants to help be an inspiration to others as her mother was for her.</p>
<p><strong>Chris Fradenburg</strong> (<a href="https://web.archive.org/web/20160305161212/http://fradensql.com/">blog</a> | <a href="https://twitter.com/chrisfradenburg">twitter</a>) &#8211; <a href="http://www.fradensql.com/2013/01/t-sql-tuesday-38resolution/" class="broken_link">Avoiding the Repetitive Mess of a Disaster</a>:  Chris is the first of the first timers that participated this month (we had a few &#8211; woohoo).  Besides the bottle of gel soap that must be used every time he washes his hands, he is trying to improve his environment by reducing the manual repetitive tasks.  This is a good story about a disaster encountered on the first day on the new job.</p>
<p><strong>Wayne Sheffield</strong> (<a href="http://blog.waynesheffield.com/wayne">blog </a>| <a href="http://twitter.com/DBAWayne">twitter</a>) &#8211; <a href="http://blog.waynesheffield.com/wayne/archive/2013/01/t-sql-tuesday-38-standing-firm/">Learning</a>:  I did a fair bit of arm twisting to get Wayne to participate this month.  He was having a bit of writers block.  Then a topic fell into his lap and it should provide a month of writing for him.  Wayne discusses how is looking to learn and also provide a series of articles on PoSH to help others learn.  It should be out soon!</p>
<p><strong>Alan Dykes</strong> (<a href="http://alandykes.com/" class="broken_link">blog </a>| <a href="http://twitter.com/dykesa">twitter</a>) &#8211; <a href="https://web.archive.org/web/20140214160751/http://alandykes.com/2013/01/08/t-sql-tuesday-38-performance-resolution/">Solid Skills</a>:  Alan is pretty much a self taught SQL Developer.  He has recently resolved to sharpen his skillset.  He learned from reading another post about how performance can vary by using a different tsql solution (e.g. NOT EXISTS versus LEFT OUTER JOINS).</p>
<p><strong>Robert Pearl</strong> (aka Bobby Tables) (<a href="http://www.sqlservercentral.com/blogs/pearlknows/">blog </a>| <a href="http://twitter.com/PearlKnows">twitter</a>) &#8211; <a href="http://www.sqlservercentral.com/blogs/pearlknows/2013/01/08/t-sql-tuesday-38-standing-firm/">HealthySQL</a>:  Some more arm twisting on this one.  Bobby has an excellent idea and it is something we should resolve to do every year as Data professionals.  Too often we get into the break/fix mode rather than the preemptive strike mode.  Regular maintenance (like you should do with your car) keeps things running longer and with less overall cost.</p>
<p><strong>Hemanth.D </strong>(<a href="http://sqlchow.wordpress.com/">blog </a>| <a href="http://twitter.com/SqlChow">twitter</a>) &#8211; <a href="http://sqlchow.wordpress.com/2013/01/08/t-sql-tuesday-38-standing-firm/">Firmness of Purpose</a>:  Hemanth is the second of our first timers to participate this month.  Hemanth goes back and explores the past a little and how community ties in with the #SQLFamily.  Hemanth wants to be more resolute in the upcoming year when faced with an issue and ensuring the issue is resolved.</p>
<p><strong>Mickey Stuewe</strong> (<a href="http://mickeystuewe.com/">blog </a>| <a href="http://twitter.com/SQLMickey">twitter</a>) &#8211; <a href="http://mickeystuewe.com/2013/01/08/t-sql-tuesday-38-there-is-no-spoon/">Spoons</a>:  Mickey introduces us first to Neo and his effort at bending a spoon.  Then she correlates that to her writing ability.  For her to write is like trying to bend a spoon with her mind.  So she uses other tools to accomplish the goal.  She shared a couple of tools of which I think I will try the mind mapping tool.  That might mean some bizarre maps though.</p>
<p><strong>Ed Watson</strong> (<a href="http://sqlgator.com/">blog </a>| <a href="http://twitter.com/SQLGator">twitter</a>) &#8211; <a href="http://sqlgator.com/2013/01/08/t-sql-tuesday-38-speaking-of-resolve/">Speaking of Resolve</a>:  Another first timer to the party (iirc), Ed shares his resolution to start speaking more at the local level.  Ed was more prone to flight than fight when it came to public speaking.  He talks about his experience and what he did in 2012 to start speaking publicly.</p>
<p><strong>Jeffrey Verheul</strong> (<a href="http://devjef.wordpress.com/">blog </a>| <a href="http://twitter.com/DevJef">twitter</a>) &#8211; <a href="http://devjef.wordpress.com/2013/01/08/t-sql-tuesday-38-standing-firm/">Standing Firm</a>:  Jeff had already planned out his goals by the time TSQL Tuesday rolled around.  After he had written some goals, he ran into a rough patch.  Based on that week, he has chosen to stand more firm and improve all that much more.</p>
<p><strong>Ana Mihalj</strong> (<a href="http://amihalj.wordpress.com/">blog </a>| <a href="http://twitter.com/amihalj">twitter</a>) &#8211; <a href="http://amihalj.wordpress.com/2013/01/08/t-sql-tuesday-38-standing-firm/">Getting Involved</a>:  Another warm welcome to another first timer.  Ana is from Bosnia and Herzegovina and has been working on blogging and getting involved in the community for the past year and a half.  Now she wants to step up her efforts.</p>
<p><strong>Ken Watson</strong> (<a href="http://interflextech.com/">blog </a>| <a href="http://twitter.com/Interflextech">twitter</a>) &#8211; <a href="https://web.archive.org/web/20160313113745/http://interflextech.com/blog/post/2013/01/08/T-SQL-Tuesday-38-e28093-Standing-Firm.aspx">Not an Average Accidental DBA</a>:  Ken shares a story on how he transitioned from a jack of all trades to being a DBA.  Ken is not enamored with being an average DBA and is working at something about which he is passionate.  He chased a dream and it is working out for him.</p>
<p><strong>Tim Ford</strong> (<a href="http://thesqlagentman.com/">blog </a>| <a href="http://twitter.com/sqlagentman">twitter</a>) &#8211; <a href="http://thesqlagentman.com/2013/01/tsqltuesday/">Bring out your Dead</a>:  You&#8217;ll get it once you read his post.  Tim is bringing back <a href="http://thesqlagentman.com/go/learn365">#Learn365</a>.  If there were two themes this month it was exercise and learning.  Learn365 is right up that alley with learning.  Go check it out.</p>
<p><strong>Chris Yates</strong> (<a href="http://chrisyatessql.wordpress.com/">blog </a>| <a href="http://twitter.com/YatesSQL">twitter</a>) &#8211; <a href="http://chrisyatessql.wordpress.com/2013/01/08/t-sql-tuesday-38-standing-firm/">Hoops and Databases</a>:  We have a baller among us.  Chris talks about the resolve he had as a High School athlete to be a better ball player and make it to the Collegiate game.  That same resolve is applicable to being an Exceptional DBA.  Practice your craft and stand firm in your determination to be an Exceptional DBA.</p>
<p><strong>My entry</strong> (<a href="http://twitter.com/sqlrnnr">twitter</a>) &#8211; <a href="http://jasonbrimhall.info/2013/01/07/a-firm-foundation/">A Firm Foundation</a>:  I shared a story that relates to disaster recovery and database consistency.  In that article, I also explored the immediate impact of changing the page verify for your database (plan cache).</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1968" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/15/t-sql-tuesday-38-recap/">T-SQL Tuesday #38 Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/15/t-sql-tuesday-38-recap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>January S3OLV 2013</title>
		<link>https://jasonbrimhall.info/2013/01/09/january-s3olv-2013/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=january-s3olv-2013</link>
					<comments>https://jasonbrimhall.info/2013/01/09/january-s3olv-2013/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 09 Jan 2013 17:30:33 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1961</guid>

					<description><![CDATA[<p>I hope you are ready for some free SQL learning.  Coming up on Thursday January 10th at 6:30 PM Pacific (GMT &#8211; 8 ) we will have a stellar opportunity to do just that &#8211; [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/09/january-s3olv-2013/">January S3OLV 2013</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I hope you are ready for some free SQL learning.  Coming up on Thursday January 10th at 6:30 PM Pacific (GMT &#8211; 8 ) we will have a stellar opportunity to do just that &#8211; Learn!</p>
<p>Edwin Sarmiento will be presenting for us this at the upcoming monthly Las Vegas User Group meeting.  Edwin has chosen (well he left it up to me to decide) to present on Powershell.</p>
<h3>Title: Windows PowerShell for the SQL Server DBA</h3>
<p><img loading="lazy" class="alignright size-full wp-image-1962" title="globe" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/globe.png" alt="" width="160" height="159" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/01/globe.png 160w, https://jasonbrimhall.info/wp-content/uploads/2013/01/globe-150x150.png 150w" sizes="(max-width: 160px) 85vw, 160px" /></p>
<h3>Abstract</h3>
<p>Windows PowerShell is becoming the scripting language of choice for managing Microsoft servers and workstations. And while T-SQL is still the scripting language for DBAs to administer and manage SQL Server, there are tons of stuff that can be easily done with Windows PowerShell. In this session, learn Windows PowerShell from the ground up and how you can use it with SQL Server Management Objects (SMO) to administer and manage a SQL Server instance.</p>
<p>Here is the bonus behind all of this &#8211; we will be broadcasting the presentation to the virtual sphere.Here are the details for joining the meeting via livemeeting.</p>
<p><strong>Copy this address and paste it into your web browser:</strong></p>
<ul>
<li>https://www.livemeeting.com/<wbr />cc/UserGroups/join</li>
</ul>
<p><strong>Copy and paste the required information:</strong></p>
<ul>
<li>Meeting ID: JRW8JQ</li>
<li>Location: https://www.livemeeting.com/cc/UserGroups</li>
</ul>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1961" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/09/january-s3olv-2013/">January S3OLV 2013</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/09/january-s3olv-2013/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A Firm Foundation</title>
		<link>https://jasonbrimhall.info/2013/01/07/a-firm-foundation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-firm-foundation</link>
					<comments>https://jasonbrimhall.info/2013/01/07/a-firm-foundation/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Jan 2013 00:12:53 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1953</guid>

					<description><![CDATA[<p>Last week I sent out an invite for the monthly TSQL Tuesday party. The theme for the party is a take on the words resolve or resolution.  I was hoping the theme would encourage some [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/07/a-firm-foundation/">A Firm Foundation</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/"><img loading="lazy" class="alignleft size-full wp-image-1954" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x1501.jpg" alt="" width="150" height="150" /></a></p>
<p>Last week I sent out an <a href="http://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/">invite </a>for the monthly TSQL Tuesday party.</p>
<p>The theme for the party is a take on the words resolve or resolution.  I was hoping the theme would encourage some reflection and sharing of real life experiences that have led to a difference being made.</p>
<p>I have resolved on two stories to share.  Both are rather short and simple in nature.</p>
<p>&nbsp;</p>
<figure id="attachment_1955" aria-describedby="caption-attachment-1955" style="width: 560px" class="wp-caption aligncenter"><img loading="lazy" class="size-large wp-image-1955 " title="Double-O-Arch" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/Double-O-Arch_Arches_National_Park_2-1024x682.jpg" alt="" width="560" height="372" srcset="https://jasonbrimhall.info/wp-content/uploads/2013/01/Double-O-Arch_Arches_National_Park_2-1024x682.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2013/01/Double-O-Arch_Arches_National_Park_2-300x200.jpg 300w" sizes="(max-width: 560px) 85vw, 560px" /><figcaption id="caption-attachment-1955" class="wp-caption-text">This arch (in Arches National Park, Ut.) has stood RESOLUTE for milennia</figcaption></figure>
<h2>Story the First</h2>
<p>Near the end of the year in 2012, I inherited a database that had not had a consistency check done on it &#8211; ever!  In checking the page_verify setting, I found that it was set to none as well.  Both of these should be alarming to any DBA &#8211; unless you are completely unconcerned by corrupt data and the potential for corrupt data.  Never-mind the potential business repercussions of having corrupt or lost data.</p>
<p>To find what level of page verification you have enabled, it is a matter of a quick script like the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Select name, page_verify_option_desc
	From sys.databases;</pre><p>[/codesyntax]</p>
<p>You can have any one of three settings for your page_verify.  The recommended option is to have CHECKSUM enabled.  If you see NONE or TORN_PAGE_DETECTION, you really need to consider changing that.  Keep in mind if you are still running SQL 2000, CHECKSUM is not an option and the query provided will fail.</p>
<p>Changing the verify option is very simple as well.  It only requires an Alter Database to be run such as the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER DATABASE [msdb]
	SET PAGE_VERIFY CHECKSUM;</pre><p>[/codesyntax]</p>
<p>You will probably notice that I am using the msdb in my sample script.  There is a reason for this that will be shown later.  Just keep in mind that msdb should not need to be changed because it should already be using the CHECKSUM option.</p>
<p>What if you have numerous databases that are not using the CHECKSUM method?  It can become rather tedious to change each of those manually.  That is why we might come up with a cursor such as the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE
	@DBName SYSNAME,
	@SQL    varchar(512);

DECLARE dbchecksum CURSOR
	LOCAL STATIC FORWARD_ONLY READ_ONLY
	FOR Select name
		from sys.databases
		where name not in ('tempdb')
			AND state_desc = 'online'
			AND page_verify_option_desc &amp;lt;&amp;gt; 'Checksum';

Open dbchecksum;
Fetch Next From dbchecksum into @DBName;
While @@Fetch_Status = 0
Begin
Set @SQL = 'ALTER DATABASE [' + @DBName +'];' +char(10)+char(13)
SET @SQL = @SQL + 'SET PAGE_VERIFY CHECKSUM;' +char(10)+char(13)

Execute (@SQL);
Set @SQL = ''

Fetch Next From dbchecksum into @DBName;
End
Close dbchecksum;
Deallocate dbchecksum;</pre><p>[/codesyntax]</p>
<p>This script is only checking for databases that are not using CHECKSUM.  Then it loops through and changes the setting to use CHECKSUM.</p>
<p><strong>I strongly caution about running this in production without an outage window!</strong>  I make that recommendation for very simple reasons.  First, the change is to a production system.  Second, the change can have a temporary adverse effect.  Now before you get too excited about it, I have a short demonstration.</p>
<p>Here is a script broken out into three sections.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT TOP(10) [type] AS [Memory Clerk Type], SUM(single_pages_kb) AS [SPA Mem, Kb] 
FROM sys.dm_os_memory_clerks WITH (NOLOCK)
GROUP BY [type]  
ORDER BY SUM(single_pages_kb) DESC OPTION (RECOMPILE);
SELECT DB_NAME(database_id) AS [Database Name],
COUNT(*) * 8/1024.0 AS [Cached Size (MB)]
FROM sys.dm_os_buffer_descriptors
WHERE database_id &amp;lt;&amp;gt; 32767 -- ResourceDB
--AND database_id &amp;gt; 4 -- system databases
GROUP BY DB_NAME(database_id)
ORDER BY [Cached Size (MB)] DESC OPTION (RECOMPILE);

SELECT DB_NAME(dbid) AS DbName,dbid,SUM(size_in_bytes)/1024/1024 AS TotalPlanCacheSize_in_MB
FROM sys.dm_exec_cached_plans cp WITH (NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(plan_handle) st
GROUP BY dbid</pre><p>[/codesyntax]</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">ALTER DATABASE [msdb]
		SET PAGE_VERIFY CHECKSUM;</pre><p>[/codesyntax]</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT TOP(10) [type] AS [Memory Clerk Type], SUM(single_pages_kb) AS [SPA Mem, Kb] 
FROM sys.dm_os_memory_clerks WITH (NOLOCK)
GROUP BY [type]  
ORDER BY SUM(single_pages_kb) DESC OPTION (RECOMPILE);
SELECT DB_NAME(database_id) AS [Database Name],
COUNT(*) * 8/1024.0 AS [Cached Size (MB)]
FROM sys.dm_os_buffer_descriptors
WHERE database_id &amp;lt;&amp;gt; 32767 -- ResourceDB
--AND database_id &amp;gt; 4 -- system databases
GROUP BY DB_NAME(database_id)
ORDER BY [Cached Size (MB)] DESC OPTION (RECOMPILE);

SELECT DB_NAME(dbid) AS DbName,dbid,SUM(size_in_bytes)/1024/1024 AS TotalPlanCacheSize_in_MB
FROM sys.dm_exec_cached_plans cp WITH (NOLOCK)
CROSS APPLY sys.dm_exec_sql_text(plan_handle) st
GROUP BY dbid</pre><p>[/codesyntax]</p>
<p>Sections one and three are the same.  This script is used to measure various memory components within SQL Server.  The second section is the change we will make to the msdb database.  The queries in the first and third section perform the following: retrieve memory clerk usage (aggregated to memory clerk type), retrieve total data pages stored in cache (aggregated by database), and retrieve the plan cache use (aggregated by database).</p>
<p>Now on to some pre and post change results.  First with what my results were prior to the change.</p>
<table width="287" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="114" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Memory Clerk Usage</td>
<td width="114"></td>
</tr>
<tr>
<td height="20"><strong>Memory Clerk Type</strong></td>
<td><strong>SPA Mem, Kb</strong></td>
</tr>
<tr>
<td height="20">CACHESTORE_SQLCP</td>
<td align="right">156184</td>
</tr>
<tr>
<td height="20">CACHESTORE_PHDR</td>
<td align="right">45904</td>
</tr>
<tr>
<td height="20">CACHESTORE_OBJCP</td>
<td align="right">20664</td>
</tr>
<tr>
<td height="20">USERSTORE_DBMETADATA</td>
<td align="right">8472</td>
</tr>
<tr>
<td height="20">USERSTORE_SCHEMAMGR</td>
<td align="right">6376</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="287" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="114" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Pages in Cache</td>
<td width="114"></td>
</tr>
<tr>
<td height="20"><strong>Database Name</strong></td>
<td><strong>Cached Size (MB)</strong></td>
</tr>
<tr>
<td height="20">msdb</td>
<td align="right">12.265625</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="463" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="114" />
<col width="176" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Plan Cache</td>
<td width="114"></td>
<td width="176"></td>
</tr>
<tr>
<td height="20"><strong>DbName</strong></td>
<td><strong>dbid</strong></td>
<td><strong>TotalPlanCacheSize_in_MB</strong></td>
</tr>
<tr>
<td height="20">NULL</td>
<td align="right">32767</td>
<td align="right">42</td>
</tr>
<tr>
<td height="20">NULL</td>
<td>NULL</td>
<td align="right">150</td>
</tr>
<tr>
<td height="20">msdb</td>
<td align="right">4</td>
<td align="right">13</td>
</tr>
<tr>
<td height="20">ReportServer$ADMIN</td>
<td align="right">5</td>
<td align="right">0</td>
</tr>
<tr>
<td height="20">MDW</td>
<td align="right">28</td>
<td align="right">8</td>
</tr>
<tr>
<td height="20">AdminDB</td>
<td align="right">14</td>
<td align="right">0</td>
</tr>
</tbody>
</table>
<p>And the following are the post change results.</p>
<table width="288" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="115" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Memory Clerk Usage</td>
<td width="115"></td>
</tr>
<tr>
<td height="20"><strong>Memory Clerk Type</strong></td>
<td><strong>SPA Mem, Kb</strong></td>
</tr>
<tr>
<td height="20">CACHESTORE_SQLCP</td>
<td align="right">109160</td>
</tr>
<tr>
<td height="20">CACHESTORE_PHDR</td>
<td align="right">36744</td>
</tr>
<tr>
<td height="20">CACHESTORE_OBJCP</td>
<td align="right">9152</td>
</tr>
<tr>
<td height="20">USERSTORE_DBMETADATA</td>
<td align="right">8472</td>
</tr>
<tr>
<td height="20">USERSTORE_SCHEMAMGR</td>
<td align="right">6296</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="288" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="115" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Data Pages in Cache</td>
<td width="115"></td>
</tr>
<tr>
<td height="20"><strong>Database Name</strong></td>
<td><strong>Cached Size (MB)</strong></td>
</tr>
<tr>
<td height="20">msdb</td>
<td align="right">12.265625</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="465" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="173" />
<col width="115" />
<col width="177" /> </colgroup>
<tbody>
<tr>
<td width="173" height="20">Plan Cache</td>
<td width="115"></td>
<td width="177"></td>
</tr>
<tr>
<td height="20"><strong>DbName</strong></td>
<td><strong>dbid</strong></td>
<td><strong>TotalPlanCacheSize_in_MB</strong></td>
</tr>
<tr>
<td height="20">NULL</td>
<td align="right">32767</td>
<td align="right">36</td>
</tr>
<tr>
<td height="20">NULL</td>
<td>NULL</td>
<td align="right">104</td>
</tr>
<tr>
<td height="20">ReportServer$ADMIN</td>
<td align="right">5</td>
<td align="right">0</td>
</tr>
<tr>
<td height="20">MDW</td>
<td align="right">28</td>
<td align="right">8</td>
</tr>
<tr>
<td height="20">AdminDB</td>
<td align="right">14</td>
<td align="right">0</td>
</tr>
</tbody>
</table>
<p>First observation I want to point out is with the second result for both the pre and post run.  Making this change will not affect the pages in cache.  This goes along with what we have been taught by Paul Randal &#8211; that a CHECKSUM is not performed immediately (I paraphrased).  You can read more about the CHECKSUM and some misconceptions about it <a href="http://www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-1730-page-checksums/">here</a>.</p>
<p>If we now turn our attention to the first and third result sets, we will see that there are changes in the memory clerks used and the plan cache.  Starting with the the third result set (both pre and post) we see that the ResourceDB decreased in total plan cache size.  The NULL item (adhoc queries not associated to a specific database) also decreased.  After that, the only change in size is the msdb database &#8211; disappeared from the results due to no plan cache in use associated to this database.  (Starting to see why I chose the msdb database for this demo?)</p>
<p>If you now look closer at the results for the first query on both sides of the change, you will see correlating changes to the plan cache.  Notice that CACHESTORE_SQLCP dropped by about 46MB (correlates to the null entry from query 3).  But of those clerks listed, you will see that only USERSTORE_DBMETADATA did not change in size.</p>
<p>Looking at these results should demonstrate why this change should be performed during a maintenance window.  There will be an effect on performance and I would rather you let the business know what is coming down the pipe.  This change is akin to running DBCC FLUSHPROCINDB(&lt;db_id&gt;);.  There are other database settings that will have the same effect.  You can read a little about that from Kalen Delaney &#8211; <a href="http://sqlblog.com/blogs/kalen_delaney/archive/2010/05/21/clearing-plans-for-a-single-database.aspx" class="broken_link">here</a>.</p>
<h3>Story the Second</h3>
<p>This story is far less interesting and a whole lot shorter.  This falls into the category of professional development and fine tuning my skills.  I took the MCM lab exam during the PASS Summit.  I failed, not unlike many who have attempted it.  That is all fine and well. I learned some things about myself and I learned some areas that may need some resolution (sharpened focus).</p>
<p>So as more of a resolution upon which I have greater resolve than a New Years resolution, I will be retaking the Lab exam.  And I will be getting my MCM in the near future.  Just sayin&#8217;!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1953" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/07/a-firm-foundation/">A Firm Foundation</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/07/a-firm-foundation/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>SSRS Subscriptions Report</title>
		<link>https://jasonbrimhall.info/2013/01/07/ssrs-subscriptions-report/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssrs-subscriptions-report</link>
					<comments>https://jasonbrimhall.info/2013/01/07/ssrs-subscriptions-report/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 07 Jan 2013 18:21:24 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[SSRS Administration]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1949</guid>

					<description><![CDATA[<p>As a part of my series leading up to Christmas 2012, I shared a script to Report on SSRS Subscriptions.  It was soon found to have a bug with SQL Server 2008 R2 SP2.  IN [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/07/ssrs-subscriptions-report/">SSRS Subscriptions Report</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As a part of my series leading up to Christmas 2012, I shared a script to <a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">Report on SSRS Subscriptions</a>.  It was soon found to have a bug with SQL Server 2008 R2 SP2.  IN the comments on that post, I promised to post an updated script.  Here is that update &#8211; without the bug.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ReportName VARCHAR(100)
SET @ReportName = NULL;

CREATE TABLE #morepower (MonthDate BIGINT,N BIGINT,PowerN BIGINT PRIMARY KEY CLUSTERED
							,NameofMonth VARCHAR(25),WkDay VARCHAR(25))
;

WITH powers(powerN, n) AS (
	SELECT POWER(2,number), number 
		FROM master.dbo.spt_values 
		WHERE type = 'P' AND number &amp;lt; 31)

INSERT INTO #morepower ( MonthDate ,N,PowerN ,NameofMonth ,WkDay)
	SELECT ROW_NUMBER() OVER (ORDER BY N) AS MonthDate,N,PowerN
			,CASE WHEN N BETWEEN 0 AND 11 
				THEN DateName(month,DATEADD(month,N+1,0)-1)
				ELSE NULL
				END AS NameofMonth
			,CASE WHEN N BETWEEN 0 AND 6
				THEN DATENAME(weekday,DATEADD(DAY,n+1,0)-2)
				ELSE NULL
				END AS WkDay
		FROM powers

SELECT DISTINCT s.ScheduleID,Ca.Path as ReportManagerPath,Ca.Name as ReportName
		, U.UserName as SubscriptionCreator
		,Su.Description as SubscriptionDescription,S.StartDate,Su.LastRunTime
		,CASE 
				WHEN s.RecurrenceType = 1 THEN 'One Off'
				WHEN s.RecurrenceType = 2 THEN 'Hour'
				WHEN s.RecurrenceType = 4 THEN 'Daily'
				WHEN s.RecurrenceType = 5 THEN 'Monthly' 
				WHEN s.RecurrenceType = 6 THEN 'Week of Month' 
			END AS RecurrenceType
		,s.EventType
		,ISNULL(REPLACE(REPLACE(STUFF(
					(Select ', ['+CONVERT(VARCHAR(20),MonthDate)+']' AS [text()] 
						FROM #morepower m1 
						WHERE m1.powerN &amp;lt; s.DaysofMonth+1 
							AND s.DaysofMonth &amp;amp; m1.powerN &amp;lt;&amp;gt;0 
						ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
			   , 1, 2, ''),'[',''),']','')
			,'N/A') AS DaysofMonth
		,ISNULL(c1.NameOfMonth,'N/A') AS MonthString
		,ISNULL(c2.WkDays,'N/A') AS DaysofWeek
		,CASE MonthlyWeek
				WHEN 1 THEN 'First'
				WHEN 2 THEN 'Second'
				WHEN 3 THEN 'Third'
				WHEN 4 THEN 'Fourth'
				WHEN 5 THEN 'Last'
				ELSE 'N/A'
			END AS MonthlyWeek
		,ISNULL(CONVERT(VARCHAR(10),s.DaysInterval),'N/A') AS DaysInterval
		,ISNULL(CONVERT(VARCHAR(10),s.MinutesInterval),'N/A') AS MinutesInterval
		,ISNULL(CONVERT(VARCHAR(10),s.WeeksInterval),'N/A') AS WeeksInterval
	FROM #morepower mp, dbo.Schedule s
		INNER JOIN ReportSchedule RS
			ON S.ScheduleID = RS.ScheduleID
		INNER JOIN Catalog Ca
			ON Ca.ItemID = RS.ReportID
		INNER JOIN Subscriptions Su
			ON Su.SubscriptionID = RS.SubscriptionID
		INNER JOIN Users U
			ON U.UserID = S.CreatedById
			OR U.UserID = Su.OwnerID
	CROSS APPLY (Select s.ScheduleID,REPLACE(REPLACE(STUFF(
							(SELECT ', ['+ NameofMonth + ']' AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s1
								WHERE m1.NameofMonth IS NOT NULL 
									AND m1.powerN &amp;amp; s1.Month &amp;lt;&amp;gt;0 
									AND s1.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
							, 1, 2, ''),'[',''),']','') AS NameOfMonth)c1
	CROSS APPLY (SELECT s.ScheduleID,REPLACE(REPLACE(STUFF(
							(SELECT ', [' + WkDay + ']' AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s2
								WHERE m1.WkDay IS NOT NULL 
									AND DaysOfWeek &amp;amp; m1.powerN &amp;lt;&amp;gt;0
									AND  s2.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH(''), TYPE).value('.','VARCHAR(MAX)')
							, 1, 2, ''),'[',''),']','') AS WkDays) c2
	WHERE Ca.Name = ISNULL(@ReportName,Ca.Name);

DROP TABLE #morepower;</pre><p>&nbsp;</p>
<p>The inline code seen above likes to reformat and and will throw an error due to capitalization of the function value and text().  Download the script here: <a href="http://jasonbrimhall.info/wp-content/uploads/2013/01/SSRS_SubscriptionsV1_5.zip">SSRS_SubscriptionsV1_5</a></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1949" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/07/ssrs-subscriptions-report/">SSRS Subscriptions Report</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/07/ssrs-subscriptions-report/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #38 &#8211; Standing Firm</title>
		<link>https://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-38-standing-firm</link>
					<comments>https://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 02 Jan 2013 07:30:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Community]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1939</guid>

					<description><![CDATA[<p>Introduction Welcome back for the 38th installment in the wildly popular blog party for the SQL Server community.  This is the party that happens on the second Tuesday of each month.  The party was started [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/">T-SQL Tuesday #38 – Standing Firm</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><img loading="lazy" class="alignright size-full wp-image-1940" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2013/01/TSQL2sDay150x150.jpg" alt="" width="150" height="150" />Introduction</h2>
<p>Welcome back for the 38th installment in the wildly popular blog party for the SQL Server community.  This is the party that happens on the second Tuesday of each month.  The party was started by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/" target="_blank" class="broken_link">B</a>|<a href="https://twitter.com/AdamMachanic" target="_blank">T</a>) just over three years ago.</p>
<p>Each month a new host selects a theme and announces it about a week in advance.  And this month I will be hosting.</p>
<h2>Theme</h2>
<p>To kick off the new year (2013), we must first adhere to a little tradition.  This is not a T-SQL Tuesday tradition.  It is more of an <a href="http://www.youtube.com/watch?v=acxnmaVTlZA">annual tradition for all to welcome the new year</a>.  Feel free to click the link and sing along!!</p>
<p>Now for the theme.  A common thing for many people to do this time of year is to do a little self reflection.  Some set meaningful goals for themselves.  Fewer actually accomplish those goals or even follow-up after initially setting the goal.</p>
<p>We are not going to set goals as a part of this T-SQL Tuesday &#8211; unless you want to.  I want to take a little different spin on the New Year&#8217;s &#8220;resolution&#8221; tradition.  So the theme this month is &#8220;Standing Firm.&#8221;</p>
<p>The idea for this theme is to start with a little self reflection.  Then to come up with a story relating to one of these words: resolve, resolution, or resolute.  Here are some examples of how these stories may be portrayed.</p>
<ul>
<li>Resolve:  A system outage occurred and you &#8220;resolved&#8221; it.</li>
<li>Resolute:  You made an executive decision and did not waver from it.</li>
<li>Resolution:  You discovered a bug and documented a work-a-round resolution for it.</li>
<li>Resolution:  You have discovered certain T-SQL skills are fuzzy and want to sharpen your ability in that area.</li>
<li>Resolute:  You are determined to improve performance in your application.</li>
</ul>
<p>All of these words are very closely related.  It is up to you to determine how you would like to apply them to your T-SQL world.  Your experiences and stories can be loosely or tightly coupled to T-SQL, it is up to you.</p>
<p>And since the theme requires a little bit of self-reflection first, bonus kudos to those that can tie a past experience to a future plan.</p>
<h2>The Rules</h2>
<p>I know, parties are not supposed to have rules.  Sadly, all parties have some rules &#8211; you just may not know them.  These rules are very simple.</p>
<ol>
<li>Your post must go live between 00:00:00 GMT on Tuesday the 8<sup>th</sup> of January 2013 and 00:00:00 GMT on Wednesday the 9<sup>th</sup>.</li>
<li>Your post has to link back to the hosting blog, and the link must be anchored from the T-SQL Tuesday LOGO (found above) which must also appear at the top of the post.</li>
<li>Trackbacks should work. However, all comments and trackbacks are moderated, so give me a few minutes. If you think you waited long enough and still don&#8217;t see yours, leave a comment below.</li>
<li>Tweet your post to the #TSQL2sDay hash tag.</li>
<li>Have Fun writing and participating.</li>
</ol>
<p>Follow these rules, and your post will be included in the roundup that will be posted on the 15<sup>th</sup> or 16<sup>th</sup> of January.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1939" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/">T-SQL Tuesday #38 – Standing Firm</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2013/01/02/t-sql-tuesday-38-standing-firm/feed/</wfw:commentRss>
			<slash:comments>29</slash:comments>
		
		
			</item>
		<item>
		<title>On the Twelfth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/24/on-the-twelfth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-twelfth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/24/on-the-twelfth-day/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 25 Dec 2012 05:56:32 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Lab]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1925</guid>

					<description><![CDATA[<p>Bacon wrapped frog legs (twelve of them) for Christmas.  No more drumming for these guys!! What could be better than bacon wrapped frog legs?  Oh yeah, more Virtual lab setup. We will delve into setting [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/24/on-the-twelfth-day/">On the Twelfth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/drummers_lastdrum.png"><img loading="lazy" class="alignright  wp-image-1927" title="drummers_lastdrum" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/drummers_lastdrum.png" alt="" width="329" height="188" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/drummers_lastdrum.png 470w, https://jasonbrimhall.info/wp-content/uploads/2012/12/drummers_lastdrum-300x171.png 300w" sizes="(max-width: 329px) 85vw, 329px" /></a>Bacon wrapped frog legs (twelve of them) for Christmas.  No more drumming for these guys!!</p>
<p>What could be better than bacon wrapped frog legs?  Oh yeah, more Virtual lab setup.</p>
<p>We will delve into setting up a SQL Cluster today.  We will also cover some high level tips for dealing with virtual box.  This will be good information and the type of stuff I would have like to have known heading into setting up a Virtual Lab.</p>
<p>Season Cleaning First.</p>
<ul>
<ul>
<li><a href="http://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/">Domain Setup</a> – 11<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/22/on-the-tenth-day/">Virtual Storage</a> – 10<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">Death and Destruction, err Deadlocks</a> &#8211; 9<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">SSRS Schedules</a> – 8<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">Runaway Jobs</a> – 7<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> – 6<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> – 5<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> – 4<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> – 3<sup>rd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> – 2<sup>nd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> – 1<sup>st</sup> Day</li>
</ul>
</ul>
<h3>On the Twelfth Day of pre-Christmas…</h3>
<p style="text-align: center;">My DBA brought to me a Virtual SQL Cluster.  And with that cluster, we have a a few tidbits for Using VirtualBox.</p>
<p>The first tidbit is an administration aid.  Occasionally it is good to have similar machines grouped together.  At the same time, it is also necessary to start multiple virtual machines at the same time.  This is done through groups in VirtualBox.</p>
<p>Here you can see some of the groups that I have created.  If I right-click on a machine name, I will be presented a menu that has the Group option.</p>
<p><a style="color: #ff4500; line-height: 15.600000381469727px; text-align: center;" href="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups.png"><img loading="lazy" class="size-full wp-image-1929 aligncenter" title="vb_groups" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups.png" alt="" width="216" height="376" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups.png 216w, https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups-172x300.png 172w" sizes="(max-width: 216px) 85vw, 216px" /></a></p>
<p>Once I have a group created, I can get a few different options if I were to highlight the group name I would get different options as shown in the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups2.png"><img loading="lazy" class="aligncenter size-full wp-image-1930" title="vb_groups2" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups2.png" alt="" width="297" height="409" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups2.png 297w, https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_groups2-217x300.png 217w" sizes="(max-width: 297px) 85vw, 297px" /></a>The notable options here are to &#8220;Ungroup&#8221;, &#8220;Rename Group&#8221;, and &#8220;Add Machine.&#8221;  Another option is &#8220;Start.&#8221;  Though this option is present for the machine menu, the behavior is different.  This option allows you to start the entire group.  This can be a handy tool when dealing with a cluster for instance.</p>
<p>The next handy tidbit is the snapshot.  A snapshot allows point in time image of the VM to be taken so different configurations can be tested &#8211; and then quickly reverted i necessary.  Here is what I have for one of my VMs in the snapshot manager.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/snapshot.png"><img loading="lazy" class="aligncenter  wp-image-1932" title="snapshot" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/snapshot.png" alt="" width="539" height="165" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/snapshot.png 770w, https://jasonbrimhall.info/wp-content/uploads/2012/12/snapshot-300x91.png 300w" sizes="(max-width: 539px) 85vw, 539px" /></a>From this very same screen you can also see one of the many methods available to create a clone of a virtual machine.  The clone icon is the little button above the right hand pane that looks like a sheep.  Cloning a VM is a quick way to create several machines for various purposes.  As you will hear from many people &#8211; you should build a base image first, then run sysprep against it.  Sysprep is necessary in order to help prevent problems down the road.</p>
<p style="text-align: left;">The next tidbit for today is in regards to the file locations for virtual machines and virtual disks.  I recommend changing the default path for the VM files.  This can be done through the preferences option on the file menu.  Shown in the attachment is what it may look like if you have not changed it.  Notice that the default path goes to your user profile directory.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_preferences.png"><img loading="lazy" class="aligncenter size-full wp-image-1933" title="vb_preferences" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_preferences.png" alt="" width="480" height="443" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_preferences.png 480w, https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_preferences-300x276.png 300w" sizes="(max-width: 480px) 85vw, 480px" /></a>Ignore the red text on this page for now.  We will not be discussing the Proxy.</p>
<p style="text-align: left;">The last tip is in the network settings within the preferences that we already have open.  In the network settings, we can find an option to configure DHCP settings for the Host-Only Ethernet Adapter.  These are settings you may want to configure to ensure you have more control over the environment.  It is also helpful when looking to configure those IP settings for the FreeNAS that we have already discussed.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/host-only_adapter.png"><img loading="lazy" class="aligncenter size-full wp-image-1934" title="host-only_adapter" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/host-only_adapter.png" alt="" width="434" height="255" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/host-only_adapter.png 434w, https://jasonbrimhall.info/wp-content/uploads/2012/12/host-only_adapter-300x176.png 300w" sizes="(max-width: 434px) 85vw, 434px" /></a>As I wrap up these tidbits, I have decided that this is a lot of information to soak in at this point.  So in the spirit of Christmas, I have decided to finish off the clustering information in a 13th day post.  This final post may or may not be available on Christmas day.  Worst case it will be available on the 26th.</p>
<p style="text-align: left;">Part of that reason is I want to rebuild my lab following the instructions I will be posting and I need time to test it.  I want the instructions to be of great use.</p>
<p style="text-align: left;">Please stay tuned as we conclude this series very soon.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1925" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/24/on-the-twelfth-day/">On the Twelfth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/24/on-the-twelfth-day/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>On the Eleventh Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-eleventh-day</link>
					<comments>https://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 24 Dec 2012 05:03:36 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Lab]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1906</guid>

					<description><![CDATA[<p>Yesterday we had an introduction into setting up a virtual lab to help the DBA learn and test new technologies while improving his/her own skill set. Today we will continue to discuss the building of [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/">On the Eleventh Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift3.png"><img loading="lazy" class="alignleft size-full wp-image-1912" title="gift3" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift3.png" alt="" width="256" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/gift3.png 256w, https://jasonbrimhall.info/wp-content/uploads/2012/12/gift3-150x150.png 150w" sizes="(max-width: 256px) 85vw, 256px" /></a></p>
<p>Yesterday we had an introduction into setting up a virtual lab to help the DBA learn and test new technologies while improving his/her own skill set.</p>
<p>Today we will continue to discuss the building of a virtual lab.  Today we will get a little closer to the SQL portion of things as we will be installing a familiar operating system to SQL Server.</p>
<p>The Operating System will be 2008.  And the version of SQL Server will be 2008 R2.  I chose these specifically because at the time that I built out my lab, I was setting up the environment to help me study for the MCM exams.</p>
<p>As a sidebar, I was just informed by a friend of another blog series that is also currently discussing setting up Virtual Machines in Virtual Box.  Fortunately, his series is based on Windows 2012 and SQL 2012 &#8211; so there is a bit of a difference.  The author of that series is Matt Velic and you can read his articles on the topic <a href="https://web.archive.org/web/20120626023250/http://mattvelic.com:80/category/sql-server/virtualization-series/">here</a>.</p>
<p>I&#8217;ll be honest, upon hearing that news I had to go check out his articles to make sure I wasn&#8217;t doing the exact same thing.  And while there may be a little overlap, it looks like we have different things that we are covering.</p>
<p>And now that brings us to recap time.</p>
<ul>
<ul>
<li><a href="http://jasonbrimhall.info/2012/12/22/on-the-tenth-day/">Virtual Storage</a> &#8211; 10<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">Death and Destruction, err Deadlocks</a> &#8211; 9<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">SSRS Schedules</a> – 8<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">Runaway Jobs</a> – 7<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> – 6<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> – 5<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> – 4<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> – 3<sup>rd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> – 2<sup>nd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> – 1<sup>st</sup> Day</li>
</ul>
</ul>
<h3>On the Eleventh Day of pre-Christmas…</h3>
<p>The next pre-requisite for this lab is to install a Domain Controller and Active Directory.  For this Domain Controller, I have the following Virtual Box settings.</p>
<ul>
<li>A single Dynamic Virtual Disk of 20GB</li>
<li>2 Network Adapters (1 NAT and 1 Internal)</li>
<li>1024 MB memory</li>
</ul>
<p>To install the operating system, we will mount the iso image the same as we did for the FreeNAS in yesterdays post.  This is a Windows setup, and I will not cover that.</p>
<p>Once you have installed the operating system, the first thing to do is to install the guest additions for Virtual Box.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/guestadditions.png"><img loading="lazy" class="aligncenter size-full wp-image-1918" title="guestadditions" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/guestadditions.png" alt="" width="530" height="288" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/guestadditions.png 530w, https://jasonbrimhall.info/wp-content/uploads/2012/12/guestadditions-300x163.png 300w" sizes="(max-width: 530px) 85vw, 530px" /></a>With guest additions installed, next we will turn to the network adapters.  I have two adapters installed for good reason.  One adapter is visible to the virtual network and will be used for the VMs to talk to each other.  The second adapter is installed so I can get windows validated and so patches can be downloaded and installed.</p>
<p>Talking about patches, this is where we want to make sure the operating system is patched.  Run windows update, finish all of the requisite reboots, and then come back to the network control panel.  Prior to installing the domain, disable the external NIC.  We will do this to limit the potential for errors when joining the subsequent machines to the domain.</p>
<p>For the Internal adapter, I will also configure a static IP address as shown here.</p>
<p><a style="color: #ff4500; line-height: 15.600000381469727px; text-align: center;" href="http://jasonbrimhall.info/wp-content/uploads/2012/12/DC_ipconfig.png"><img loading="lazy" class="aligncenter  wp-image-1919" title="DC_ipconfig" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/DC_ipconfig.png" alt="" width="464" height="311" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/DC_ipconfig.png 663w, https://jasonbrimhall.info/wp-content/uploads/2012/12/DC_ipconfig-300x200.png 300w" sizes="(max-width: 464px) 85vw, 464px" /></a></p>
<p>Let&#8217;s now setup the domain and domain controller on this machine.  From Server Manager, right click roles and select Add Roles.  From the new screen, select Active Directory Domain Services and DNS Server.</p>
<p>You are now ready to configure your domain.  I am going to allow you to use your favorite resource for the directions on configuring a domain in Windows 2008.  After the domain has been configured, then enable the external network adapter.</p>
<p>The final step is to configure DNS.  The main concern in DNS to configure is the reverse lookup zones.  I have three subnets (network address ranges) that I will configure.  The relevance of these three zones will become apparent in the final article of the lab setup mini-series.  The configurations will be along the lines as seen in this next screenshot.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/reverse_lookup.png"><img loading="lazy" class="aligncenter  wp-image-1922" title="reverse_lookup" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/reverse_lookup.png" alt="" width="495" height="337" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/reverse_lookup.png 707w, https://jasonbrimhall.info/wp-content/uploads/2012/12/reverse_lookup-300x204.png 300w" sizes="(max-width: 495px) 85vw, 495px" /></a>This gets us to where we can start building our SQL Cluster.  We will cover that in the next installment.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1906" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/">On the Eleventh Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/23/on-the-eleventh-day/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>On the Tenth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/22/on-the-tenth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-tenth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/22/on-the-tenth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 22 Dec 2012 20:13:37 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Lab]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[Training]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VirtualBox]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1882</guid>

					<description><![CDATA[<p>Silver and Gold have a way of really bringing the look and feel of the Christmas season. Silver and Gold also seem to represent something of greater value. We are now into the final three [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/22/on-the-tenth-day/">On the Tenth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2012/12/candle_ornaments_gold.png"><img loading="lazy" class="alignleft  wp-image-1883" title="candle_ornaments_gold" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/candle_ornaments_gold.png" alt="" width="346" height="258" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/candle_ornaments_gold.png 384w, https://jasonbrimhall.info/wp-content/uploads/2012/12/candle_ornaments_gold-300x224.png 300w" sizes="(max-width: 346px) 85vw, 346px" /></a></p>
<p>Silver and Gold have a way of really bringing the look and feel of the Christmas season.</p>
<p>Silver and Gold also seem to represent something of greater value.</p>
<p>We are now into the final three articles of the 12 Days of pre-Christmas.  And with these three articles, I hope to bring something that is of more value than anything shared so far.</p>
<p>Of course, the value of these articles is subjective.  I have my opinion as to why these are more valuable.  I hope to convey that opinion as best as possible to help bring out as much value as can be garnered from these articles.</p>
<p>Let&#8217;s first recap what we have to date.</p>
<ul>
<ul>
<li><a href="http://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">Death and Destruction, err Deadlocks</a> &#8211; 9<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">SSRS Schedules</a> – 8<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">Runaway Jobs</a> – 7<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> – 6<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> – 5<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> – 4<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> – 3<sup>rd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> – 2<sup>nd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> – 1<sup>st</sup> Day</li>
</ul>
</ul>
<h3>On the Tenth Day of pre-Christmas…</h3>
<p>My DBA gave me an education.  Sure, everyday so far in this series could possibly be an education.  This is an education via a lab.  Every DBA should have a lab to be able to test features and hone skills.  A lab is a better place to do some of the testing that needs done than the DEV, QA, or even Production environments.</p>
<p>Think about it, do we really want to be testing the setup of clustering in the DEV environment and potentially impact the development cycle?  I&#8217;d dare so no.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/datalab.png"><img loading="lazy" class="alignright size-full wp-image-1886" title="datalab" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/datalab.png" alt="" width="277" height="290" /></a>Unfortunately, reality does not always allow for a lab environment to be accessible to the DBA.  So the DBA needs to make do with other means.  It is due to these types of constraints, that I am devoting the next three days to the setup of a lab.  This lab can even be created on a laptop.  I created this lab on my laptop with only 8GB of ram.  I was quite pleased to see that it performed well enough for my testing purposes.</p>
<p>We will begin with an introduction to the technology used &#8211; VirtualBox.  I will also discuss the creation of enough virtual machines to create a SQL Cluster (domain controller, two sql boxes, and a NAS) along with the configuration steps to ensure it will work.</p>
<p>For this lab, we will be using Virtual Box.  You can download Virtual Box <a href="https://www.virtualbox.org/wiki/Downloads" class="broken_link">here</a>.  And yes, the tool is one that is provided by Oracle.  Two of the reasons I want to use Virtual Box is the ability to install multiple operating systems, and the tool is currently free.  Another benefit is that I can easily import virtual machines created in VMWare as well as Microsoft Virtual Server/Virtual PC (I have not tested any created in Hyper-V).</p>
<p>While you are downloading the Virtual Box app, download the Extension Pack as well.  Links are provided for the extension pack on the same page as the application download.  Be sure to download the Extension Pack for the version of Virtual Box you download.</p>
<p>The version of VirtualBox I will be using for this article is 4.2.2.  As of the writing of this article a new version has been released &#8211; 4.2.6.  The differences in versions may cause the instructions in these articles to be inaccurate for 4.2.6.  You can use whichever version you deem appropriate.  I just won&#8217;t be covering version 4.2.6 and don&#8217;t know if the screens are different or it the settings are different.</p>
<p>You can check your version in the Help.About Menu.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_about.png"><img loading="lazy" class="aligncenter  wp-image-1890" title="vb_about" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/vb_about.png" alt="" width="523" height="414" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_about.png 654w, https://jasonbrimhall.info/wp-content/uploads/2012/12/vb_about-300x237.png 300w" sizes="(max-width: 523px) 85vw, 523px" /></a>For this lab, we have a few things that will be required prior to setting up the SQL Cluster.  Two big components of this infrastructure are Storage and a Domain.  We are going to simulate shared storage through the use of FreeNAS.  We will be discussing FreeNAS today.</p>
<p style="text-align: left;">For starters, we can download FreeNAS from <a href="http://www.freenas.org/">here</a>.  You might be able to find a few configuration guides online for FreeNAS.  Most of them seemed to be for really old versions and were less than usable for the version that I had downloaded.  All settings to be discussed today are pertinent to FreeNAS-8.3.0-RELEASE-x64 (r12701M).</p>
<p style="text-align: left;">To setup FreeNAS, we will need to have a Virtual Machine configured with the following settings.</p>
<ul>
<li>A BSD VM with FreeBSD as the version.</li>
<li>Ensure the motherboard settings only has the &#8220;Enable IO APIC&#8221; setting checked.</li>
<li>Three Virtual Disks (1 for NAS OS, 1 for SAN Storage, and another for a Quorum)</li>
<li>512 MB memory</li>
<li>2 Network Adapters (1 Internal and 1 connected to the Host-Only Adapter)</li>
</ul>
<p>Despite the FreeNAS actual disk requirements being rather small, any fixed disk size less than 2GB causes mount errors.  Any amount of memory less than 512MB also causes a mount problem.  These settings are the minimum configurations to save the hair on your head.</p>
<p>The Network Adapters is more of a strong suggestion.  I was able to get it to work with only one adapter, but it was more hassle than it was worth.  I found it easier to configure for use by the cluster later if I had two adapters.  The two adapter configuration also allows me easier administration from within the VM environment as well as from the host machine.</p>
<p>One other thing to do is to mount the FreeNAS ISO that has been downloaded to the CD drive that is created by default with the VM creation.  I mount the ISO before booting by opening the settings for the VM within Virtual Box.  On the storage screen, highlight the &#8220;Empty&#8221; CD Icon in the middle then click on the CD Menu Icon on the far right as shown below.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_MountISO.png"><img loading="lazy" class="aligncenter size-full wp-image-1892" title="FreeNAS_MountISO" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_MountISO.png" alt="" width="657" height="482" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_MountISO.png 657w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_MountISO-300x220.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>Navigate to the folder where the FreeNAS ISO is saved and then click ok until you are back at the Virtual Box manager screen.  You are now ready to start the machine and finish the install and then configure.</p>
<p>Once powered on, you should eventually come to the following screen.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_Install.png"><img loading="lazy" class="aligncenter  wp-image-1893" title="FreeNas_Install" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_Install.png" alt="" width="507" height="331" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_Install.png 724w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_Install-300x195.png 300w" sizes="(max-width: 507px) 85vw, 507px" /></a>Select to Install/Upgrade.  From here, you will see a few more prompts such as the next screen to select the installation location.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_SelectHD.png"><img loading="lazy" class="aligncenter  wp-image-1894" title="FreeNas_SelectHD" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_SelectHD.png" alt="" width="510" height="332" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_SelectHD.png 729w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNas_SelectHD-300x195.png 300w" sizes="(max-width: 510px) 85vw, 510px" /></a>This should be pretty straight forward installation options for the IT professional.  I will not cover all of the installation prompts.  Once the install is finished, you will need to reboot the VM and un-mount the installation media.  The system will then come to the following screen.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_console.png"><img loading="lazy" class="aligncenter  wp-image-1895" title="freenas_console" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_console.png" alt="" width="511" height="333" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_console.png 730w, https://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_console-300x195.png 300w" sizes="(max-width: 511px) 85vw, 511px" /></a>Now that we are at the console screen, the next step is to configure the Network Interfaces.  You can see that I have already done this based on the IP addresses seen at the bottom of the screen.  I will leave the configuration of the IP addresses to you.  Both the internal network and the host-only network will need to be configured.  The host network should be the second adapter.  Keep track of the IP addresses that have been configured.  We will need to use them later.</p>
<p style="text-align: left;">In a browser window we will now start configuring the storage to be used by our Lab.  In the address bar, we will need to input the address we configured for the host network.  In my case, 192.168.56.103.  When that page loads, the first thing we need to do is change the Admin password.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_changepw.png"><img loading="lazy" class="aligncenter size-full wp-image-1896" title="freenas_changepw" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_changepw.png" alt="" width="677" height="397" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_changepw.png 677w, https://jasonbrimhall.info/wp-content/uploads/2012/12/freenas_changepw-300x175.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>The default password is empty.  Pick a password you will remember and that is appropriate.  With that done, we can configure the storage.</p>
<p style="text-align: left;">The Next setting, I want to configure is the iSCSI setting.  In order to use the volumes that we create, we must enable the iSCSI service.  In the top section, click the Services button.  This will open a new tab in the web browser.  On the Services tab, we need to toggle the slider for iSCSI to the &#8220;ON&#8221; position as shown in the image.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeSAN_enable_iSCSI.png"><img loading="lazy" class="aligncenter size-full wp-image-1897" title="FreeSAN_enable_iSCSI" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeSAN_enable_iSCSI.png" alt="" width="471" height="272" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeSAN_enable_iSCSI.png 471w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeSAN_enable_iSCSI-300x173.png 300w" sizes="(max-width: 471px) 85vw, 471px" /></a>Once toggled, we can configure the iSCSI settings for the volumes we will now create.  From here, we click on the storage tab.  Next, click on the Volume Manager Button.  In order for the disks to be imported, we have to use volume manager.  The Import Volume and Auto Import Volume must serve other purposes &#8211; but they don&#8217;t work for importing a new volume.  Here is a screenshot demonstrating what needs to be configured.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_VolumeMGR.png"><img loading="lazy" class="aligncenter  wp-image-1916" title="FreeNAS_VolumeMGR" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_VolumeMGR.png" alt="" width="587" height="334" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_VolumeMGR.png 838w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_VolumeMGR-300x170.png 300w" sizes="(max-width: 587px) 85vw, 587px" /></a></p>
<p style="text-align: left;">With the Volume created, a ZFS volume must next be created from within the storage management.  We do this by clicking the &#8220;Create ZFS Volume&#8221; icon next to the main volume we just created.  This icon is illustrated as the icon on the far right in the next image.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/createzfs_volume.png"><img loading="lazy" class="aligncenter  wp-image-1947" title="createzfs_volume" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/createzfs_volume.png" alt="" width="562" height="322" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/createzfs_volume.png 702w, https://jasonbrimhall.info/wp-content/uploads/2012/12/createzfs_volume-300x172.png 300w" sizes="(max-width: 562px) 85vw, 562px" /></a></p>
<p style="text-align: left;">Once that icon is clicked, you will be presented with a new dialog.  The dialog is demonstrated in the above image.  Give the Volume a Name and then give it a size.  Note that you must specify a storage unit (m or g for example) or you will receive a pretty red error message.</p>
<p style="text-align: left;">Now go back to the Services tab where we enabled iSCSI.  There is a wrench icon next to the toggle to enable the service.  Click on this wrench and a new tab will be opened (again within the FreeNAS webgui) and the focus will be switched to this new tab.  On the &#8220;Target Global Configuration&#8221; ensure that Discovery Auth Method is set to &#8220;Auto.&#8221;  If it is not, make the change and click save at the bottom.</p>
<p style="text-align: left;">Next is the Portals.  The portals should be empty so we will need to add a portal.  By default, only one IP address is displayed for configuration on a new Portal entry.  We want to configure two IP addresses.  First, select 0.0.0.0 from the IP Address drop down on the new window that opened when clicking on &#8220;Add Portal.&#8221;  Then select &#8220;Add extra Portal IP&#8221;.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_addportal.png"><img loading="lazy" class="aligncenter  wp-image-1898" title="FreeNAS_addportal" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_addportal.png" alt="" width="502" height="378" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_addportal.png 627w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_addportal-300x226.png 300w" sizes="(max-width: 502px) 85vw, 502px" /></a>Next is to configure an Initiator.  For this lab, I created on Initiator specifying ALL for the Initiators and Authorized Network as shown here.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_initiator.png"><img loading="lazy" class="aligncenter  wp-image-1899" title="FreeNAS_initiator" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_initiator.png" alt="" width="513" height="243" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_initiator.png 733w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_initiator-300x142.png 300w" sizes="(max-width: 513px) 85vw, 513px" /></a>With an initiator and a portal in place, we now proceed to the configuration of the Targets.  I have configured three targets and the main difference is in the name.  They should be configured as shown here.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_Targets.png"><img loading="lazy" class="aligncenter  wp-image-1900" title="FreeNAS_Targets" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_Targets.png" alt="" width="493" height="303" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_Targets.png 704w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_Targets-300x184.png 300w" sizes="(max-width: 493px) 85vw, 493px" /></a>Almost done with the setup for the storage.  It will all be well worth it when we are done.  We need to configure Device Extents and then Associate the targets, then we will be done.</p>
<p style="text-align: left;">Like with the Targets, I have three device extents configured.  The configuration for each is the same process.  I want to give each a name that is meaningful and then associate the extent to a disk that we imported earlier.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_extents.png"><img loading="lazy" class="aligncenter  wp-image-1901" title="FreeNAS_extents" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_extents.png" alt="" width="494" height="259" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_extents.png 618w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_extents-300x157.png 300w" sizes="(max-width: 494px) 85vw, 494px" /></a>Last for this setup is the Target to Extent association.  This a pretty straight forward configuration.  I named my targets the same as extents so there was no confusion as to which should go with which.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_TargetExtent.png"><img loading="lazy" class="aligncenter size-full wp-image-1902" title="FreeNAS_TargetExtent" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_TargetExtent.png" alt="" width="329" height="305" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_TargetExtent.png 329w, https://jasonbrimhall.info/wp-content/uploads/2012/12/FreeNAS_TargetExtent-300x278.png 300w" sizes="(max-width: 329px) 85vw, 329px" /></a>That wraps up the configurations needed to get the storage working so we can configure a cluster later on.  Just getting through this configuration is a pretty big step in getting the lab created for use in your studies and career enhancement.</p>
<p style="text-align: left;">Next up in this series is to show how to configure (in limited detail) a domain and DNS, and then to install and configure a cluster.  Stay tuned and I will even through in a few tidbits here and there about Virtual Box.</p>
<p style="text-align: left;">I didn&#8217;t include every screenshot possible throughout the setup of FreeNAS and the configuration of iSCSI.  Part of the fun and education of a lab is troubleshooting and learning as you go.  If you run into issues, I encourage you to troubleshoot and research.  It will definitely strengthen your skill-set.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1882" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/22/on-the-tenth-day/">On the Tenth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/22/on-the-tenth-day/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>On the Ninth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/21/on-the-ninth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-ninth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/21/on-the-ninth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 21 Dec 2012 09:30:44 +0000</pubDate>
				<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Database Performance]]></category>
		<category><![CDATA[Management Data Warehouse]]></category>
		<category><![CDATA[MDW]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<category><![CDATA[XE]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1868</guid>

					<description><![CDATA[<p>Creating a custom data collector can be very handy for a DBA.  Especially in times of troubleshooting.  These collectors are also quite useful for trending and analysis.  Consider this a tool in the chest for the poor man.</p>
The post <a href="https://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">On the Ninth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignright wp-image-1869" title="mayan-calendar1" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/mayan-calendar1.jpg" alt="" width="336" height="224" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/mayan-calendar1.jpg 480w, https://jasonbrimhall.info/wp-content/uploads/2012/12/mayan-calendar1-300x200.jpg 300w" sizes="(max-width: 336px) 85vw, 336px" /></p>
<p><a href="http://www.youtube.com/watch?v=u2UhvN0k74w">It&#8217;s the end of the world as we know it</a>.  And as the song goes&#8230;I feel fine!  But hey, <a href="http://www.youtube.com/watch?v=eFTLKWw542g">we didn&#8217;t start the fire</a>.</p>
<p>Those are a couple of songs that pop into my head every time somebody starts talking doomsday and doomsday prophecies.</p>
<p>If you are reading this, I dare say that the world is still turning.  And that is a good thing because that gives us a chance to talk about the 12 days of pre-Christmas.</p>
<p>Today we will be talking about a tool that can be at the DBAs disposal to help in tracking performance as well as problems.</p>
<p>First there are a couple of items of housekeeping.  First item is that I only realized with this post that the post on the first day was wrong.  I had miscalculated my twelve days to end on Christmas day.  That is wrong!  Counting down from that first post on the 13th means the 12th day will end up on December 24th.  Maybe I will throw in a bonus 13th day post, or delay a post for a day, or just go with it.  It will be a mystery!</p>
<p>Second item is naturally the daily recap of the 12 days to date.</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">SSRS Schedules</a> – 8<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">Runaway Jobs</a> – 7<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> – 6<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> – 5<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> – 4<sup>th</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> – 3<sup>rd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> – 2<sup>nd</sup> Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> – 1<sup>st</sup> Day</li>
</ul>
</li>
</ul>
<h3>On the Ninth Day of pre-Christmas…</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/Candy-Canes.jpg"><img loading="lazy" class="aligncenter size-full wp-image-1875" title="Candy-Canes" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/Candy-Canes.jpg" alt="" width="480" height="320" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/Candy-Canes.jpg 480w, https://jasonbrimhall.info/wp-content/uploads/2012/12/Candy-Canes-300x200.jpg 300w" sizes="(max-width: 480px) 85vw, 480px" /></a>My DBA gave to me a Data Collection!</p>
<p>If only my DBA had told me that I would need to have Management Data Warehouse (MDW) preconfigured.  Well, that is not a problem.  We can handle that too.  For a tutorial on how to setup MDW, I am going to provide a <a href="http://msdn.microsoft.com/en-us/library/dd939169(v=sql.100).aspx">link </a>to one that has been very well written by Kalen Delaney.</p>
<p>The article written by Kalen covers the topic of MDW very well all the way from setting up the MDW, to setting up the Data Collectors, and all the way down to the default reports you can run for MDW.  The MDW and canned Data Collectors can provide some really useful information for your environment.</p>
<p>What I want to share though is a means to add custom data collections to your MDW.  To create a custom collection, we need to rely on two stored procedures provided to us by Microsoft.  Those stored procedures are: <a href="http://msdn.microsoft.com/en-us/library/bb677286(v=sql.105).aspx">sp_syscollector_create_collection_item </a>and <a href="http://msdn.microsoft.com/en-us/library/bb677291(v=sql.105).aspx">sp_syscollector_create_collection_set</a>.  Both of these stored procedures are found in the, you guessed it, msdb database.</p>
<p>Each of these stored procedures has a number of parameters to help in the creation of an appropriate data collection.  When creating a data collection, you will first create the collection set, and then you add collection items to that set.</p>
<p>There are a few notable parameters for each stored procedure that I will cover.  Otherwise, you can refer back to the links for each of the stored procedures to see more information about the parameters.</p>
<p>Starting with the sp_syscollector_create_collection_set stored procedure, I want to point out the @schedule_name, @name, and @collection_mode parameters.  The name is pretty obvious &#8211; make sure you have a distinguishable name that is descriptive (my opinion) or at least have good documentation.  The collection mode has two values.  As noted in the documentation, you will want to choose one value over the other depending on the intended use of this data collector.  If running continuously, just remember to run in cached mode.  And lastly is the schedule name.  This will help determine how frequently the job runs.</p>
<p>Unfortunately, the schedule names are not found in the documentation, but rather you are directed to query the sysschedules tables.  To help you find those schedules, here is a quick query.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT schedule_id,name
	FROM dbo.sysschedules
	WHERE name LIKE '%collector%';</pre><p>Now on to the sp_syscollector_create_collection_item stored procedure.  There are three parameters that I want to lightly touch on.  For the rest, you can refer back to the documentation.  The parameters of interest here are @parameters, @frequency and @collector_type_uid.  Starting with the frequency parameter, this tells the collector how often to upload the data to the MDW if running in cached mode.  Be careful here to select an appropriate interval.  Next is the parameters parameter which is really the workhorse of the collection item.  In the case of the custom data collector that I will show in a bit, this is where the tsql query will go.</p>
<p>Last parameter to discuss is the collector type uid.  Like the schedule for the previous proc, the documentation for this one essentially refers you to a system view &#8211; syscollector_collector_types.  Here is a quick query to see the different collector types.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT name
	FROM syscollector_collector_types;</pre><p>The collector type that I will be using for this example is Generic T-SQL Query Collector Type.  A discussion on the four types of collectors can be reserved for another time.</p>
<p>Let&#8217;s move on to the example now.  This custom data collector is designed to help troubleshoot deadlock problems.  The means I want to accomplish this is by querying the system_health extended event session.</p>
<p>I can query for deadlock information direct to the system_health session using a query like the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT CAST(
                  REPLACE(
                        REPLACE(XEventData.XEvent.value('(data/value)[1]', 'varchar(max)'), 
                        '', ''),
                  '','')
            AS varchar(4000)) AS DeadlockGraph
FROM
(SELECT CAST(target_data AS XML) AS TargetData
from sys.dm_xe_session_targets st
join sys.dm_xe_sessions s on s.address = st.event_session_address
where name = 'system_health') AS Data
CROSS APPLY TargetData.nodes ('//RingBufferTarget/event') AS XEventData (XEvent)
where XEventData.XEvent.value('@name', 'varchar(4000)') = 'xml_deadlock_report';</pre><p>You may notice that I have converted to varchar(4000) from XML.  This is in large part to make sure the results will play nicely with the data collector.  Now to convert that to a query that can be used in the @parameters parameter, we get the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;ns:TSQLQueryCollector xmlns:ns="DataCollectorType"&gt;&lt;Query&gt;&lt;Value&gt;

SELECT CAST(
                  REPLACE(
                        REPLACE(XEventData.XEvent.value(''(data/value)[1]'', ''varchar(max)''), 
                        '''', ''''),
                  '''','''')
            AS varchar(4000)) AS DeadlockGraph
FROM
(SELECT CAST(target_data AS XML) AS TargetData
from sys.dm_xe_session_targets st
join sys.dm_xe_sessions s on s.address = st.event_session_address
where name = ''system_health'') AS Data
CROSS APPLY TargetData.nodes (''//RingBufferTarget/event'') AS XEventData (XEvent)
where XEventData.XEvent.value(''@name'', ''varchar(4000)'') = ''xml_deadlock_report'' 

&lt;/Value&gt;&lt;OutputTable&gt;systemhealthdeadlock&lt;/OutputTable&gt;&lt;/Query&gt;&lt;/ns:TSQLQueryCollector&gt;</pre><p>With this query, we are loading the necessary schema nodes that correlate to the Data Collector Type that we chose.  Since this parameter is XML, the schema must match or you will get an error.  We are now ready to generate a script that can create a deadlock data collector.</p><pre class="urvanov-syntax-highlighter-plain-tag">Begin Transaction
Begin Try
Declare @collection_set_id_1 int
Declare @collection_set_uid_2 uniqueidentifier
EXEC [msdb].[dbo].[sp_syscollector_create_collection_set]
	  @name=N'systemhealthdeadlock'
	, @collection_mode=1
	, @description=N'systemhealthdeadlock'
	, @logging_level=1
	, @days_until_expiration=14
	, @schedule_name=N'CollectorSchedule_Every_15min'
	, @collection_set_id=@collection_set_id_1 OUTPUT
	, @collection_set_uid=@collection_set_uid_2 OUTPUT

Select @collection_set_id_1, @collection_set_uid_2

Declare @collector_type_uid_3 uniqueidentifier
Select @collector_type_uid_3 = collector_type_uid 
	From [msdb].[dbo].[syscollector_collector_types] 
	Where name = N'Generic T-SQL Query Collector Type';

Declare @collection_item_id_4 int
EXEC [msdb].[dbo].[sp_syscollector_create_collection_item]
	  @name=N'systemhealthdeadlock'
	, @parameters=N'&lt;ns:TSQLQueryCollector xmlns:ns="DataCollectorType"&gt;&lt;Query&gt;&lt;Value&gt;

SELECT CAST(
                  REPLACE(
                        REPLACE(XEventData.XEvent.value(''(data/value)[1]'', ''varchar(max)''), 
                        '''', ''''),
                  '''','''')
            AS varchar(4000)) AS DeadlockGraph
FROM
(SELECT CAST(target_data AS XML) AS TargetData
from sys.dm_xe_session_targets st
join sys.dm_xe_sessions s on s.address = st.event_session_address
where name = ''system_health'') AS Data
CROSS APPLY TargetData.nodes (''//RingBufferTarget/event'') AS XEventData (XEvent)
where XEventData.XEvent.value(''@name'', ''varchar(4000)'') = ''xml_deadlock_report'' 

&lt;/Value&gt;&lt;OutputTable&gt;systemhealthdeadlock&lt;/OutputTable&gt;&lt;/Query&gt;&lt;/ns:TSQLQueryCollector&gt;'
	, @collection_item_id=@collection_item_id_4 OUTPUT
	, @frequency=30
	, @collection_set_id=@collection_set_id_1
	, @collector_type_uid=@collector_type_uid_3

Select @collection_item_id_4

Commit Transaction;
End Try
Begin Catch
Rollback Transaction;
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
DECLARE @ErrorNumber INT;
DECLARE @ErrorLine INT;
DECLARE @ErrorProcedure NVARCHAR(200);
SELECT @ErrorLine = ERROR_LINE(),
       @ErrorSeverity = ERROR_SEVERITY(),
       @ErrorState = ERROR_STATE(),
       @ErrorNumber = ERROR_NUMBER(),
       @ErrorMessage = ERROR_MESSAGE(),
       @ErrorProcedure = ISNULL(ERROR_PROCEDURE(), '-');
RAISERROR (14684, @ErrorSeverity, 1 , @ErrorNumber, @ErrorSeverity, @ErrorState, @ErrorProcedure, @ErrorLine, @ErrorMessage);

End Catch;

GO</pre><p>Upon creation, this will create a SQL Agent job with the defined schedule.  Since this is a non-cached data collector set, the Agent job will adhere to the schedule specified and upload data on that interval.</p>
<p>Now all we need to do is generate a deadlock to see if it is working.  It is also a good idea to introduce you to the table that will be created due to this data collector.  Once we create this collector set, a new table will be created in the MDW database.  In the case of this collector set, we have a table with the schema and name of custom_snapshots.systemhealthdeadlock.</p>
<p>This new table will have three columns.  One column represents the DeadlockGraph as we retrieved from the query we provided to the @parameters parameter.  The remaining columns are data collector columns for the collection date and the snapshot id.</p>
<p>Now that we have covered all of that, your favorite deadlock query has had enough time to finally fall victim to a deadlock.  We should also have some information recorded in the custom_snapshots.systemhealthdeadlock table relevant to the deadlock information (if not, it will be there once the agent job runs, or you can run a snapshot from SSMS of the data collector).  With a quick query, we can start looking into the deadlock problem.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT collection_time,CAST(DeadlockGraph AS XML) AS DeadlockGraph, snapshot_id
	FROM mdw.custom_snapshots.systemhealthdeadlock;</pre><p>This query will give me a few entries (since I went overkill and created a bunch of deadlocks).  If I click the DeadlockGraph cell in the result sets, I can then view the XML of the DeadlockGraph, as in the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;deadlock&gt;
  &lt;victim-list&gt;
    &lt;victimProcess id="process5a4ebc8" /&gt;
  &lt;/victim-list&gt;
  &lt;process-list&gt;
    &lt;process id="process5a4ebc8" taskpriority="0" logused="0" waitresource="KEY: 26:72057594048020480 (b4903b2250cc)" waittime="609" ownerId="2803145" transactionname="user_transaction" lasttranstarted="2012-12-20T22:32:09.987" XDES="0x8008d950" lockMode="X" schedulerid="8" kpid="13656" status="suspended" spid="87" sbid="0" ecid="0" priority="0" trancount="4" lastbatchstarted="2012-12-20T22:38:50.020" lastbatchcompleted="2012-12-20T22:38:50.020" lastattention="2012-12-20T22:38:24.217" clientapp="Microsoft SQL Server Management Studio - Query" hostname="SomeServer" hostpid="7604" loginname="SomeLogin" isolationlevel="serializable (4)" xactid="2803145" currentdb="26" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200"&gt;
      &lt;executionStack&gt;
        &lt;frame procname="" line="10" stmtstart="40" sqlhandle="0x02000000eac1af36f412db4e21d9dcc86feb261fa6bcd230" /&gt;
        &lt;frame procname="" line="10" stmtstart="356" stmtend="518" sqlhandle="0x0200000095b4ee32a25e9724dd73fd6894c60748af6c136b" /&gt;
      &lt;/executionStack&gt;
      &lt;inputbuf&gt;
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
WHILE 1=1 
BEGIN 
BEGIN TRAN
UPDATE Purchasing.Vendor
SET CreditRating = 2
WHERE BusinessEntityID = 1492;

UPDATE Purchasing.Vendor
SET CreditRating = 1
WHERE BusinessEntityID = 1494;

COMMIT TRAN 
END
   &lt;/inputbuf&gt;
    &lt;/process&gt;
    &lt;process id="process5a44bc8" taskpriority="0" logused="0" waitresource="KEY: 26:72057594048020480 (ade87e3a717c)" waittime="609" ownerId="2878446" transactionname="user_transaction" lasttranstarted="2012-12-20T22:38:50.020" XDES="0xa9abd950" lockMode="X" schedulerid="7" kpid="15008" status="suspended" spid="86" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2012-12-20T22:38:47.887" lastbatchcompleted="2012-12-20T22:38:47.887" lastattention="2012-12-20T22:36:21.247" clientapp="Microsoft SQL Server Management Studio - Query" hostname="SomeServer" hostpid="7604" loginname="SomeLogin" isolationlevel="serializable (4)" xactid="2878446" currentdb="26" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200"&gt;
      &lt;executionStack&gt;
        &lt;frame procname="" line="9" stmtstart="40" sqlhandle="0x02000000eac1af36f412db4e21d9dcc86feb261fa6bcd230" /&gt;
        &lt;frame procname="" line="9" stmtstart="352" stmtend="510" sqlhandle="0x020000000c4b9412577ec884cbd51882e5310dd340216739" /&gt;
      &lt;/executionStack&gt;
      &lt;inputbuf&gt;
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
WHILE 1=1 
BEGIN 
BEGIN TRAN
UPDATE Purchasing.Vendor
SET CreditRating = 1
WHERE BusinessEntityID = 1494;
UPDATE Purchasing.Vendor
SET CreditRating = 2
WHERE BusinessEntityID = 1492;
COMMIT TRAN 
END
   &lt;/inputbuf&gt;
    &lt;/process&gt;
  &lt;/process-list&gt;
  &lt;resource-list&gt;
    &lt;keylock hobtid="72057594048020480" dbid="26" objectname="" indexname="" id="lock5aeec80" mode="X" associatedObjectId="72057594048020480"&gt;
      &lt;owner-list&gt;
        &lt;owner id="process5a44bc8" mode="X" /&gt;
      &lt;/owner-list&gt;
      &lt;waiter-list&gt;
        &lt;waiter id="process5a4ebc8" mode="X" requestType="wait" /&gt;
      &lt;/waiter-list&gt;
    &lt;/keylock&gt;
    &lt;keylock hobtid="72057594048020480" dbid="26" objectname="" indexname="" id="lock6164d80" mode="X" associatedObjectId="72057594048020480"&gt;
      &lt;owner-list&gt;
        &lt;owner id="process5a4ebc8" mode="X" /&gt;
      &lt;/owner-list&gt;
      &lt;waiter-list&gt;
        &lt;waiter id="process5a44bc8" mode="X" requestType="wait" /&gt;
      &lt;/waiter-list&gt;
    &lt;/keylock&gt;
  &lt;/resource-list&gt;
&lt;/deadlock&gt;</pre><p>Code to generate deadlock courtesy of &#8220;<a href="http://www.amazon.com/Server-2012-T-SQL-Recipes-Problem-Solution/dp/1430242000">SQL Server 2012 T-SQL Recipes: A Problem-Solution Approach</a>&#8221; by Jason Brimhall, Wayne Sheffield et al (Chapter 12, pages 267-268).  If you examine the deadlock graph you will see the code that generated the deadlock.</p>
<p>Since this is being pulled from the RingBuffer target of the system_health, it can prove useful to store that data into a table such as I have done.  The reason being that the Ringbuffer can be overwritten, and with good timing on the data collector, we can preserve this information for later retrieval and troubleshooting.  Deadlocks don&#8217;t always happen at the most opportune time and even less likely to occur when we are staring at the screen waiting for them to happen.</p>
<p>As you read more about the stored procedures used to create a data collector, you will see that there is a retention parameter.  This helps prevent the table from getting too large on us.  We can also ensure that an appropriate retention is stored for these custom collectors.</p>
<h3>Conclusion</h3>
<p>Creating a custom data collector can be very handy for a DBA.  Especially in times of troubleshooting.  These collectors are also quite useful for trending and analysis.  Consider this a tool in the chest for the poor man. <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Enjoy and stay tuned!</p>
<p><em>All scripts and references were for SQL 2008 R2.  The Deadlock script was pulled from the 2012 book, but the script runs the same for the 2008 version of the AdventureWorks database.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1868" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/21/on-the-ninth-day/">On the Ninth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/21/on-the-ninth-day/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>On the Eighth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/20/on-the-eighth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-eighth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/20/on-the-eighth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 20 Dec 2012 09:30:05 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[SSRS]]></category>
		<category><![CDATA[SSRS Administration]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1859</guid>

					<description><![CDATA[<p>Today&#8217;s post is merely an illusion.  The illusion being that we have finally stopped talking about the msdb database.  I&#8217;ll explain about that later in this post. This should be a good addition to the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">On the Eighth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/8maids.png"><img loading="lazy" class=" wp-image-1860 alignleft" title="8maids" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/8maids.png" alt="" width="256" height="310" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/8maids.png 320w, https://jasonbrimhall.info/wp-content/uploads/2012/12/8maids-247x300.png 247w" sizes="(max-width: 256px) 85vw, 256px" /></a></p>
<p>Today&#8217;s post is merely an illusion.  The illusion being that we have finally stopped talking about the msdb database.  I&#8217;ll explain about that later in this post.</p>
<p>This should be a good addition to the script toolbox for those Mere Mortal DBAs out there supporting their corporate SSRS environment.  Everybody could use a script now and then that helps them better support their environment and perform their DBA duties, right?</p>
<p>No reading ahead now.  We&#8217;ll get to the script soon enough.  First, we have a bit of business to cover just as we normally do.</p>
<p>We need to quickly recap the first seven days thus far (after all, the song does a recap with each day).</p>
<p>&nbsp;</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/19/on-the-seventh-day/">Runaway Jobs</a> &#8211; 7th Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> &#8211; 6th Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> &#8211; 5th Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> &#8211; 4th Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> &#8211; 3rd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> &#8211; 2nd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> &#8211; 1st Day</li>
</ol>
<h3>On the Eighth Day of pre-Christmas&#8230;</h3>
<p>My DBA gave to me a means to see Report Subscriptions and their schedules.</p>
<p>One of the intriguing points that we find with having a reporting environment is that we also need to report on that reporting environment.  And one of the nuisances of dealing with a Reporting Services Environment is that data like report subscription schedules is not very human friendly.</p>
<p>Part of the issue is that you need to be fluent with math.  Another part of the issue is that you need to be a little familiar with bitwise operations in SQL Server.  That said, it is possible to get by without understanding both very well.  And as a last resort, there is always the manual method of using Report Manager to check the subscriptions for each of the reports that have been deployed to that server.  Though, I think you will find this to be a bit tedious if you have a large number of reports.</p>
<p>I have seen more than one script that provides the schedule information for the subscriptions without using math and just relying on the bitwise operations.  This tends to produce a lot of repetitive code.  The method works, I&#8217;m just not that interested in the repetitive nature employed.</p>
<p>Within SQL Server you should notice that in several tables, views, and processes employ the powers of 2 or base 2 or binary number system.  This is natural since this is so integral within computer science in general.  Powers of 2 translates to binary fairly easily and then integrates so well with bitwise operations.</p>
<p>The following table demonstrates the powers of 2 and conversion to binary.</p>
<table border="0" width="217" cellspacing="0" cellpadding="0">
<colgroup>
<col width="73" />
<col width="64" />
<col width="80" /> </colgroup>
<tbody>
<tr>
<td width="73" height="20">power of 2</td>
<td width="64">value</td>
<td width="80">binary</td>
</tr>
<tr>
<td align="right" height="20">0</td>
<td align="right">1</td>
<td>1</td>
</tr>
<tr>
<td align="right" height="20">1</td>
<td align="right">2</td>
<td>10</td>
</tr>
<tr>
<td align="right" height="20">2</td>
<td align="right">4</td>
<td>100</td>
</tr>
<tr>
<td align="right" height="20">3</td>
<td align="right">8</td>
<td>1000</td>
</tr>
<tr>
<td align="right" height="20">4</td>
<td align="right">16</td>
<td>10000</td>
</tr>
<tr>
<td align="right" height="20">5</td>
<td align="right">32</td>
<td>100000</td>
</tr>
<tr>
<td align="right" height="20">6</td>
<td align="right">64</td>
<td>1000000</td>
</tr>
<tr>
<td align="right" height="20">7</td>
<td align="right">128</td>
<td>10000000</td>
</tr>
<tr>
<td align="right" height="20">8</td>
<td align="right">256</td>
<td>100000000</td>
</tr>
</tbody>
</table>
<p>To get numbers and values between the binary results or the value results listed above is a matter of addition.  We add the value from a power of 2 to another power of 2.  So if I need a value of 7, then I need 2^0 + 2^1 + 2^2.  This results in a binary value of 0111.  Now this is where the need for bit comparisons comes into play so we will use some bitwise operations (read more <a href="http://jasonbrimhall.info/2011/03/10/sql-bitwise-operations/">here</a>) to figure out quickly which values are used to reach an end value of 7 (so I don&#8217;t need to really know a lot of math there <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ).</p>
<h3>How does this Apply to Schedules?</h3>
<p>This background has everything to do with scheduling in SSRS.  Within the ReportServer database, there is a table called Schedule in the dbo schema.  This table has multiple columns that store pieces of the Subscription Schedule.  The three key columns are DaysofWeek, DaysofMonth and Month.  The values stored in these columns are all sums of the powers of 2 necessary to represent multiple days or months.</p>
<p>For instance, you may see the following values</p>
<table border="0" width="228" cellspacing="0" cellpadding="0">
<colgroup>
<col width="87" />
<col width="93" />
<col width="48" /> </colgroup>
<tbody>
<tr>
<td width="87" height="20">DaysOfWeek</td>
<td width="93">DaysOfMonth</td>
<td width="48">Month</td>
</tr>
<tr>
<td align="right" height="20">62</td>
<td align="right">135283073</td>
<td align="right">2575</td>
</tr>
</tbody>
</table>
<p>These values are not friendly to normal every day mere mortal DBAs.  The values from the preceding table are shown below with the human friendly data they represent.</p>
<table border="0" width="711" cellspacing="0" cellpadding="0">
<colgroup>
<col width="299" />
<col width="93" />
<col width="319" /> </colgroup>
<tbody>
<tr>
<td width="299" height="20">DaysOfWeek</td>
<td width="93">DaysOfMonth</td>
<td width="319">Month</td>
</tr>
<tr>
<td align="right" height="20">62</td>
<td align="right">135283073</td>
<td align="right">2575</td>
</tr>
<tr>
<td height="20">Monday,Tuesday,Wednesday,Thursday,Friday</td>
<td>1,8,9,15,21,28</td>
<td>January,February,March,April,October,December</td>
</tr>
</tbody>
</table>
<p>That is better for us to understand, but not necessarily better to store in the database.  So, I hope you can see the value of storing it in a numeric representation that is easily deciphered through math and TSQL.</p>
<p>Without further adieu, we have a script to report on these schedules without too much repetition.</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ReportName VARCHAR(100)
SET @ReportName = NULL;

CREATE TABLE #morepower (MonthDate BIGINT,N BIGINT,PowerN BIGINT PRIMARY KEY CLUSTERED
							,NameofMonth VARCHAR(25),WkDay VARCHAR(25))
;
WITH E1(N) AS ( --=== Create Ten 1's
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 --10
               ),
      E2(N) AS (SELECT 1 FROM E1 a, E1 b),   --100
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT N)) FROM E2  UNION ALL SELECT 0
),powers(powerN,n) AS (SELECT POWER(2,N),N FROM cteTally WHERE N &amp;lt; 31)

INSERT INTO #morepower ( MonthDate ,N,PowerN ,NameofMonth ,WkDay)
	SELECT ROW_NUMBER() OVER (ORDER BY N) AS MonthDate,N,PowerN
			,CASE WHEN N BETWEEN 0 AND 11 
				THEN DateName(month,DATEADD(month,N+1,0)-1)
				ELSE NULL
				END AS NameofMonth
			,CASE WHEN N BETWEEN 0 AND 6
				THEN DATENAME(weekday,DATEADD(DAY,n+1,0)-2)
				ELSE NULL
				END AS WkDay
		FROM powers

SELECT DISTINCT s.ScheduleID,Ca.Path as ReportManagerPath,Ca.Name as ReportName
		, U.UserName as SubscriptionCreator
		,Su.Description as SubscriptionDescription,S.StartDate,Su.LastRunTime
		,case 
			when s.RecurrenceType = 1 then 'One Off'
			when s.RecurrenceType = 2 then 'Hour'
			when s.RecurrenceType = 4 then 'Daily'
			when s.RecurrenceType = 5 then 'Monthly' 
			when s.RecurrenceType = 6 then 'Week of Month' 
		end as RecurrenceType
		,s.EventType
		,ISNULL(STUFF(
				(Select ','+CONVERT(VARCHAR(50),MonthDate) AS [text()] 
					FROM #morepower m1 
					WHERE m1.powerN &amp;lt; s.DaysofMonth+1 
						AND s.DaysofMonth &amp;amp; m1.powerN &amp;lt;&amp;gt;0 
					ORDER BY N FOR XML PATH('')),1,1,''),'N/A') AS DaysofMonth
		,ISNULL(c1.NameOfMonth,'N/A') AS MonthString
		,ISNULL(c2.WkDays,'N/A') AS DaysofWeek
		,CASE MonthlyWeek
				WHEN 1 THEN 'First'
				WHEN 2 THEN 'Second'
				WHEN 3 THEN 'Third'
				WHEN 4 THEN 'Fourth'
				WHEN 5 THEN 'Last'
				ELSE 'N/A'
			END AS MonthlyWeek
		,ISNULL(CONVERT(VARCHAR(10),s.DaysInterval),'N/A') AS DaysInterval
		,ISNULL(CONVERT(VARCHAR(10),s.MinutesInterval),'N/A') AS MinutesInterval
		,ISNULL(CONVERT(VARCHAR(10),s.WeeksInterval),'N/A') AS WeeksInterval
	FROM #morepower mp, dbo.Schedule s
		INNER JOIN ReportSchedule RS
			ON S.ScheduleID = RS.ScheduleID
		INNER JOIN Catalog Ca
			ON Ca.ItemID = RS.ReportID
		INNER JOIN Subscriptions Su
			ON Su.SubscriptionID = RS.SubscriptionID
		INNER JOIN Users U
			ON U.UserID = S.CreatedById
			OR U.UserID = Su.OwnerID
	CROSS APPLY (Select s.ScheduleID,STUFF(
							(SELECT ','+NameofMonth AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s1
								WHERE m1.NameofMonth IS NOT NULL 
									AND m1.powerN &amp;amp; s1.Month &amp;lt;&amp;gt;0 
									AND s1.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH('')),1,1,'') AS NameOfMonth)c1
	CROSS APPLY (SELECT s.ScheduleID,STUFF(
							(SELECT ','+WkDay AS [text()] 
								FROM #morepower m1 ,dbo.Schedule s2
								WHERE m1.WkDay IS NOT NULL 
									AND DaysOfWeek &amp;amp; m1.powerN &amp;lt;&amp;gt;0
									AND  s2.ScheduleID = s.ScheduleID
								ORDER BY N FOR XML PATH('')),1,1,'') AS WkDays) c2
	WHERE Ca.Name = ISNULL(@ReportName,Ca.Name);

DROP TABLE #morepower;</pre><p>Consider this as V1 of the script with expected changes coming forth.</p>
<p>I have set this up so a specific report name can be provided or not.  If not provided, the query will return all scheduling information for all reports.</p>
<p>Through the use of a numbers table (done through the CTE), I have been able to create a map table for each of the necessary values to be parsed from the schedule later in the script.  In the creation of that map table, note the use of the power function.  This map table was the critical piece in my opinion to create a script that could quickly decipher the values in the schedule and provide something readable to the DBA.</p>
<h3>Conclusion</h3>
<p>I did this script because I feel it important to know what reports are running and when they are running.  Add that management also likes to know that information, so there is value to it.  But, I found scripts on the web that used the bitwise operation piece but a lot of repetitive code to determine each Weekday and month.</p>
<p>An alternative would be to perform a query against the msdb database since Scheduled reports are done via a SQL Agent job.  I hope you find this report useful and that you can put it to use.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1859" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/20/on-the-eighth-day/">On the Eighth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/20/on-the-eighth-day/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>On the Seventh Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/19/on-the-seventh-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-seventh-day</link>
					<comments>https://jasonbrimhall.info/2012/12/19/on-the-seventh-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 19 Dec 2012 09:30:08 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Agent Job]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1851</guid>

					<description><![CDATA[<p>So far this series has been a bit of fun.  We have discussed a fair amount of useful things to date.  And here we are only on the seventh day. Today we will be reverting [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/19/on-the-seventh-day/">On the Seventh Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignright  wp-image-1854" title="7swans" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/7swans1.png" alt="" width="320" height="320" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/7swans1.png 400w, https://jasonbrimhall.info/wp-content/uploads/2012/12/7swans1-150x150.png 150w, https://jasonbrimhall.info/wp-content/uploads/2012/12/7swans1-300x300.png 300w" sizes="(max-width: 320px) 85vw, 320px" /></p>
<p>So far this series has been a bit of fun.  We have discussed a fair amount of useful things to date.  And here we are only on the seventh day.</p>
<p>Today we will be reverting our attention back to the msdb database.  This time not as a means of maintaining the under-carriage but rather to help us try and become better DBAs.</p>
<p>Sometimes to be a better DBA, we have to be a bit proactive and less reactive.</p>
<p>We&#8217;ll get to that shortly.  As we have done just about every day so far though, we need to recap real quick what we have to date in the 12 Days of pre-Christmas.</p>
<p>&nbsp;</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">Maintenance Plan Gravage</a> &#8211; Day 6</li>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> &#8211; Day 5</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> &#8211; Day 4</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> &#8211; 3rd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> &#8211; 2nd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> &#8211; 1st Day</li>
</ol>
<h3>On the Seventh Day of pre-Christmas&#8230;</h3>
<p>My DBA gave to me an early Nuclear Fallout detection and warning system.  Ok, maybe not quite that extensive &#8211; but it could sure feel like it if something were to slip through the crevasses and the business management started breathing down your neck.</p>
<p>Have you ever had a SQL Job run longer than it should have?  Has the job run long enough that it ran past the next scheduled start time?  These are both symptoms that you might want to monitor for and track in your environment.  If you are watching for it &#8211; you should be able to preemptively strike with warning flares sent out to the interested parties.  Then you would be more of the hero than the scapegoat.  And we all want to be on the winning side of that conversation without the confrontation from time to time ;).</p>
<p>Today, I am going to share a quick script that can be used to help monitor for jobs that have waltzed well beyond the next scheduled start time.  First though, there is a script available out there for the jobs that have run beyond normal run times.  You can check out this <a href="http://thomaslarock.com/2012/10/how-to-find-currently-running-long-sql-agent-jobs/">article </a>by Thomas LaRock to get a good script to check and log long running jobs.</p>
<p>Though the criteria are similar &#8211; we do have two different needs that need to be reported on and monitored.  This is why we have this second script.  If you have a job that should run every 15 minutes but you find that the job has been running non-stop for 45 minutes, that is quite a problem.  And many times we should alert on something like that.</p>
<p>So here is the quick script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH preagg AS (   
SELECT sj.name,MAX(sa.last_executed_step_date) AS last_executed_step_date
		,MAX(sa.start_execution_date) AS start_execution_date
		,MAX(sa.stop_execution_date) AS stop_execution_date
		,MAX(sa.next_scheduled_run_date) AS next_scheduled_run_date
		,MAX(sh.run_status) AS run_status
		,MAX(ca.next_run_date_time) AS Next_Scheduled_RunDate
		,MAX(CAST(STUFF(STUFF(REPLACE(STR(sh.run_duration, 6), ' ', '0')
							, 3, 0, ':')
						, 6, 0, ':')
				AS varchar)) AS Run_Duration
	FROM msdb.dbo.sysjobs sj
		INNER JOIN msdb.dbo.sysjobactivity sa
			ON sj.job_id = sa.job_id
		LEFT OUTER JOIN msdb.dbo.sysjobhistory sh
			ON sa.job_history_id = sh.instance_id
		INNER JOIN msdb.dbo.sysjobschedules sjs 
			ON sj.job_id = sjs.job_id
        INNER JOIN msdb.dbo.sysschedules ss 
			ON sjs.schedule_id = ss.schedule_id
        CROSS APPLY (SELECT CONVERT(DATETIME, 
                    CASE WHEN sjs.next_run_date = 0 THEN NULL
                    ELSE RIGHT('00000000' + CONVERT(VARCHAR(8), sjs.next_run_date),8) 
						+ ' ' + 
						STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(6), sjs.next_run_time),6)
									, 3, 0, ':')
							, 6, 0, ':')
                    END)
            ) ca(next_run_date_time)
	WHERE (sa.start_execution_date &amp;gt; 0
		AND sa.stop_execution_date IS NULL)
		And (ISNULL(sa.next_scheduled_run_date,GETDATE()) &amp;lt;&amp;gt; ca.next_run_date_time
			OR ISNULL(sh.run_status,4) in (1,4))
	/*
		Status of the job execution:
		0 = Failed
		1 = Succeeded
		2 = Retry
		3 = Canceled
		4 = In progress
	*/
	GROUP BY sj.name
)
SELECT *
	FROM preagg
	WHERE next_scheduled_run_date IS NULL
	ORDER BY Next_Scheduled_RunDate</pre><p>[/codesyntax]</p>
<p>From here, it is a matter of creating a SQL job to run this script.  The schedule is dependent on job frequency and your expected needs to monitor.  It can very easily be set to run every five minutes.</p>
<p>Once the job is created then it is a matter of setting up a mechanism to alert.  There are any number of ways to do that as well.  I leave that to any who use the script to determine how best to implement for their own environment.</p>
<h3>Conclusion</h3>
<p>This script will catch jobs that are running and have exceeded the next scheduled start time.  This is accomplished through the filters in the where clause.  With a couple of date comparisons as well as filtering on job_status we can get the desired results.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1851" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/19/on-the-seventh-day/">On the Seventh Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/19/on-the-seventh-day/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>On the Sixth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/18/on-the-sixth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-sixth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/18/on-the-sixth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 18 Dec 2012 09:30:59 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[CheckDB]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1842</guid>

					<description><![CDATA[<p>What better way to kick off the sixth day of pre-Christmas than with six slices of foie-gras?  No animals have been hurt in the making of this post! This could be a pretty festive dish [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">On the Sixth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p class="mceTemp"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/6geesealaying.png"><img loading="lazy" class="alignright size-full wp-image-1846" title="6geesealaying" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/6geesealaying.png" alt="" width="353" height="246" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/6geesealaying.png 353w, https://jasonbrimhall.info/wp-content/uploads/2012/12/6geesealaying-300x209.png 300w" sizes="(max-width: 353px) 85vw, 353px" /></a>What better way to kick off the sixth day of pre-Christmas than with six slices of foie-gras?  No animals have been hurt in the making of this post!</p>
<p class="mceTemp">This could be a pretty festive dish thanks in part to those geese.  I enjoy a little foie gras every now and again.</p>
<p>No, this was not just a clever ploy to bring fat into another post.  Rather, I feel that foie gras is more of a delicacy than eggs.</p>
<p>Today, we will be talking of a delicacy in the database world.  It is a feature that should help every DBA sleep better at night.  Sadly, this delicacy can be tainted by another feature that may just give you hear burn instead.</p>
<p>First though, let&#8217;s recap.</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">Table Compression</a> &#8211; Day 5</li>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> &#8211; Day 4</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> &#8211; 3rd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> &#8211; 2nd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> &#8211; 1st Day</li>
</ol>
<h3>On the Sixth Day of pre-Christmas&#8230;</h3>
<figure style="width: 219px" class="wp-caption alignright"><a style="color: #ff4500;" href="http://jasonbrimhall.info/wp-content/uploads/2012/12/foiegras4r.jpg"><img loading="lazy" class="size-full wp-image-1843 " title="foiegras4r" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/foiegras4r.jpg" alt="" width="219" height="315" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/foiegras4r.jpg 219w, https://jasonbrimhall.info/wp-content/uploads/2012/12/foiegras4r-208x300.jpg 208w" sizes="(max-width: 219px) 85vw, 219px" /></a><figcaption class="wp-caption-text">Picture Courtesy of AllCreatures.org</figcaption></figure>
<p>My DBA gave to me a way to ensure my databases are not corrupt.</p>
<p>Sadly, the method chosen is to force feed (gravage) the checkdb through an SSIS style maintenance plan.  Have you ever tried to run checkdb through a maintenance plan?  It doesn&#8217;t always work so well.</p>
<p>Many times, when running checkdb, you may run into this pretty little error message.</p>
<p><span style="color: #ff0000;">Msg 5808, Level 16, State 1, Line 2</span><br />
<span style="color: #ff0000;">Ad hoc update to system catalogs is not supported.</span></p>
<p>Well, that is just downright wrong.  If I am provided a tool to create maintenance plans, then the tool should not generate an error such as that when I want to run consistency checks against the database.  This is akin to force feeding us something that isn&#8217;t all that good for our health.  There was even a connect item filed for this behavior, <a href="http://connect.microsoft.com/SQLServer/feedback/details/126163/maintenace-plan-integrity-checks-fail-with-alter-failed-for-server-xxx">here</a>.</p>
<h3>So, what is it that causes this behavior?</h3>
<p>Well, there are a couple of things that contribute to this behavior.  This can be reproduced from tsql as well.  To find what is causing this behavior, I used a tool that is a bit more reliable.  To recreate the failure, I created a small test database and then created a maintenance plan to run consistency checks for that database.  Then the reliable tool I used is Profiler.</p>
<p>Next up is to run the profiler with a filter for the test database, then to start the maintenance plan.  It shouldn&#8217;t take too long to have the maintenance plan complete.  When it completes, it is time to investigate the TSQL generated by Profiler and it should become apparent pretty quick what TSQL is being run during a maintenance plan that causes the checkdb to fail with the above mentioned error.</p>
<p>Are you ready?  This code is pretty complex and perplexing.  You better sit down so you don&#8217;t fall from the surprise and shock.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC sys.sp_configure N'user options', 0 
RECONFIGURE</pre><p>[/codesyntax]</p>
<p>Why would a maintenance plan need to run that snippet every time that a checkdb is performed?</p>
<p>Now, there is another piece to this puzzle.  This error is thrown when another configuration setting is present.  If we change that setting, the error no longer happens.  Soooo, a quick fix would be to change that setting.  The setting in question is &#8220;Allow Updates&#8221;.  It has a value of 1 and must be changed to a value of 0.  Since SQL 2005, we want it to be a 0 anyway.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC sp_configure 'allow updates' ,0
RECONFIGURE WITH override</pre><p>[/codesyntax]</p>
<p>Now, another option for this issue would be that the maintenance plan not run the sp_configure at all.  Or, if it is deemed necessary, that it be changed to the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC sys.sp_configure N'user options', 0 
RECONFIGURE WITH override</pre><p>[/codesyntax]</p>
<p>The best option in my opinion is that a maintenance plan not be used for consistency checks.  I&#8217;d prefer to see a custom built routine, a routine using sp_msforeachdb, or the maintenance plan routines developed by Ola Hallengren that can be found <a href="http://ola.hallengren.com/">here</a>.  All of these methods require that a little more thought be put into the consistency checking of your database, but that means you will get better sleep through the night.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1842" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/18/on-the-sixth-day/">On the Sixth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/18/on-the-sixth-day/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>On the Fifth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/17/on-the-fifth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-fifth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/17/on-the-fifth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 17 Dec 2012 09:30:21 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1834</guid>

					<description><![CDATA[<p>Today we will have a quick change of pace.  This will be less about maintenance and more about internals. Today&#8217;s topic is one of particular interest to me as well.  The topic is a small [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">On the Fifth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft  wp-image-1836" title="5goldrings" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/5goldrings.png" alt="" width="256" height="224" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/5goldrings.png 400w, https://jasonbrimhall.info/wp-content/uploads/2012/12/5goldrings-300x262.png 300w" sizes="(max-width: 256px) 85vw, 256px" /></p>
<p>Today we will have a quick change of pace.  This will be less about maintenance and more about internals.</p>
<p>Today&#8217;s topic is one of particular interest to me as well.  The topic is a small section of a presentation I like to give at User Groups and at SQL Saturdays.</p>
<p>Before we take this diversion from the under-carriage to something more related to the engine, let&#8217;s have a brief recap of the previous four days of pre-Christmas.</p>
<p>So far the gifts of pre-Christmas have included the following articles.</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">Exercise for msdb</a> &#8211; Day 4</li>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> &#8211; 3rd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> &#8211; 2nd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> &#8211; 1st Day</li>
</ol>
<h3>On the Fifth Day of pre-Christmas&#8230;</h3>
<p><img loading="lazy" class="alignright size-full wp-image-1837" title="compactcars" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/compactcars.png" alt="" width="312" height="329" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/compactcars.png 312w, https://jasonbrimhall.info/wp-content/uploads/2012/12/compactcars-284x300.png 284w" sizes="(max-width: 312px) 85vw, 312px" /></p>
<p>My DBA gave to me a much more compact database.  Surprisingly it can be as much as much as 20% of the original size.</p>
<p>I know, I know.  I&#8217;ve heard it before but this is not the compression used by doublespace and drivespace that we were given many years ago.  This really is much better.</p>
<p>And yes I have heard about the performance factor too.  That is a topic for another discussion.  As an aside, when it comes to performance, I always tell people that they <strong>must</strong> test for themselves because mileage will vary.</p>
<p>No, what I want to talk about is much different.  I want to talk about the CD Array(at the page level) and the new data types specific to compression that you may encounter within the CD Array.</p>
<h3>CD Array Data Types</h3>
<p>SQL Server introduces us to 13 data types that are used within the CD Array when Compression has been enabled.  Twelve of these data types can be seen when Row Compression has been enabled on an object.  The thirteenth data type is only applicable when page compression has been implemented.</p>
<p>There is no guarantee that any or all of these data types will be present on a page related to an object that has been compressed using either Row Compression or Page Compression.  If you want to find these data types on a compressed page, you may have to do a little hunting.</p>
<p>To demonstrate that these data types exist and that they can be found, I have a sample script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">USE CompressTest
GO

IF EXISTS(SELECT NAME FROM sys.tables WHERE name=N'CDTypes')
BEGIN
	DROP TABLE dbo.CDTypes
END

IF EXISTS(SELECT NAME FROM sys.tables WHERE name=N'CDTypes2')
BEGIN
	DROP TABLE dbo.CDTypes2
END

CREATE TABLE dbo.CDTypes( 
	SomeNull int
	,SomeBit BIT
	,Some1Byte INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,Some2Byte CHAR(2)
	,Some3Byte CHAR(3)
	,Some4Byte CHAR(4)
	,Some5Byte CHAR(5)
	,Some6Byte CHAR(6)
	,Some7Byte CHAR(7)
	,Some8Byte CHAR(8)
	,SomeLong CHAR(9)
	,SomeBit2 BIT
) WITH (DATA_COMPRESSION=ROW) ;	

 SELECT TOP 20000
        SomeID       = IDENTITY(INT,1,1),
        SomeInt      = ABS(CHECKSUM(NEWID()))%50000+1,
        SomeLetters2 = REPLICATE(CHAR(ABS(CHECKSUM(NEWID()))%26+65)
                     + CHAR(ABS(CHECKSUM(NEWID()))%26+65),10),
        SomeMoney    = CAST(ABS(CHECKSUM(NEWID()))%10000 /100.0 AS MONEY),
        SomeDate     = CAST(RAND(CHECKSUM(NEWID()))*3653.0+36524.0 AS DATETIME),
        SomeHex12    = RIGHT(NEWID(),12)
   INTO dbo.CDTypes2
   FROM Master.dbo.SysColumns t1,
        Master.dbo.SysColumns t2;
GO

/*
Let's create a Clustered Index
*/
CREATE CLUSTERED INDEX CompressSTable ON  dbo.CDTypes2(SomeID) WITH (DATA_COMPRESSION = PAGE);
GO

/* Insert Data */
INSERT INTO dbo.CDTypes
        ( SomeNull, SomeBit,  Some2Byte, Some3Byte,Some4byte, Some5byte
        , Some6byte, Some7byte, Some8byte, SomeLong, Somebit2)
VALUES  (NULL, 0,  '12', '123', '1234', '12345', '123456', '1234567', '12345678', '123456789', 1)
Go

DBCC IND(CompressTest, 'CDTypes', 1)
go

/* Make sure CDTypes2 is page compressed */
ALTER INDEX CompressSTable ON CDTypes2 REBUILD WITH (DATA_COMPRESSION = PAGE);

DBCC IND(CompressTest, 'CDTypes2', 1)
go

DBCC TRACEON(3604)
go
/*
Set Trace 3604 To Get Output to SSMS
Then take a look at the Page

--or--
Use the tableresults method
Both methods shown here

*/

DBCC PAGE('CompressTest', 1, 20392, 3) WITH tableresults
go 
DBCC PAGE('CompressTest', 1, 24889, 3) --in this exercise the second page of type 1 is usually page compressed
go</pre><p>[/codesyntax]</p>
<p>Now let&#8217;s take a look at the different data types, starting with the 12 available with Row Compression.</p>
<table width="274" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="64" />
<col width="133" />
<col width="77" /> </colgroup>
<tbody>
<tr>
<td width="64" height="20">0x00</td>
<td width="133">NULL</td>
<td width="77">SomeNull</td>
</tr>
<tr>
<td height="20">0x01</td>
<td>EMPTY</td>
<td>SomeBit</td>
</tr>
<tr>
<td height="20">0x02</td>
<td>ONE_BYTE_SHORT</td>
<td>Some1Byte</td>
</tr>
<tr>
<td height="20">0x03</td>
<td>TWO_BYTE_SHORT</td>
<td>Some2Byte</td>
</tr>
<tr>
<td height="20">0x04</td>
<td>THREE_BYTE_SHORT</td>
<td>Some3Byte</td>
</tr>
<tr>
<td height="20">0x05</td>
<td>FOUR_BYTE_SHORT</td>
<td>Some4Byte</td>
</tr>
<tr>
<td height="20">0x06</td>
<td>FIVE_BYTE_SHORT</td>
<td>Some5Byte</td>
</tr>
<tr>
<td height="20">0x07</td>
<td>SIX_BYTE_SHORT</td>
<td>Some6Byte</td>
</tr>
<tr>
<td height="20">0x08</td>
<td>SEVEN_BYTE_SHORT</td>
<td>Some7Byte</td>
</tr>
<tr>
<td height="20">0x09</td>
<td>EIGHT_BYTE_SHORT</td>
<td>Some8Byte</td>
</tr>
<tr>
<td height="20">0x0a</td>
<td>LONG</td>
<td>SomeLong</td>
</tr>
<tr>
<td height="20">0x0b</td>
<td>BIT_COLUMN</td>
<td>SomeBit2</td>
</tr>
</tbody>
</table>
<p>If we look at page 20392 (yours will likely be different), we will find all of these data types present.  We will also note that this page should show (COMPRESSED) PRIMARY_RECORD &#8211; which indicates that the page is Row Compressed.  When hunting for these data types, it is a good idea to make sure the page is compressed first.  In the supplied table, you can see what data type matches to which column in the table we created via the script.  The table also provides a short description of what that data type represents (as you would see in the CD Array).</p>
<p>If we now want to explore and find the 13th data type, we need to look at the second table we created in the attached script &#8211; CDTypes2.  Notice that this table has been page compressed.  I even did that twice.  I did this to make sure the data was page compressed (occasionally when testing I could not easily find a page compressed page unless I page compressed a second time).</p>
<p>Much the same as was done with Row Compression, we need to verify that a page is Page Compressed before searching up and down trying to find this 13th type.  To find a Page Compressed page, we need to look in the CompressionInfo section of the page for CI_HAS_DICTIONARY.  If this notation is present, the page is Page Compressed.</p>
<p>Here is a page snippet with the pertinent data type.</p>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/PageCompress_Symbol.png"><img loading="lazy" class="aligncenter  wp-image-1840" title="PageCompress_Symbol" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/PageCompress_Symbol.png" alt="" width="714" height="149" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/PageCompress_Symbol.png 793w, https://jasonbrimhall.info/wp-content/uploads/2012/12/PageCompress_Symbol-300x62.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a>The CD array entry for Column 4 is what we are interested in here.  In this particular record, we see the thirteenth data type of 0x0c (ONE_BYTE_PAGE_SYMBOL).  This data type can appear for any of the columns in the CD array and can be different for each record on the page.  This is due to how Page Compression works (which is also a different discussion).</p>
<p>For this last example, I want to backtrack a bit and point out that I used page 24889 to query for the Symbol data type in the CD Array.  This page was different every time I re-ran the test script.  One thing that was consistent with how I setup the exercise is that the page compressed page that had this data type was always the second page of type 1 (data page) in the results from DBCC Ind.</p>
<h3>Conclusion</h3>
<p>I hope this helped demystify compression in SQL Server &#8211; a little.  This is only one piece of compression but an interesting one in my opinion.  Use the provided script and play with it a little bit to get some familiarity.</p>
<p>Stay tuned for the 6th day of pre-Christmas.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1834" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/17/on-the-fifth-day/">On the Fifth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/17/on-the-fifth-day/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>On the Fourth Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/16/on-the-fourth-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-fourth-day</link>
					<comments>https://jasonbrimhall.info/2012/12/16/on-the-fourth-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sun, 16 Dec 2012 21:56:48 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1818</guid>

					<description><![CDATA[<p>We have come to the fourth day in this mini-series.  So far I have laid down some under-carriage maintenance for one of our favorite databases.  That database being the msdb database.  The maintenance discussed so [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">On the Fourth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/4dbs.png"><img loading="lazy" class="alignleft size-full wp-image-1826" title="4dbs" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/4dbs.png" alt="" width="224" height="241" /></a>We have come to the fourth day in this mini-series.  So far I have laid down some under-carriage maintenance for one of our favorite databases.  That database being the msdb database.  The maintenance discussed so far has covered a few different tables and processes to try and keep things tidy (at a base level).</p>
<p>Today I want to discuss some under-carriage work for the database of id 4.  Yep, that&#8217;s right, we will talk some more about the msdb database today.  What we discuss today, though, may be applicable beyond just the msdb database.  First, let&#8217;s recap the previous three days.</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/15/on-the-third-day/">Backup, Job and Mail History Cleanup</a> &#8211; 3rd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker Out of Control</a> &#8211; 2nd Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maint Plan Logs</a> &#8211; 1st Day</li>
</ol>
<h3>On the Fourth Day of pre-Christmas&#8230;</h3>
<p style="text-align: left;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/pork_fat.jpg"><img loading="lazy" class="size-full wp-image-1823 aligncenter" title="pork_fat" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/pork_fat.jpg" alt="" width="220" height="220" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/pork_fat.jpg 220w, https://jasonbrimhall.info/wp-content/uploads/2012/12/pork_fat-150x150.jpg 150w" sizes="(max-width: 220px) 85vw, 220px" /></a>My DBA gave to me an exercise program to help me trim the fat!!</p>
<p>Somehow, that seems like it would be more appealing on bacon.  But the amount of fat shown here is just nasty.  And that is what I think a table using multiple gigabytes in a database is when it holds 0 records.</p>
<p>Just deleting the records we have spoken of over the past three days is not the end of the road with the maintenance of the msdb database.  Often times the pages allocated to these tables don&#8217;t deallocate right away.  Sometimes, the pages don&#8217;t deallocate for quite some time.</p>
<p>When these pages are cleaned up depends in large part on the ghost cleanup process. Of course, the ghost cleanup is not going to do anything on the tables where records were removed unless it knows that there are some ghost records (records that have been deleted) in the first place.  This doesn&#8217;t happen until a scan operation occurs.  You can read a much more detailed explanation on the ghost cleanup process from Paul Randal, <a href="http://www.sqlskills.com/blogs/paul/post/inside-the-storage-engine-ghost-cleanup-in-depth.aspx">here</a>.</p>
<p>Because of this, you can try running a query against the table to help move the process along.  But what if you can&#8217;t get a scan operation to occur against the table?</p>
<p>Could you try updating statistics?  Maybe try running updateusage?  How about forcing a rebuild of the Clustered Index?  Or even running Index Rebuilds with LOB_Compaction on?  Or even creating a Clustered Index where one doesn&#8217;t exist?  Maybe you could try DBCC CLEANTABLE and see if that works.  Or you could try running DBCC CheckDb on the msdb database and try to get all of the pages read.</p>
<p>While working to reduce the table size for the tables in the following image, I tried several different things to try and force a scan of the pages so I could reduce the table sizes (0 records really should not consume several GB of space).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged1.png"><img loading="lazy" class="aligncenter size-full wp-image-1829" title="xmitqueue_purged" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged1.png" alt="" width="485" height="37" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged1.png 485w, https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged1-300x22.png 300w" sizes="(max-width: 485px) 85vw, 485px" /></a></p>
<p>&nbsp;</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/sysmaintplan.png"><img loading="lazy" class="aligncenter size-full wp-image-1828" title="sysmaintplan" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/sysmaintplan.png" alt="" width="529" height="36" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/sysmaintplan.png 529w, https://jasonbrimhall.info/wp-content/uploads/2012/12/sysmaintplan-300x20.png 300w" sizes="(max-width: 529px) 85vw, 529px" /></a></p>
<p>Even letting things simmer for a few days to see if backup operations could help, I still see the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/tablesize_afterbackups.png"><img loading="lazy" class="aligncenter size-full wp-image-1830" title="tablesize_afterbackups" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/tablesize_afterbackups.png" alt="" width="506" height="54" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/tablesize_afterbackups.png 506w, https://jasonbrimhall.info/wp-content/uploads/2012/12/tablesize_afterbackups-300x32.png 300w" sizes="(max-width: 506px) 85vw, 506px" /></a></p>
<p>This is better than it was, but still seems a bit over the top.  Something that both of these tables have in common is that they have BLOB columns.  To find that for the sysxmitqueue table, you would need to connect to the server using a DAC connection.  If you were to use a DAC connection, you would find that the msgbody column is a varbinary(max).</p>
<p>What I found to work for this particular case was to use DBCC Shrinkfile.  As a one time (hopefully)  maintenance task, it should be ok.  I would never recommend this as a regular maintenance task.  The used space for these tables does not decrease until DBCC Shrinkfile reaches the DbccFilesCompact<strong> </strong>stage.  This is the second phase of ShrinkFile and may take some time to complete.  You can read more on Shrinkfile <a href="http://blogs.msdn.com/b/psssql/archive/2008/03/28/how-it-works-sql-server-2005-dbcc-shrink-may-take-longer-than-sql-server-2000.aspx">here</a>.</p>
<h3>Conclusion</h3>
<p>Is it necessary to go to these lengths to reclaim space in your msdb database from tables that are excessively large with very few records?  That is up to you and your environment.  In many cases, I would say it is a nice to have but not a necessity.</p>
<p>If you do go to these lengths to reduce space in msdb, then you need to understand that there are costs associated with it.  There will be additional IO as well as index fragmentation that you should be prepared to handle as a consequence of shrinking.</p>
<p>Stay tuned for the next installment.  We will be taking a look into some internals related to Compression.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1818" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/16/on-the-fourth-day/">On the Fourth Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/16/on-the-fourth-day/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>On the Third Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/15/on-the-third-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-third-day</link>
					<comments>https://jasonbrimhall.info/2012/12/15/on-the-third-day/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Sat, 15 Dec 2012 09:30:54 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1809</guid>

					<description><![CDATA[<p>Mais Oui! But of course, we must have some french hens for today!  Today we have the third day of pre-Christmas.  And as was mentioned we have more undercarriage work in store. So far we [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/15/on-the-third-day/">On the Third Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/1044833_BLOGPNG_20121213170215567.png"><img loading="lazy" class="size-full wp-image-1811 aligncenter" title="3 French hens" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/1044833_BLOGPNG_20121213170215567.png" alt="" width="450" height="260" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/1044833_BLOGPNG_20121213170215567.png 450w, https://jasonbrimhall.info/wp-content/uploads/2012/12/1044833_BLOGPNG_20121213170215567-300x173.png 300w" sizes="(max-width: 450px) 85vw, 450px" /></a></p>
<h3 style="text-align: center;">Mais Oui!</h3>
<p>But of course, we must have some french hens for today!  Today we have the third day of pre-Christmas.  And as was mentioned we have more undercarriage work in store.</p>
<p>So far we have talked about the following:</p>
<ol>
<li><a href="http://jasonbrimhall.info/2012/12/13/on-the-first-day/">Maintenance Plan Logs</a> on the First Day</li>
<li><a href="http://jasonbrimhall.info/2012/12/14/on-the-second-day/">Service Broker lost Messages</a> on the Second Day</li>
</ol>
<h3>On the Third Day of Pre-Christmas&#8230;</h3>
<p>My DBA gave to me more old fat.  Like the past few days, we are looking at more tables that have too much fat.  The kind of fat that has been sitting around for too long and is far beyond stale.</p>
<p>Here, I am going to cover two more tables that can get large.  This is very much similar to how Nicholas Cain (<a href="https://twitter.com/sirsql">twitter</a>) has covered the topic, though I do it slightly different.  You can read what he has done <a href="https://sirsql.net/2011/01/26/2011125keeping-msdb-clean-html/">here</a>. *</p>
<p><i></i>The biggest difference comes in how we determine large tables.  You can read my method for finding large tables <a href="http://jasonbrimhall.info/2011/11/17/table-space-revised-again/">here</a>.</p>
<p>The key here is that there are tables in the msdb database that are in use for maintaining mail history and backup history.  These tables need to be given TLC.</p>
<p>To maintain these tables, I do much the same as Nic does.  To maintain these two tables, I create a SQL Job to run scripts.  The scripts are as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Cleanup old backup history */
DECLARE @BackupHistoryOlderThan DATE 
SET @BackupHistoryOlderThan = DATEADD(d, -90, GETDATE())
EXECUTE msdb.dbo.sp_delete_backuphistory @BackupHistoryOlderThan</pre><p>&nbsp;</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Cleanup old mail items */
DECLARE @MailItemHistoryOlderThan DATE 
SET @MailItemHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sysmail_delete_mailitems_sp @sent_before = @MailItemHistoryOlderThan</pre><p>Now, this is the third day of pre-Christmas so I have one more routine that Nic didn&#8217;t discuss in that post.  This one is to clean out Agent Job history.  This is done because I have seen the sysjobhistory table get rather large like the other tables I have discussed so far in this series.  To run maintenance for this table, it is rather similar to the prior two scripts from today.</p><pre class="urvanov-syntax-highlighter-plain-tag">/*Cleanup of Old Job History*/
Declare @JobHistoryOlderThan DATE
Set @JobHistoryOlderThan = DATEADD(d, -14, GETDATE())
EXECUTE msdb.dbo.sp_purge_jobhistory @oldest_date = @JobHistoryOlderThan</pre><p>The stored procedure being used can take different parameters.  It allows you to purge either for a specific job or by date or everything if no parameter is supplied.  You can read more of that from the documentation <a href="http://msdn.microsoft.com/en-us/library/ms175044.aspx">here</a>.</p>
<p>Another reason I like to do this is to make it easier to read the agent job history when I am troubleshooting.  When there is a lot of history, it can be rather slow and even possibly cause timeouts trying to get in to troubleshoot a failed job.</p>
<p>Running this procedure comes in very handy when somebody has forgotten to set the SQL Agent properties for job history retention.  Then again, maybe they didn&#8217;t forget.</p>
<p>This type of setting of course is a blanket example.  As I alluded to earlier, this procedure can take different parameters.  And if somebody has not set the history retention properties for SQL Agent, then we have some flexibility.</p>
<p>With this flexibility, you can set a custom purge cycle for each of several different jobs.  Maybe some jobs only need 2-3 days of retention but another needs to have 90 days.  This method allows you to do that.</p>
<h3>Upcoming</h3>
<p>So far we have worked to maintain several different large tables within the msdb database.  In the next article, we will discuss how to release the space from the table that should be released after removing large amounts of data stored in these tables due to a lack of maintenance and TLC.</p>
<h3>Notes</h3>
<p><i>* The page previously linked to the blog for Nicholas Cain appears to now be broken. Due to that break, here are the indexes that were referenced in that blog post.</i></p><pre class="urvanov-syntax-highlighter-plain-tag">/* msdb maintenance activity related indexes */

Create Index IX_maintplan_taskdetailid on [msdb].[dbo].[sysmaintplan_logdetail]
	([task_detail_id])
	with (fillfactor = 90)
	/* Improves plan cost by 10x down from 417 to 44 in one batch.  Down from 26 to .1 in another batch*/


Create Index IX_backupset_type on msdb.dbo.backupset
	([type],[backup_finish_date])
	Include ([media_set_id], [database_name])
	With (fillfactor = 90)

Create Index IX_jobactivity_jobid on [msdb].[dbo].[sysjobactivity]
	([job_id])
	Include ([session_id])
	With (fillfactor = 90)</pre><p></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1809" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/15/on-the-third-day/">On the Third Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/15/on-the-third-day/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>On the Second Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/14/on-the-second-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-second-day</link>
					<comments>https://jasonbrimhall.info/2012/12/14/on-the-second-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 14 Dec 2012 09:30:40 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1803</guid>

					<description><![CDATA[<p>&#160; Yesterday, I introduced the 12 Days of pre-Christmas.  In that first article, I gave you a gift to help maintain your msdb undercarriage.  Today I want to continue in that vein. As is the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/14/on-the-second-day/">On the Second Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift2.png"><img loading="lazy" class="alignleft size-full wp-image-1804" title="gift2" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift2.png" alt="" width="256" height="256" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/gift2.png 256w, https://jasonbrimhall.info/wp-content/uploads/2012/12/gift2-150x150.png 150w" sizes="(max-width: 256px) 85vw, 256px" /></a></p>
<p>&nbsp;</p>
<p>Yesterday, I introduced the 12 Days of pre-Christmas.  In that first article, I gave you a gift to help maintain your msdb undercarriage.  Today I want to continue in that vein.</p>
<p>As is the tradition with the 12 Days of Christmas, each of these gifts should provide more value as we go.  The value may not be that the gift I share is of any more value than a previous gift, but that in combination with the previous gifts more value will be gained.  Woot!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>On the Second Day of Pre-Christmas&#8230;</h3>
<p>My DBA gave to me some lost messages.  After fixing the issue with the maintenance plan log tables you still notice that you have a large msdb database.  Through further investigation you can see that the cause is related to the sysxmitqueue table as displayed in the attached image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue.png"><img loading="lazy" class="aligncenter size-full wp-image-1805" title="xmitqueue" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue.png" alt="" width="551" height="37" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue.png 551w, https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue-300x20.png 300w" sizes="(max-width: 551px) 85vw, 551px" /></a></p>
<p>The sysxmitqueue table is a queue table for Service Broker messages.  If this table is growing, then you have some undeliverable messages.  This means that something with Service Broker is mis-configured.  Too many of these messages start building up and the size can get relatively large for this table.</p>
<p>Once the messages start to queue up, you need to investigate.  Start with querying the sys.transmission_queue system catalog view.  In that view there is a transmission_status column.  If you get a message like &#8220;The Service Broker in the target database is unavailable: &#8216;The service broker is administratively disabled.&#8217;.&#8221;, then you have an issue with Service Broker not being properly enabled in at least one of the databases involved in Service Broker.</p>
<p>If you have that message, you can confirm that Service Broker is not properly setup in one of the databases by running the following query from each database involved in Service Broker.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT is_broker_enabled FROM sys.databases
WHERE database_id = DB_ID() ;</pre><p>[/codesyntax]</p>
<p>If you have inherited something like this, and nobody has noticed that it isn&#8217;t working &#8211; you may not need it enabled and may need to look at removing the components for the queue associated with the failed messages.  Check with interested parties and determine if the queue and service are needed or not.  In the meantime, you can clear out some of these messages by running the following.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">END CONVERSATION 'conversation_handle' WITH CLEANUP;</pre><p>[/codesyntax]</p>
<p>In this code, conversation_handle is the handle retrieved from the sys.transmission_queue system catalog view.  Once this completes, you should see the that the number of rows is greatly reduced in sysxmitqueue as shown here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged.png"><img loading="lazy" class="aligncenter size-full wp-image-1806" title="xmitqueue_purged" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged.png" alt="" width="485" height="37" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged.png 485w, https://jasonbrimhall.info/wp-content/uploads/2012/12/xmitqueue_purged-300x22.png 300w" sizes="(max-width: 485px) 85vw, 485px" /></a></p>
<p>Notice here that the rows have been reduced to 0.  At this time, the space has yet to be released from the table.  This is something you may have noticed from purging the maint plan logs as discussed yesterday.</p>
<h3>Coming Up</h3>
<p>In the next few posts, we will discuss some more undercarriage work for the msdb database.  In addition, we will discuss releasing this space.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1803" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/14/on-the-second-day/">On the Second Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/14/on-the-second-day/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>On the First Day&#8230;</title>
		<link>https://jasonbrimhall.info/2012/12/13/on-the-first-day/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=on-the-first-day</link>
					<comments>https://jasonbrimhall.info/2012/12/13/on-the-first-day/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 13 Dec 2012 17:33:16 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1798</guid>

					<description><![CDATA[<p>Many of us have heard the song &#8220;The Twelve Days of Christmas.&#8221;  Some are familiar with how that song has some connection with the Holiday season for Christians.  Fewer are aware that this song is [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/12/13/on-the-first-day/">On the First Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift1.jpg"><img loading="lazy" class="alignleft  wp-image-1801" title="gift1" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/gift1.jpg" alt="" width="307" height="303" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/gift1.jpg 307w, https://jasonbrimhall.info/wp-content/uploads/2012/12/gift1-300x296.jpg 300w" sizes="(max-width: 307px) 85vw, 307px" /></a>Many of us have heard the song &#8220;The Twelve Days of Christmas.&#8221;  Some are familiar with how that song has some connection with the Holiday season for Christians.  Fewer are aware that this song is connected to the tradition of giving traditions on each of the days of Christmas.  Fewer yet know that the first day of Christmas is actually December 25th.</p>
<p>So, instead of a blog series for the 12 Days of Christmas, I am doing a blog series for the 12 Days of pre-Christmas.  Today is Day 1, or day -12, depending on how you look at it.</p>
<p>My caveat is that in my own little world, the 12th day of pre-Christmas will overlap with the actual first day of Christmas.  You may find that this is similar to how the First Day of Epiphany and 12th day of Christmas can overlap.</p>
<p>Now that we have that all squared away, on to my First day of pre-Christmas gift for you.</p>
<h3>On the First Day of pre-Christmas&#8230;</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log.jpg"><img loading="lazy" class="alignright  wp-image-1799" title="yule log" src="http://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log.jpg" alt="" width="307" height="230" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log.jpg 384w, https://jasonbrimhall.info/wp-content/uploads/2012/12/yule-log-300x225.jpg 300w" sizes="(max-width: 307px) 85vw, 307px" /></a>My DBA gave to me  &#8211; A maintenance plan log.  No, not a yule log.  But a maintenance plan log.  Have you heard of sysmaintplan_log and sysmaintplan_logdetail?  These are system tables in the msdb database.</p>
<p>These tables are used to support logging of maintenance plans (SSIS style) since SQL 2005.  If you have not introduced yourself to them and you are running maintenance plans (SSIS style), you may have some large tables.  I have seen these tables become very large and as a result cause the msdb database to also be very large.</p>
<p>Part of a good maintenance plan is also to take care of the undercarriage.  In this case, we need to take good care of the supporting tables for the SSIS style maintenance plans.  One quick and easy method to do this is to add a SQL Agent job to help maintain these tables.</p>
<p>In the SQL Agent job that you create, add this query to maintain the amount of historical information held by these tables.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @OldDate DateTime
Set @OldDate = GETDATE() - 14;

Execute msdb.dbo.sp_maintplan_delete_log @oldest_time = @OldDate</pre><p>[/codesyntax]</p>
<p>And there you have it.  Something you may also want to do is to add a Clustered Index to the sysmaintplan_logdetail table.  There are no indexes on this table.  Since the stored procedure is looking at start_time, and this is likely to be the most frequently queried field, I chose to create a Clustered Index on start_time.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE CLUSTERED INDEX [CI_Start_time] ON [dbo].[sysmaintplan_logdetail] 
(
	[start_time] ASC
)</pre><p>[/codesyntax]</p>
<h3>Conclusion</h3>
<p>Simple but effective.  The idea here is to decrease the chance of bloat in the msdb database.  We don&#8217;t want the database to grow out of control.  We don&#8217;t want the size of these tables to cause the Maintenance plans to run slower.  And we certainly don&#8217;t want these tables to grow to a size that causes the database to fill and subsequently cause backups to start failing (for instance).</p>
<p>Tune in each day between now and December 25th for a new gift in this season of giving.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1798" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/12/13/on-the-first-day/">On the First Day…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/12/13/on-the-first-day/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Last Known Good CheckDB</title>
		<link>https://jasonbrimhall.info/2012/11/20/last-known-good-checkdb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=last-known-good-checkdb</link>
					<comments>https://jasonbrimhall.info/2012/11/20/last-known-good-checkdb/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Nov 2012 09:00:32 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[CheckDB]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1772</guid>

					<description><![CDATA[<p>Diligent DBAs like to check their databases for a little thing called corruption.  Some of those DBAs are masterful at keeping records and logging that the database was checked and came up with a clean [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/11/20/last-known-good-checkdb/">Last Known Good CheckDB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Diligent DBAs like to check their databases for a little thing called corruption.  Some of those DBAs are masterful at keeping records and logging that the database was checked and came up with a clean bill of health.</p>
<p>There are many different ways of logging this kind of activity.  Today I will share one such way to track when the last successful run of Checkdb happened.</p>
<h2>First a little back story</h2>
<p>A question came across twitter on the <a href="https://twitter.com/search?q=%23sqlhelp">SQLhelp</a> hashtag. The question was &#8220;Does restoring a database clear the dbi_dbccLastKnownGood value on the boot page?&#8221;</p>
<p>This question prompted me to do a quick test to see.  The test is simple.  Create a small database, backup the database, run checkdb, check to see what the dbi_dbccLastKnownGood value is, restore the previous backup and check the dbi_dbccLastKnownGood value again.</p>
<p>So here is a quick script</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [master]
GO

IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'TestB')
DROP DATABASE [TestB]
GO

USE [master]
GO
CREATE DATABASE [TestB] 
GO

DECLARE @BackupPath VARCHAR(256)
	,@BackupName VARCHAR(50)
SET @BackupPath = 'C:\Database\Backup\' --replace with valid file path
SET @BackupName = 'TestB.bak'

SET @BackupPath = @BackupPath + @BackupName
BACKUP DATABASE [TestB]
	TO DISK = @BackupPath
	WITH init;
GO

CREATE TABLE #temp (
       Id INT IDENTITY(1,1), 
       ParentObject VARCHAR(255),
       [Object] VARCHAR(255),
       Field VARCHAR(255),
       [Value] VARCHAR(255)
)

INSERT INTO #temp
EXECUTE ('DBCC Page ( TestB,1,9,3) WITH TABLERESULTS');

/* You will get two results from the following query */
SELECT *
	FROM #temp
	WHERE Field = 'dbi_dbccLastKnownGood';

/* TAKE note OF the date returned by the last query */

DROP TABLE #temp;
GO

DBCC CHECKDB(TestB) WITH no_infomsgs;
GO

CREATE TABLE #temp (
       Id INT IDENTITY(1,1), 
       ParentObject VARCHAR(255),
       [Object] VARCHAR(255),
       Field VARCHAR(255),
       [Value] VARCHAR(255)
)

INSERT INTO #temp
EXECUTE ('DBCC Page ( TestB,1,9,3) WITH TABLERESULTS');

/* You will get two results from the following query */
SELECT *
	FROM #temp
	WHERE Field = 'dbi_dbccLastKnownGood';

/* TAKE note OF the date returned by the last query */

DROP TABLE #temp;
GO

/* Now Restore the database */
DECLARE @BackupPath VARCHAR(256)
	,@BackupName VARCHAR(50)
SET @BackupPath = 'C:\Database\Backup\' --replace with valid file path
SET @BackupName = 'TestB.bak'

SET @BackupPath = @BackupPath + @BackupName
/* for this contrived example, i will not take a tail log backup
and just use replace instead */

RESTORE DATABASE TestB
	FROM DISK = @BackupPath
	WITH REPLACE; 
GO

/* Rerun The Boot Page Check */
CREATE TABLE #temp (
       Id INT IDENTITY(1,1), 
       ParentObject VARCHAR(255),
       [Object] VARCHAR(255),
       Field VARCHAR(255),
       [Value] VARCHAR(255)
)

INSERT INTO #temp
EXECUTE ('DBCC Page ( TestB,1,9,3) WITH TABLERESULTS');

/* You will get two results from the following query */
SELECT *
	FROM #temp
	WHERE Field = 'dbi_dbccLastKnownGood';

/* TAKE note OF the date returned by the last query */

DROP TABLE #temp;
GO</pre><p>[/codesyntax]</p>
<p>If you run this little test, you should observe that the date value for dbi_dbccLastKnownGood changes with each test.  Now let&#8217;s discuss the question and the answer to that original question about whether or not this value gets cleared.</p>
<p>The value does not get cleared.  The value does not get reset.  The cause for the change in the value that you have observed is due simply to the <span style="text-decoration: underline;">boot page</span> having been restored.  If CheckDB has never been run on the database, you will get the SQL default date of &#8216;1900-01-01 00:00:00.000&#8217;.</p>
<h2>And then&#8230;</h2>
<p>Now that the back story is told, that brings us to how to track this &#8211; at least one such method.  I had to cover the back story since it is what prompted the writing of a method to gather this information in a quick script so I could use it to monitor.  Yes, it is just another tool to throw into the toolbox.  And to reiterate, it is by no means the only way to track or gather this type of information.  Some are more elaborate than others.  It is up to you to choose.</p>
<p>Keeping in mind that we can get the last time that Checkdb completed without a report of corruption, I delve into this cursor based method to retrieve the dbi_dbccLastKnownGood value for all databases within your SQL Server Instance.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #temp (
       Id INT IDENTITY(1,1), 
       ParentObject VARCHAR(255),
       [Object] VARCHAR(255),
       Field VARCHAR(255),
       [Value] VARCHAR(255)
)

CREATE TABLE #DBCCRes (
       Id INT IDENTITY(1,1)PRIMARY KEY CLUSTERED, 
       DBName sysname ,
       dbccLastKnownGood DATETIME,
       RowNum	INT
)

DECLARE
	@DBName SYSNAME,
	@SQL    varchar(512);

DECLARE dbccpage CURSOR
	LOCAL STATIC FORWARD_ONLY READ_ONLY
	FOR Select name
		from sys.databases
		where name not in ('tempdb');

Open dbccpage;
Fetch Next From dbccpage into @DBName;
While @@Fetch_Status = 0
Begin
Set @SQL = 'Use [' + @DBName +'];' +char(10)+char(13)
Set @SQL = @SQL + 'DBCC Page ( ['+ @DBName +'],1,9,3) WITH TABLERESULTS;' +char(10)+char(13)

INSERT INTO #temp
	Execute (@SQL);
Set @SQL = ''

INSERT INTO #DBCCRes
        ( DBName, dbccLastKnownGood,RowNum )
	SELECT @DBName, VALUE
			, ROW_NUMBER() OVER (PARTITION BY Field ORDER BY Value) AS Rownum
		FROM #temp
		WHERE field = 'dbi_dbccLastKnownGood';

TRUNCATE TABLE #temp;

Fetch Next From dbccpage into @DBName;
End
Close dbccpage;
Deallocate dbccpage;

SELECT DBName,dbccLastKnownGood
	FROM #DBCCRes
	WHERE RowNum = 1;

DROP TABLE #temp
DROP TABLE #DBCCRes</pre><p>[/codesyntax]</p>
<p>You can use this or find something else if you desire.  The sole purpose of this script is to provide a means to gather quickly the last date known to report a clean bill of health from Checkdb.  From there, I will leave it to you to add it to another process in order to track over the long term.</p>
<p>You can read the twitter conversation <a href="https://twitter.com/search?q=%23sqlhelp%20%40sqlbob&amp;src=typd">here</a>.  I also have it on good authority that Bob Pusateri (<a href="https://twitter.com/SQLBob">twitter</a>) will be blogging about the same topic.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1772" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/11/20/last-known-good-checkdb/">Last Known Good CheckDB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/11/20/last-known-good-checkdb/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>Summit 2012 Community Zone</title>
		<link>https://jasonbrimhall.info/2012/11/02/summit-2012-community-zone/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=summit-2012-community-zone</link>
					<comments>https://jasonbrimhall.info/2012/11/02/summit-2012-community-zone/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 02 Nov 2012 20:02:03 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS SUMMIT]]></category>
		<category><![CDATA[Volunteer]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1761</guid>

					<description><![CDATA[<p>&#160; &#160; &#160; &#160; Will you be at Summit 2012? I will be. I will even be pretty easy to find on multiple occasions.  If you haven&#8217;t seen my schedule already &#8211; you can check [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/11/02/summit-2012-community-zone/">Summit 2012 Community Zone</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignleft" title="Summit" src="http://www.sqlpass.org/images/Summit2012_header_passlogo.png" alt="" width="286" height="83" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Will you be at Summit 2012?</p>
<p>I will be. I will even be pretty easy to find on multiple occasions.  If you haven&#8217;t seen my schedule already &#8211; you can check it out <a href="http://jasonbrimhall.info/2012/11/01/summit-2012/">here</a>. You&#8217;ll probably notice that there are a few times where I will be in a very public spot helping at a booth of some sort (like the Apress booth with my book).</p>
<p>There are two times that you will find me as a volunteer with PASS helping out in the Community Zone. What is the Community Zone you ask? Well, it is mostly a place were you can just sack out on the bean bags (I hope they are <a href="https://www.lovesac.com/sacs-learn">LoveSacs</a> &#8211; they are sooo comfy!). Not just kidding &#8211; though you could relax on the bean bags if you wanted.</p>
<p>From the PASS Summit Community Zone page, the CZ is a place to help you stay involved.</p>
<blockquote><p>Want to stay involved in the SQL Server community year-round? Check out the Community Zone at PASS Summit 2012 and talk with PASS Community Evangelists, user group leaders, SQLSaturday organizers, and other SQL Server community groups about how you can participate.</p></blockquote>
<p>The CZ is also a place where you can get some swag or get your game card to have a chance at some cool prizes.</p>
<p>The game card is for a networking game that involves you talking to and meeting other people at Summit.  Here is the full description in the email sent to me:</p>
<blockquote><p>Networking Game:  We will start handing out the cards at the CZ when it opens on Wednesday. The game is actually two parts.</p>
<p>a.       Meet 10 people from outside of the country where you live and learn something interesting about their country. They will be required to write these individuals names down, along with what they learned, and what country they are from. We will have “icebreakers” and networking tips listed on the back of the game card to help them out. Once they have all 10, their card will go into the raffle drawing, which will be held right before the BoF lunch in the Exhibitors Hall (our drawings will be immediately after the Exhibitor raffles are done)</p>
<p>b.      Part two, the spin-off game from the above involves pics. The attendee who manages to get the most pictures taken of themselves with the people they meet, will win top prize. If we have several who get all 10, then we will of course do a drawing. We want to encourage folks to bring their pics by often, so we can copy off and possibly use in slides before the keynote Thursday, but also so we can get them up to flicker. Social Media will also be doing some picture contests, as well as several other fun social media games. The Community Zone will also be on FourSquare among other HOT Summit spots!</p>
<p>c.       Now the prize details:</p>
<p>For the completed networking game card drawing, the first winner drawn will get their choice between a Surface tablet or a $250 Amex Gift Card. We will draw a second person for this first game, they will win a MSFT Arc Mouse.  For the picture contest portion of this, the first drawn winner will receive whatever the first winner didn’t select (either the tablet or the gift card).  And we’ll do a runner up to this game as well, who will also receive a MSFT Arc Mouse. Great prizes, don’t you think!</p></blockquote>
<p>I don&#8217;t know about you, but that sounds like some pretty good stuff to win just for talking to a few people.</p>
<p>If that kind of networking game isn&#8217;t your cup of tea, there is still the opportunity to get some daily swag. Each day there will be various new activities tweeted or written on the boards in the CZ.  Go do that activity and you can get some swag.  Easy Peasy Lemon Squeezy &#8211; right?</p>
<p>So where is this Community Zone?  Glad you asked.  The CZ will be near the SQLClinic, Bookstore, Exhibit Hall and the Lunch Hall.  It is in the Skybridge on the 4th floor. Directly across from the CZ you will find the PASS kiosks.  I hope you are able to find it and come visit!</p>
<p><em>*PASS Summit logo is hosted by the PASS Servers and is merely present via a link to the PASS website.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1761" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/11/02/summit-2012-community-zone/">Summit 2012 Community Zone</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/11/02/summit-2012-community-zone/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQLSat153 Recap</title>
		<link>https://jasonbrimhall.info/2012/10/24/sqlsat153-recap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlsat153-recap</link>
					<comments>https://jasonbrimhall.info/2012/10/24/sqlsat153-recap/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 24 Oct 2012 17:23:19 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLFamily]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1753</guid>

					<description><![CDATA[<p>You may not know that this past Saturday ( October 20, 2012) was SQLSaturday 153 in Salt Lake City.  If you knew about it, awesome.  If you attended &#8211; even better.  You probably don&#8217;t know [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/10/24/sqlsat153-recap/">SQLSat153 Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>You may not know that this past Saturday ( October 20, 2012) was <a href="http://sqlsaturday.com/153/eventhome.aspx">SQLSaturday 153</a> in Salt Lake City.  If you knew about it, awesome.  If you attended &#8211; even better.  You probably don&#8217;t know that I was there presenting this year.  I was a huge slacker in getting the word out about presenting at SQLSat153.</p>
<p>I am hoping that this recap will help atone for that grievous mistake. <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Pat Wright (<a href="http://twitter.com/SqlAsylum">twitter</a>)and company did a great job putting the event together and it appeared to run without problem.  I did what I could to help where possible.  I showed up early to try and help with setup and also to make sure demos and equipment would work.</p>
<p>Notice that I was there to make sure my there wouldn&#8217;t be equipment issues.  I had the first presentation of the day and I wanted it to run smoothly.  I&#8217;ll also throw out there that it was a first time presenting that topic for myself.  Well, I hope the feedback is as good as the turnout.</p>
<p style="text-align: center;"><a href="http://jasonbrimhall.info/wp-content/uploads/2012/10/xe_session.jpg"><img loading="lazy" class="aligncenter  wp-image-1754" title="xe_session" src="http://jasonbrimhall.info/wp-content/uploads/2012/10/xe_session.jpg" alt="" width="531" height="353" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/10/xe_session.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2012/10/xe_session-300x199.jpg 300w" sizes="(max-width: 531px) 85vw, 531px" /></a></p>
<p style="text-align: left;">I had a packed house!  I had a couple of other presenters find me afterward because they had heard my session was packed.  A little razzing about stealing their attendees was to be had and it was welcomed.</p>
<p style="text-align: left;">The session that was packed (and the empty chair was a momentary absence so he could answer his phone) was on Extended Events in SQL 2012.  This was a fun session and the topic is really good.  Unfortunately we did not make it to the bonus material.  I think the bonus demos would have been very good to discuss.  I hope we can get to that material next time.</p>
<p style="text-align: left;">Despite not reaching the bonus material, I have included the material in the zip file that I uploaded to the event website.</p>
<p style="text-align: left;">I did present two sessions Saturday and was part of the open forum panel that consisted of Cindy Gross (<a href="https://twitter.com/SQLCindy">twitter</a>), Randy Knight (<a href="https://twitter.com/randy_knight">twitter</a>), Ben Miller (<a href="https://twitter.com/dbaduck">twitter</a>) and myself.    Now you may know that Cindy is an MCM.  You might also know that Randy and Ben have both passed the MCM Knowledge exam (Ben is taking the Lab as I type).  That made the panel full of SQL Knowledge (we joked that it was equal to two full MCMs giving Ben, Randy and myself 1/3 each for having passed the Knowledge Exam).  This Q&amp;A session went over quite well too.</p>
<p style="text-align: left;">If you didn&#8217;t make it out, I hope it was a really good reason.  I also hope that you can make it next time because the sessions were outstanding and the opportunity to learn is top notch.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1753" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/10/24/sqlsat153-recap/">SQLSat153 Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/10/24/sqlsat153-recap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Finally, it has happened&#8230;</title>
		<link>https://jasonbrimhall.info/2012/10/04/finally-it-has-happened/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=finally-it-has-happened</link>
					<comments>https://jasonbrimhall.info/2012/10/04/finally-it-has-happened/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 04 Oct 2012 13:00:25 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Authored Books]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1725</guid>

					<description><![CDATA[<p>Last month I blogged about my absence from the blogosphere.  If you want, you can read about it again &#8211; here.  Granted, it has been a month and I still have been slacking.  I am [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/10/04/finally-it-has-happened/">Finally, it has happened…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Last month I blogged about my absence from the blogosphere.  If you want, you can read about it again &#8211; <a href="http://jasonbrimhall.info/2012/07/18/where-in-the-world-is/">here</a>.  Granted, it has been a month and I still have been slacking.  I am hoping to turn a new leaf and post more regularly here in the next few weeks.</p>
<p>Since that last post I had been anxiously waiting.  The book seemed to keep getting delayed.  Yesterday, reality finally hit home.  It is so weird how much different it feels to finally have a book physically in my hands.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/10/bookinhand.png"><img loading="lazy" class="aligncenter size-full wp-image-1726" title="bookinhand" src="http://jasonbrimhall.info/wp-content/uploads/2012/10/bookinhand.png" alt="" width="512" height="288" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/10/bookinhand.png 512w, https://jasonbrimhall.info/wp-content/uploads/2012/10/bookinhand-300x168.png 300w" sizes="(max-width: 512px) 85vw, 512px" /></a></p>
<p>I am one that likes ebooks and I don&#8217;t normally have to be able to feel the pages of the book.  But this is one case where the ability to rifle the pages is so much more gratifying.  Finally the book is real!!</p>
<p>If you are interested, you can get the book <a href="http://www.amazon.com/Server-2012-T-SQL-Recipes-Problem-Solution/dp/1430242000">here</a>.</p>
<p><em>Oh and if you are wondering why I posted this picture, it is simple.  I didn&#8217;t want to take a picture of myself today holding the book and the other books pictured happen to be books that I had on hand because I have been reading them of late.</em></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1725" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/10/04/finally-it-has-happened/">Finally, it has happened…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/10/04/finally-it-has-happened/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>August 2012 S3OLV Meeting</title>
		<link>https://jasonbrimhall.info/2012/07/30/august-2012-s3olv-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=august-2012-s3olv-meeting</link>
					<comments>https://jasonbrimhall.info/2012/07/30/august-2012-s3olv-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 30 Jul 2012 16:28:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1713</guid>

					<description><![CDATA[<p>Well well well.  It has certainly been a long time between announcements on the blog about meetings for the Las Vegas SQL Server Users Group. We have had to cancel a couple of times in [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/07/30/august-2012-s3olv-meeting/">August 2012 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Well well well.  It has certainly been a long time between announcements on the blog about meetings for the Las Vegas SQL Server Users Group.</p>
<p>We have had to cancel a couple of times in the past few months &#8211; but the meetings have been happening with or without the blog post about it.  I have been a little more occupied with a few other things (like the book).  But we are back (at least for a little bit) in the saddle!</p>
<p>Here are the meeting details in case you are not on the mailing list.</p>
<p><strong>Next Meeting</strong><br />
August 09, 2012 6:00-8:00pm PDT</p>
<p><strong>Jason Brimhall</strong><br />
Jason Brimhall has 10+ yrs experience and has worked with SQL Server from 6.5 through SQL 2012. He has experience in performance tuning, high transaction environments, as well as large environments. He is currently a DB Architect and an MCDBA. He is he VP of the Las Vegas User Group (SSSOLV). Jason is also the co-author of the book <a href="http://www.amazon.com/Server-2012-T-SQL-Recipes-Problem-Solution/dp/1430242000">&#8220;SQL Server 2012 T-SQL Recipes&#8221;</a><br />
You can read more about the book here: <a href="http://jasonbrimhall.info/2012/07/18/where-in-the-world-is/">SQL Server 2012 T-SQL Recipes </a></p>
<p><strong>SQL 2012 Table Compression</strong><br />
SQL Server 2008 has introduced Table compression to the DBA toolkit. We all know there are different kinds of compression available in SQL Server. What some may not know is the subtleties of compression. Such subtleties include that not all Page Compressed tables are entirely page compressed. This session will show you how to reach into the database and discover compression states at the page level. At the lower level, this session will also show how to determine compression settings of objects in the database. Participants will be able to use undocumented commands as well as commands such as PIVOT to derive some interesting information from the database engine.</p>
<p><strong>LiveMeeting Information:</strong><br />
Attendee URL: https://www.livemeeting.com/cc/UserGroups/join?id=FQS7BW&amp;role=attend<br />
Meeting ID: FQS7BW</p>
<p><strong>Location:</strong><br />
Still meeting at M Staff Solutions &amp; Training / 2620 Regatta Drive Suite 102 Las Vegas, NV 89128</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1713" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/07/30/august-2012-s3olv-meeting/">August 2012 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/07/30/august-2012-s3olv-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A Trio of EachDB</title>
		<link>https://jasonbrimhall.info/2012/07/17/a-trio-of-eachdb/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-trio-of-eachdb</link>
					<comments>https://jasonbrimhall.info/2012/07/17/a-trio-of-eachdb/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 17 Jul 2012 16:54:57 +0000</pubDate>
				<category><![CDATA[Corner]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1705</guid>

					<description><![CDATA[<p>When administering a larger database environment, sometimes one needs to perform repetitive tasks.  Performing repetitive tasks becomes more and more painful (maybe even demoralizing) with the larger the number of databases that might exist on [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/07/17/a-trio-of-eachdb/">A Trio of EachDB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>When administering a larger database environment, sometimes one needs to perform repetitive tasks.  Performing repetitive tasks becomes more and more painful (maybe even demoralizing) with the larger the number of databases that might exist on a server.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/07/escher-waterfall-medium.jpg"><img loading="lazy" class="alignnone size-large wp-image-1707" title="Waterfall" src="http://jasonbrimhall.info/wp-content/uploads/2012/07/escher-waterfall-medium-813x1024.jpg" alt="" width="560" height="705" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/07/escher-waterfall-medium-813x1024.jpg 813w, https://jasonbrimhall.info/wp-content/uploads/2012/07/escher-waterfall-medium-238x300.jpg 238w, https://jasonbrimhall.info/wp-content/uploads/2012/07/escher-waterfall-medium.jpg 1024w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>This kind of administration will have you running in circles.  You may even feel like you are making progress and then suddenly feel like there is no end in sight as you repeat the process with each database.</p>
<p>Some of the tasks that you may need to perform on a regularly basis may be to run reports on security access across all databases for a particular user, or to retrieve file free space information for all databases, or you may even just need to update the statistics across multiple databases.</p>
<p>These tasks can be simplified and even automated to help free your sanity and free your time.  Here is a trio of examples.</p>
<h3>Update Statistics</h3>
<p><em>*Disclaimer* These examples are just that &#8211; examples.  They are meant to be simple introductions.  The development into a full solution for use in your environment is a project for you to undertake.</em></p>
<p>In all of the examples I will share, there will be a common theme.  I will employ the looping mechanism introduced via sp_MSforeachdb.  I will also introduce a better version of that proc and how to execute each of these scripts with the newer version.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXECUTE sp_MSforeachdb 'use ?; Execute sp_updatestats;'
GO</pre><p>[/codesyntax]</p>
<p>As promised, that script is very simple to create.  I will leave it to you to make modifications for your environment.</p>
<h3>User Exists</h3>
<p>Suppose you get a request from your manager to list out the databases that a particular user has been granted access.  Here is a simple script to find which databases a user has been created within to report back to your manager.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #UserExists (DatabaseName VARCHAR(128), UserName VARCHAR(128));
GO

EXECUTE sp_MSforeachdb 'Insert Into #UserExists (DatabaseName, UserName)
				select ''?'' AS DatabaseName, 
                name AS UserName 
                FROM [?].sys.database_principals
                WHERE name = ''guest'' ';

SELECT DatabaseName, UserName
	FROM #UserExists;

DROP TABLE #UserExists;</pre><p>[/codesyntax]</p>
<p>Again, the script is not too terribly complex and can get the job done quickly.  The idea here is that each database will be queried on the database_principals catalog view.  I dump the results into a temp table for the each database in which that user exists and then query the temp table for the final result.</p>
<h3>File Free Space</h3>
<p>Occasionally you will want to know how much free space is in each database file.  This can be very useful should you manage your file growths.  You can use this information to establish alerts for when a file reaches a certain capacity threshold.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #FileProp (dbid INT,FILE_ID INT, SpaceUsed DECIMAL(14,2));
GO

EXECUTE sp_MSforeachdb 'USE ?; Insert Into #FileProp (dbid,FILE_ID,SpaceUsed) 
SELECT database_id,file_id,FILEPROPERTY(name,''SpaceUsed'') from sys.master_files where DB_NAME(database_id) = ''?'''

SELECT DB_NAME(database_id) AS DBName,physical_name,CONVERT(DECIMAL(14,2),size)/128 AS FileSize, growth
		,CONVERT(DECIMAL(14,2),max_size)/128 AS MaxFileSize,FP.SpaceUsed,mf.type_desc
	FROM sys.master_files mf
		INNER JOIN #FileProp FP
			ON FP.dbid = mf.database_id
			AND FP.FILE_ID = mf.file_id;

DROP TABLE #FileProp;
GO</pre><p>[/codesyntax]</p>
<p>Similar to the previous query, this query dumps results for each database into a temp table.  From there, we then query that temp table to get the final result set.  Like the others, this is an example to help produce some ideas.  You can extend this type of query to meet your needs as you see fit.</p>
<h3>Alternative</h3>
<p>Gianluca Sartori did some good work on building a better procedure to replace sp_MSforeachdb (<strong>while not using a cursor</strong>).  You can find his work <a href="http://spaghettidba.com/2011/09/09/a-better-sp_msforeachdb/">here</a>.  The reason for the updated procedure is due to some limitations/bugs with sp_MSforeachdb.  If you decide to use the new version, here is an example of how you might run one of the previously discussed queries.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #UserExists (DatabaseName VARCHAR(128), UserName VARCHAR(128));
GO

EXECUTE dbo.[dba_ForEachDB] @statement = 'Insert Into #UserExists (DatabaseName, UserName)
				select ''?'' AS DatabaseName, 
                name AS UserName 
                FROM [?].sys.database_principals
                WHERE name = ''guest'' '
		,@replacechar = '?';

SELECT DatabaseName, UserName
	FROM #UserExists;

DROP TABLE #UserExists;</pre><p>[/codesyntax]</p>
<h3>Conclusion</h3>
<p>Some simple examples of routine database administration tasks have been illustrated.  Take these examples and extend on them if you like.  It can save you some time.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1705" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/07/17/a-trio-of-eachdb/">A Trio of EachDB</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/07/17/a-trio-of-eachdb/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Maintenance Plan Owner</title>
		<link>https://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maintenance-plan-owner</link>
					<comments>https://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 25 Jun 2012 12:00:47 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSG Syndication]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1684</guid>

					<description><![CDATA[<p>We all inherit things from time to time through our profession.  Sometimes we inherit some good things, sometimes we inherit some things that are not so good.  Other times we inherit some things that are just plan annoying.  Yet other times, we inherit things that may be annoying and we probably just haven't discovered them yet.</p>
The post <a href="https://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/">Maintenance Plan Owner</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We all inherit things from time to time through our profession.  Sometimes we inherit some good things, sometimes we inherit some things that are not so good.  Other times we inherit some things that are just plan annoying.  Yet other times, we inherit things that may be annoying and we probably just haven&#8217;t discovered them yet.</p>
<p>Dizzying, I know.</p>
<h2>Inheritance</h2>
<p>Have you ever taken over a server that had several maintenance plans on it?  Have you ever really checked who the owner of those plans is?  Or, maybe you had a failing job relating to one of these maintenance plans and you changed the job owner, but did you really fix the root cause?  That could be one of those things that you inherited that could be annoying but you just don&#8217;t know it yet.</p>
<h2>Step by Step</h2>
<p>No this is not New Kids on the Block (I think I just threw up in my mouth thinking that).</p>
<p><a style="color: #ff4500; line-height: 15px;" href="http://jasonbrimhall.info/wp-content/uploads/2012/06/MaintPlanContext.png"><img loading="lazy" class="size-full wp-image-1686 alignleft" title="MaintPlanContext" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/MaintPlanContext.png" alt="" width="290" height="140" /></a></p>
<p>Let&#8217;s create a generic maintenance plan and see what happens.</p>
<p>The first thing we do is navigate to Maintenance Plans under the Management menu in Management Studio.  Right Click the Maintenance Plan folder and select New Maintenance Plan&#8230; from the context menu.  This will prompt us with the following dialog box.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner.png"><img loading="lazy" class="alignleft size-full wp-image-1687" title="maintplanowner" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner.png" alt="" width="354" height="125" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner.png 354w, https://jasonbrimhall.info/wp-content/uploads/2012/06/maintplanowner-300x105.png 300w" sizes="(max-width: 354px) 85vw, 354px" /></a>In this box, we can type a name for this Maintenance Plan that is to be created.  I chose MaintPlanOwner, since that is the topic of this article.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><img loading="lazy" class="alignleft size-full wp-image-1689" title="modifyplan" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/modifyplan.png" alt="" width="258" height="360" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/06/modifyplan.png 258w, https://jasonbrimhall.info/wp-content/uploads/2012/06/modifyplan-215x300.png 215w" sizes="(max-width: 258px) 85vw, 258px" /></p>
<p>After clicking ok on this dialog box, you will be presented with a blank canvas with which to design your maintenance plan.  I have chose a simple task for the purposes of this article.</p>
<p>I will create a subplan named Statistics and add the Update Statistics task to the canvas.</p>
<p>You can see this illustrated to the left.  I chose to update the statistics on all databases and left all other options as the default option &#8211; for simplicity of this article.</p>
<p>At this point, the only thing left to do is to save this Maintenance Plan.  Once the plan is saved, then we can move on to the next step &#8211; some fun with TSQL.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Fun with TSQL</h2>
<p>This is the stage of the article where we get to play with TSQL and investigate at a high level the Maintenance Plan we just created.</p>
<p>Within the msdb database, we have some system tables that store information about SSIS packages, DTS packages, and Maintenance Plans.  We will be investigating from a SQL 2008 and SQL 2005 standpoint (it changed in 2005 and then again in 2008).</p>
<p>In SQL 2005, we can query the sysdtspackages90 and sysdtspackagefolders90 to gain insight into who owns these Maintenance Plans.  In SQL 2008 and up, we can query sysssispackages and sysssispackagefolders to gain the same insight.  These system tables are within the msdb database.</p>
<p>In SQL 2005, we can use the following to find that I am now the owner of that maintenance plan we just created.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
SELECT p.name AS PackageName,p.createdate,pf.foldername AS PackageType,sp.name AS PrincipalName
	FROM msdb.dbo.sysdtspackages90  p
	INNER JOIN dbo.sysdtspackagefolders90 pf
		ON p.folderid = pf.folderid
	INNER JOIN master.sys.server_principals sp
		ON p.ownersid = sp.sid
WHERE pf.foldername = 'Maintenance Plans';</pre><p>For 2008, a slight modification yields the following query that returns the same results.</p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
SELECT p.name AS PackageName,p.createdate,pf.foldername AS PackageType,sp.name AS PrincipalName
	FROM msdb.dbo.sysssispackages  p
	INNER JOIN dbo.sysssispackagefolders pf
		ON p.folderid = pf.folderid
	INNER JOIN master.sys.server_principals sp
		ON p.ownersid = sp.sid
WHERE pf.foldername = 'Maintenance Plans';</pre><p>Notice that in both queries, I delve out in the sys.server_principals catalog view.  I did this to retrieve the name of the owner of the package that was found in the sysdtspackages90 and sysssispackages  tables respective to version of SQL Server.  These queries would yield the following result set for that new Maintenance Plan that was just created.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/06/owner.png"><img loading="lazy" class="alignnone wp-image-1690" title="owner" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/owner.png" alt="" width="617" height="46" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/06/owner.png 771w, https://jasonbrimhall.info/wp-content/uploads/2012/06/owner-300x22.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<h2>Caveat</h2>
<p>Let&#8217;s assume that this package is scheduled via a SQL Agent job on a production server.  I then get moved to a different department and no longer have permissions on this particular production server.  The job will start failing due to the principal not having access.  One fix would be to change the owner of the job.</p>
<p>That will work.  However, there is a problem with that fix.  As soon as somebody opens and saves the Maintenance Plan, the owner of the job will revert back to the owner of the Maintenance Plan.  When that happens, then the job will fail again.</p>
<p>A permanent fix is needed.  The permanent fix is to change the owner of the Maintenance Plan.  The following will change the owner to &#8216;sa&#8217; for both SQL 2005 and SQL 2008 (and up).</p>
<h3>SQL 2005</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
UPDATE p
SET ownersid = 0x01
FROM msdb.dbo.sysdtspackages90  p
	INNER JOIN dbo.sysdtspackagefolders90 pf
		ON p.folderid = pf.folderid
WHERE pf.foldername = 'Maintenance Plans';</pre><p></p>
<h3>SQL 2008</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">USE msdb;
GO
UPDATE p
SET ownersid = 0x01
From msdb.dbo.sysssispackages  p
	INNER JOIN dbo.sysssispackagefolders pf
		ON p.folderid = pf.folderid
WHERE pf.foldername = 'Maintenance Plans';</pre><p>Now if you run the code used earlier to investigate, you will find that the owner has indeed changed.  The results of that query should be similar to the following.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/06/owner_changed.png"><img loading="lazy" class="alignnone wp-image-1691" title="owner_changed" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/owner_changed.png" alt="" width="560" height="44" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/06/owner_changed.png 700w, https://jasonbrimhall.info/wp-content/uploads/2012/06/owner_changed-300x23.png 300w" sizes="(max-width: 560px) 85vw, 560px" /></a></p>
<p>There you have it.  No more hair tugging over something as benign as the owner of a Maintenance Plan.  This is one of those things that should be looked at as soon as you inherit a new server.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1684" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/">Maintenance Plan Owner</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/06/25/maintenance-plan-owner/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Database In Recovery</title>
		<link>https://jasonbrimhall.info/2012/06/04/database-in-recovery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=database-in-recovery</link>
					<comments>https://jasonbrimhall.info/2012/06/04/database-in-recovery/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 04 Jun 2012 12:00:01 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[MCM]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1673</guid>

					<description><![CDATA[<p>What do we do? Have you ever run into a database that is in the &#8220;In Recovery&#8221; state? If that has happened, have the bosses and/or endusers come to you asking &#8220;What do we do?&#8221; [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/06/04/database-in-recovery/">Database In Recovery</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2012/06/dr.jpg"><img loading="lazy" class="alignleft  wp-image-1674" title="dr" src="http://jasonbrimhall.info/wp-content/uploads/2012/06/dr.jpg" alt="" width="256" height="237" /></a>What do we do?</h3>
<p>Have you ever run into a database that is in the &#8220;In Recovery&#8221; state?</p>
<p>If that has happened, have the bosses and/or endusers come to you asking &#8220;What do we do?&#8221; or &#8220;When will it be done?&#8221;.  They probably have &#8211; it is inevitable.</p>
<p>The question is, what do <span style="text-decoration: underline;">you</span> do when you run into a database that is in this state?</p>
<p>We all know that it doesn&#8217;t help much if we are panicked about the issue &#8211; that just feeds the already growing anxiety.  If you feel anxiety &#8211; that&#8217;s OK, just don&#8217;t show that to the endusers or to the boss.  You need to portray to them that you are on top of the issue.</p>
<p>While trying to keep everybody calm and apprised of the situation, you would probably like some assurances for yourself that the database is progressing to a usable state.  That is what I want to share today &#8211; a little query that I wrote for this very instance.</p>
<h3>Anxiety Tranquilizer</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @ErrorLog AS TABLE([LogDate] DateTime, [ProcessInfo] VARCHAR(64), [TEXT] VARCHAR(MAX))

INSERT INTO @ErrorLog
EXEC sys.xp_readerrorlog 0, 1, 'Recovery of database'

SELECT  DB_NAME(dt.database_id) AS DBName,GETDATE() as currenttime, at.transaction_begin_time
      ,dt.transaction_id,at.name AS TranName
	  ,cx.PercentComplete,cx.MinutesRemaining
      ,d.log_reuse_wait_desc
      ,database_transaction_log_record_count, database_transaction_log_bytes_used
	, database_transaction_next_undo_lsn
	,CASE at.transaction_state
		WHEN 0 THEN 'Not Completely Initialized'
		WHEN 1 THEN 'Initialized but Not Started'
		WHEN 2 THEN 'Transaction is Active'
		WHEN 3 THEN 'Read-Only tran has Ended'
		WHEN 4 THEN 'Distributed Tran commit process has been initiated'
		WHEN 5 THEN 'In prepared state and waiting resolution'
		WHEN 6 THEN 'Transaction has been committed'
		WHEN 7 THEN 'Transaction is being rolled back'
		WHEN 8 THEN 'Transaction has been rolled back'
		END AS TranState
      FROM sys.dm_tran_database_transactions dt
		LEFT OUTER JOIN sys.dm_tran_active_transactions at
			ON dt.transaction_id = at.transaction_id
		INNER JOIN master.sys.databases d
			ON d.database_id = dt.database_id
		Cross Apply (SELECT TOP 1
			 [LogDate]
			,SUBSTRING([TEXT], CHARINDEX(') is ', [TEXT]) + 4,CHARINDEX(' complete (', [TEXT]) - CHARINDEX(') is ', [TEXT]) - 4) AS PercentComplete
			,CAST(SUBSTRING([TEXT], CHARINDEX('approximately', [TEXT]) + 13,CHARINDEX(' seconds remain', [TEXT]) - CHARINDEX('approximately', [TEXT]) - 13) AS FLOAT)/60.0 AS MinutesRemaining
			,db_name(SUBSTRING([TEXT], CHARINDEX('(', [TEXT]) + 1,CHARINDEX(')', [TEXT]) - CHARINDEX('(', [TEXT]) - 1) ) as DBName
			,Cast(SUBSTRING([TEXT], CHARINDEX('(', [TEXT]) + 1,CHARINDEX(')', [TEXT]) - CHARINDEX('(', [TEXT]) - 1) as Int) as DBID
			FROM @ErrorLog ORDER BY [LogDate] DESC) cx
		WHERE d.state_desc &amp;lt;&amp;gt; 'online'
			And cx.dbid = dt.database_id</pre><p>Unfortunately, this query does not demonstrate the time remaining for the rollback nor the percent complete without needing to query the error log.  Those would be awesome additions if you know how to do it (and let me know), other than via the error log.  Thanks to a <a href="https://web.archive.org/web/20180117133532/http://timlaqua.com:80/2009/09/determining-how-long-a-database-will-be-in-recovery-sql-server-2008/">blog post by Tim Laqua</a> for the base info on querying the error log for the percent complete.</p>
<p>I think the key component on this query is the LEFT OUTER JOIN to sys.dm_tran_active_transactions.  This is essential since the recovery is shown in two transactions.  One transaction is numbered and is the placeholder for the un-numbered transaction where the work is actually being done.  In the numbered transaction, you should see a transaction name of &#8220;Recovery Allocation Locks&#8221; and nothing for the unnumbered transaction.</p>
<p>Now, unnumbered is not entirely accurate because that transaction has an id of 0, but you will not find a correlating transaction for that in the sys.dm_tran_active_transactions DMV.</p>
<p>The transactions displayed here will be displayed until recovery is complete.  That also means that if you really wanted to, you could create a table to log the recovery process by inserting the results from this query into it.  Then you could revisit the table and examine at closer detail what happened during recovery.</p>
<p>The anxiety killer from this query is to watch two columns in the unnumbered transaction.  These columns are database_transaction_log_record_count and database_transaction_next_undo_lsn.  I rerun the query multiple times throughout the process of recovery.  I check those columns to ensure the data in them is changing.  Changing results in those fields means that you are seeing progress and can provide some comfort by seeing actual progress (even though we know in the back of our head that it is progressing).</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1673" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/06/04/database-in-recovery/">Database In Recovery</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/06/04/database-in-recovery/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Are my Linked Servers Being Used?</title>
		<link>https://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=are-my-linked-servers-being-used</link>
					<comments>https://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 05 Mar 2012 13:00:57 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Administration]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1616</guid>

					<description><![CDATA[<p>This is a follow up to an article published on 3/1/2012.  That article showed how to find what linked servers were created on your instance of SQL Server.  You can read it here. This article [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/">Are my Linked Servers Being Used?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/02/link.png"><img loading="lazy" class="size-full wp-image-1613 alignright" title="link" src="http://jasonbrimhall.info/wp-content/uploads/2012/02/link.png" alt="" width="292" height="275" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/02/link.png 365w, https://jasonbrimhall.info/wp-content/uploads/2012/02/link-300x282.png 300w" sizes="(max-width: 292px) 85vw, 292px" /></a>This is a follow up to an article published on 3/1/2012.  That article showed how to find what linked servers were created on your instance of SQL Server.  You can read it <a href="http://jasonbrimhall.info/2012/03/01/linked-servers/">here</a>.</p>
<p>This article came about due to a request to find if any stored procedures are using any of the linked servers.  In addition to finding if any stored procedures may be using a linked server was the need to find the name of that procedure.  The request evolved to also include finding any SQL Agent jobs that may be using the linked server.</p>
<p>In response to that request, I had the idea to adapt a query I had recently written.  I will be posting that in the near future.</p>
<h3>Query</h3>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @VName varchar(256)
Declare Findlinked cursor
LOCAL STATIC FORWARD_ONLY READ_ONLY
     FOR
Select name AS name
	From sys.servers
	Where is_linked = 1

Open Findlinked;
Fetch next from Findlinked into @VName;

while @@FETCH_STATUS = 0
Begin
	SELECT OBJECT_NAME(object_id) 
		FROM sys.sql_modules 
		WHERE Definition LIKE '%'+@VName +'%' 
		AND OBJECTPROPERTY(object_id, 'IsProcedure') = 1 ;

	Fetch next from Findlinked into @VName;
END
Close Findlinked

Open Findlinked;
Fetch next from Findlinked into @VName;

while @@FETCH_STATUS = 0
Begin
	SELECT j.name AS JobName,js.command 
		FROM msdb.dbo.sysjobsteps js
			INNER JOIN msdb.dbo.sysjobs j
				ON j.job_id = js.job_id
		WHERE js.command LIKE '%'+@VName +'%'
	Fetch next from Findlinked into @VName;
END

Close Findlinked
Deallocate Findlinked</pre><p>Don&#8217;t blast me just yet due to the use of a loop (cursor).  In a case such as what has just been presented, a cursor is a legitimate tool.  I need to find all stored procedures that contain the text I specify.  In this case, I am searching for each of the linked servers.</p>
<p>In addition to searching all of the stored procedures for the use of a defined linked server, I am re-opening the same cursor to search all of the jobs defined on the server.  I do this in the event that the job was created with an ad-hoc query in lieu of using a stored procedure.</p>
<p>If you run the query, you will find that it should provide a quicker turnaround time on documenting the use of the linked servers than manually searching.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1616" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/">Are my Linked Servers Being Used?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>System Base Tables</title>
		<link>https://jasonbrimhall.info/2012/01/30/system-base-tables/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=system-base-tables</link>
					<comments>https://jasonbrimhall.info/2012/01/30/system-base-tables/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 30 Jan 2012 13:00:43 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[MCM]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1594</guid>

					<description><![CDATA[<p>On January 19th, I published a post about the Dedicated Administrator Connection.  I spoke very briefly of the system base tables in that article.  Today, I want to dive into these tables a little bit [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/01/30/system-base-tables/">System Base Tables</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>On January 19th, I published a post about the <a href="http://jasonbrimhall.info/2012/01/19/dedicated-administrator-connection/">Dedicated Administrator Connection</a>.  I spoke very briefly of the system base tables in that article.  Today, I want to dive into these tables a little bit more.</p>
<p>First, let&#8217;s get the <a href="http://msdn.microsoft.com/en-us/library/ms179503.aspx">Microsoft definition</a> for these tables.  &#8220;System base tables are the underlying tables that actually store the metadata for a specific database.&#8221;</p>
<p>Have you ever queried sys.objects from the master database and wondered about some of the results?  You can see all of the System base tables when querying the sys.objects view.  These tables are denoted in sys.objects by type of &#8216;S&#8217; and a type_desc of &#8216;SYSTEM_TABLE&#8217;.</p>
<p>Here is a simple query to take a quick peek at these tables.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT * FROM sys.objects
	WHERE Type = 'S'
	ORDER BY NAME</pre><p>[/codesyntax]</p>
<p>There is no need for a Dedicated Administrator connection in order for this query to work.  You can view these results with a non-DAC connection to the instance so long as you have adequate permissions to query sys.objects.  That said, not all objects returned by that query are System Base Tables.  Furthermore, it appears that the list from <a href="http://msdn.microsoft.com/en-us/library/ms179503.aspx">MSDN</a> is not comprehensive.  One such example is the reference to sys.sysserrefs that does not appear to exist in SQL 2008 R2 and the missing System Base table called sys.sysbrickfiles (which is used by sysaltfiles as shown in this execution plan).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2012/01/brickfiles.png"><img loading="lazy" class="alignnone size-full wp-image-1599" title="brickfiles" src="http://jasonbrimhall.info/wp-content/uploads/2012/01/brickfiles.png" alt="" width="600" height="116" srcset="https://jasonbrimhall.info/wp-content/uploads/2012/01/brickfiles.png 750w, https://jasonbrimhall.info/wp-content/uploads/2012/01/brickfiles-300x58.png 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>If I try to query the sysbrickfiles table (as an example) without connecting via DAC, I will get an error message like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">Msg 208, Level 16, State 1, Line 1
Invalid object name 'sys.sysbrickfiles'.</pre><p>This is normal behavior.  You cannot query the system base tables without first connecting via DAC.  Having said that, the obligatory warning is required.  As explained on MSDN, these tables are intended for use by Microsoft.  Proceed at your own risk and please make sure you have backups.</p>
<p>In addition to these System Base tables, you will find tables not mentioned in the article nor in the master database.  These System Base tables are found within the Resource database.  The resource database does contain most of the tables mentioned in that article, but there are some differences.  I will leave that discovery exercise to the reader.</p>
<p>There is plenty about SQL Server that many of us take for granted.  Under the hood, there is much more to learn.  Taking a peek at the System Base tables is one of those areas that will help you to learn more about SQL Server.  My question is this: How far are you willing to explore to learn more about SQL Server?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1594" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/01/30/system-base-tables/">System Base Tables</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/01/30/system-base-tables/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Missing Indexes</title>
		<link>https://jasonbrimhall.info/2012/01/12/missing-indexes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=missing-indexes</link>
					<comments>https://jasonbrimhall.info/2012/01/12/missing-indexes/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 12 Jan 2012 14:00:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Index Maintenance]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1563</guid>

					<description><![CDATA[<p>SQL Server has means built into it to track possible missing indexes.  This used to be found through the use of the Index Tuning Wizard.  The process has improved over time (you can sort of [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2012/01/12/missing-indexes/">Missing Indexes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>SQL Server has means built into it to track possible missing indexes.  This used to be found through the use of the Index Tuning Wizard.  The process has improved over time (you can sort of see that from my <a href="http://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/">April Fools post</a>).</p>
<p>As luck would have it, I was recently asked to help fix a query that was somewhat related to the whole process.  You see, since SQL Server 2005, there are DMOs that help to track metadata related to column and index usage.  And if there a query is repeated enough that doesn&#8217;t have a good matching index, then the engine may think that a new index is needed.  This potential index information is recorded and becomes visible via the DMOs.</p>
<p>The query that I was asked to help fix was a dynamic query within a cursor that read information from the DMOs in order to generate some missing index information.  That particular query was failing for a couple of reasons, but on the same token it gave me an idea to modify and adapt the query to something more in line with what I might use.  After all, the queries that I used were in need of updating and this gets me started in that direction.</p>
<p>First, a little on why the query was failing.  A common problem with dynamic queries is the placement of quotes and having enough quotes in all required locations.  When you start nesting more levels into a dynamic query, the more confusing the quotes can get.  When running into something like this, I like to print the statement that I am trying to build dynamically.  If it doesn&#8217;t look right, then adjust the quotes until it looks right.</p>
<p>The second reason it was failing was a simple oversight.  Whether building dynamic queries or just using variables in your code, make sure you use properly sized variables.  In this case, the dynamic query variable was substantially inadequate.  The use of a print statement also helps to catch these types of errors rather quickly.</p>
<p>There were also a few things that would cause me to not use the original query in any environment.  The first problem is that the script contains a column which is the create statement for each proposed index.  In this create statement, all indexes were given the same name.  That would be a bit of a problem.</p>
<p>The next issue is my concern with the creation of indexes without ensuring that the index is going to provide greater benefit than cost.  Better stated is that the creation of these indexes just because the script spewed them out is no better than to create all of the indexes proposed by the Database Engine Tuning Advisor.  For this, I added a cautionary statement next to every index create statement.</p>
<p>So with these tweaks, as well as other less significant tweaks, here is the query.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE AllDatabases CURSOR FOR
SELECT [name] FROM master.dbo.sysdatabases WHERE dbid &amp;gt; 4

OPEN AllDatabases

DECLARE @DBNameVar NVARCHAR(128),@Statement NVARCHAR(max)

FETCH NEXT FROM AllDatabases INTO @DBNameVar
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT N'--CHECKING DATABASE ' + @DBNameVar
SET @Statement = N'USE [' + @DBNameVar + ']'+ CHAR(13) +';' +CHAR(13)
+ N'
SELECT SO.name
		, ((CONVERT(Numeric(19,6), migs.user_seeks)+CONVERT(Numeric(19,6), migs.unique_compiles))
			*CONVERT(Numeric(19,6), migs.avg_total_user_cost)
			*CONVERT(Numeric(19,6), migs.avg_user_impact/100.0)) AS Impact
		,''DO NOT AUTO CREATE THESE INDEXES - Creating these indexes could be as bad as blindly using DTA'' as Note
		, ''CREATE NONCLUSTERED INDEX IDX_'' + SO.name +''_'' + STUFF (
		(SELECT ''_'' + column_name FROM sys.dm_db_missing_index_columns(mid.index_handle) WHERE column_usage IN (''Equality'',''InEquality'') FOR XML PATH (''''))
		, 1, 1, '''')  + '' ON ['+@DBNameVar+'].'' + schema_name(SO.schema_id) + ''.'' + SO.name COLLATE DATABASE_DEFAULT + '' ( '' + IsNull(mid.equality_columns, '''') + CASE WHEN mid.inequality_columns IS NULL
		THEN ''''
		ELSE CASE WHEN mid.equality_columns IS NULL
		THEN ''''
		ELSE '','' END + mid.inequality_columns END + '' ) '' + CASE WHEN mid.included_columns IS NULL
		THEN ''''
		ELSE ''INCLUDE ('' + mid.included_columns + '')'' END + '';'' AS CreateIndexStatement
		, mid.equality_columns
		, mid.inequality_columns
		, mid.included_columns
	FROM sys.dm_db_missing_index_group_stats AS migs
		INNER JOIN sys.dm_db_missing_index_groups AS mig
			ON migs.group_handle = mig.index_group_handle
		INNER JOIN sys.dm_db_missing_index_details AS mid
			ON mig.index_handle = mid.index_handle
			AND mid.database_id = DB_ID()
		INNER JOIN sys.objects SO WITH (nolock)
			ON mid.OBJECT_ID = SO.OBJECT_ID
	WHERE (migs.group_handle IN
			(
			SELECT TOP (500) group_handle
			FROM sys.dm_db_missing_index_group_stats WITH (nolock)
			ORDER BY ((CONVERT(Numeric(19,6), migs.user_seeks)+CONVERT(Numeric(19,6), migs.unique_compiles))
				*CONVERT(Numeric(19,6), migs.avg_total_user_cost)
				*CONVERT(Numeric(19,6), migs.avg_user_impact/100.0)) DESC))
		AND OBJECTPROPERTY(SO.OBJECT_ID, ''isusertable'')=1
	ORDER BY 2 DESC , 3 DESC' 

PRINT @Statement
EXEC sp_executesql @Statement
PRINT CHAR(13) + CHAR(13)
FETCH NEXT FROM AllDatabases INTO @DBNameVar
END

CLOSE AllDatabases
DEALLOCATE AllDatabases</pre><p>[/codesyntax]</p>
<p>As I post this message, as I tend to do, I am looking for ways to improve upon the query and make it better.  This script should only be used with caution.  It is to provide an insight into potential missing indexes in each database.  A score is assigned to each potential index.  It is with the highest score indexes, that I typically begin analysis to improve performance.  I typically start from a query and execution plan to performance tune.  There are times when an alternative starting point is necessary.  This script is a tool for those times.  Please head the warning that these should be created with extreme caution.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1563" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2012/01/12/missing-indexes/">Missing Indexes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2012/01/12/missing-indexes/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Public Role and Security</title>
		<link>https://jasonbrimhall.info/2011/12/20/public-role-and-security/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=public-role-and-security</link>
					<comments>https://jasonbrimhall.info/2011/12/20/public-role-and-security/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Dec 2011 10:24:43 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1514</guid>

					<description><![CDATA[<p>A good rule of thumb with the public role is to leave it be.  Do not add permissions to this role.  Add permissions on a per database  and per group of users basis.  Create roles within the database and grant permissions to that role - in each database.  And remember the rule of least privilege - don't grant more permissions to a user/role than necessary to perform the job function.  Just the same as in an airport - everybody has their role and it is strictly defined.  If the user need not have access - then don't grant the permissions.</p>
The post <a href="https://jasonbrimhall.info/2011/12/20/public-role-and-security/">Public Role and Security</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Having flown a fair amount lately, I was thinking about the various levels of security within an airport.  Part of that comes from seeing signs like the following all over the place.</p>
<p><img loading="lazy" class="alignleft size-full wp-image-1515" title="acces-interdit-toute-personne-non-autorisee" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/acces-interdit-toute-personne-non-autorisee.jpg" alt="" width="550" height="550" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/acces-interdit-toute-personne-non-autorisee.jpg 550w, https://jasonbrimhall.info/wp-content/uploads/2011/12/acces-interdit-toute-personne-non-autorisee-150x150.jpg 150w, https://jasonbrimhall.info/wp-content/uploads/2011/12/acces-interdit-toute-personne-non-autorisee-300x300.jpg 300w" sizes="(max-width: 550px) 85vw, 550px" /></p>
<p>&nbsp;</p>
<p>These signs are placed in various places for very good reason.  But seeing a sign such as this made me wonder about the various access levels in an airport and how they might relate to the database world.</p>
<p>Let&#8217;s start with some of the zones that might be recognizable in an airport.  First there is the ticketing counter.  This is a general access area open to the public.  Anybody can approach a ticketing counter whether they are intending to purchase a ticket or not.  Another area similar to this is frequently the baggage claim area.  These are common areas and generally less secure than other areas.</p>
<p>Next, you might encounter the concourses.  Only ticketed passengers and authorized airport personnel may enter these areas after some degree of screening.  From these areas you have greater access to the airplanes.  You have been explicitly granted permission to enter an aircraft and are required to have a separate pass for each craft you desire to board.  If I were to correlate this to security in SQL server, this would most closely match the db_datareader database role &#8211; for which explicit permission has to be granted for the user in order to access each additional database.</p>
<p>From this same area you may witness that there are several aircraft crews.  Each member filling a specific role.  There is a pilot, copilot, flight attendants and ground crew.  Each role may have different access throughout the airport.  And in the case of the flight crew, they have to be given access to each plane they will board.  A United Airlines flight crew cannot go and pilot a British Airways craft for instance &#8211; they are responsible for specific flights belonging to UA.</p>
<p>Another potential role is that of the control tower.  The personnel manning the tower have access to quite a bit more than a pilot or passenger.  They have access to communications between all flights and the ground within their airspace.  They are coordinating efforts and trying to make the whole thing go smoothly.  These guys are much more like the specialized server roles in SQL Server.  They can be passengers and have public access.  They can also assist in the piloting of a craft (if you believe what you see in the movies) while giving instruction for flight path, landing and takeoff.</p>
<p>The point is, there is highly segregated roles in an Airport and in the air when an aircraft is involved.  The same should be true in a database environment.  There are special server roles that include public, sysadmin, securityadmin, and diskadmin (amongst others).  Then there are specific database roles that come prepackaged as well as the ability to create any number of specific roles that you need to run your environment.</p>
<p>Now let&#8217;s step back out again to the airport example and the public access areas.  These are the least secure areas.  Also, there is a group of people that we should call public.  I am a part of this particular group.  Every person that enters an airport is a member of this group.  The crew piloting a craft is a member of this public group, but they are also members of other more restricted groups.</p>
<p>Being a member of just the public group does not get me permission to enter the pilots cabin.  It does not grant me permission to enter the flight control tower.  It does not even grant me permission to stand behind the ticket counter.  You wouldn&#8217;t want just any old Joe Schmoe entering those particular areas &#8211; so they become more secure.  And the public group is denied access.</p>
<p>Back to the public server role in SQL Server.  This <a href="http://msdn.microsoft.com/en-us/library/ms175892.aspx">role </a>is granted VIEW Any Database as well as Connect, but by default is limited to just those permissions.  Can that be changed?  Sure &#8211; just like I could walk behind the ticket counter or walk into a pilots cabin (the flight staff may occasionally allow you to take a peek &#8211; typically children though).</p>
<p>Just because it can be changed &#8211; doesn&#8217;t mean it should be done.  In the example of me taking a peek into the Pilots cabin, that is a one person permission being granted.  If I granted that permission to the public role in SQL Server, now everybody can do that same thing.  So think about it for a minute, do you really want everybody being able to change the schema in your database if you decide to grant alter any to public?  I really doubt it.</p>
<p>A good rule of thumb with the public role is to leave it be.  Do not add permissions to this role.  Add permissions on a per database  and per group of users basis.  Create roles within the database and grant permissions to that role &#8211; in each database.  And remember the rule of least privilege &#8211; don&#8217;t grant more permissions to a user/role than necessary to perform the job function.  Just the same as in an airport &#8211; everybody has their role and it is strictly defined.  If the user need not have access &#8211; then don&#8217;t grant the permissions.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/12/access-forbidden-sign.jpg"><img loading="lazy" class="aligncenter size-full wp-image-1516" title="access-forbidden-sign" src="http://jasonbrimhall.info/wp-content/uploads/2011/12/access-forbidden-sign.jpg" alt="" width="250" height="250" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/12/access-forbidden-sign.jpg 250w, https://jasonbrimhall.info/wp-content/uploads/2011/12/access-forbidden-sign-150x150.jpg 150w" sizes="(max-width: 250px) 85vw, 250px" /></a>I want to re-iterate that point.  To help <a href="https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/server-and-database-roles-in-sql-server">prevent unauthorized access</a>, keep permissions in the public role to a minimum and create roles within the database to manage the different job functions as necessary/possible.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1514" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/12/20/public-role-and-security/">Public Role and Security</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/12/20/public-role-and-security/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>A Trio of Tools</title>
		<link>https://jasonbrimhall.info/2011/11/15/a-trio-of-tools/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-trio-of-tools</link>
					<comments>https://jasonbrimhall.info/2011/11/15/a-trio-of-tools/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 15 Nov 2011 13:00:10 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Tools]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1442</guid>

					<description><![CDATA[<p>I have talked about tools for SQL server a few times in the past.  You can read some of what I wrote here and here. Since writing those last articles, I have come across more [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/11/15/a-trio-of-tools/">A Trio of Tools</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I have talked about tools for SQL server a few times in the past.  You can read some of what I wrote <a href="http://jasonbrimhall.info/2011/03/17/database-tools/">here</a> and <a href="http://jasonbrimhall.info/2011/03/18/database-tools-follow-up/">here</a>.</p>
<p>Since writing those last articles, I have come across more tools here and there.  Over the past few weeks, I came across three that stood out and I wanted to give them a quick shout out.</p>
<p><a href="http://www.ssmstoolspack.com/Download">SSMS Tools Pack</a>:  I have already written about this tool.  It was recently updated and the functionality has been improved since I last wrote about it.  Not only did that functionality improve, but the feature set is better now too!.  Go give it a try.</p>
<p><a href="http://ssisreportingpack.codeplex.com/" class="broken_link">SSIS Reporting Pack</a>:  This tool is available on Codeplex.  This is one of those things that could be queried from TSQL, but this gives an interface (SSRS reports) for you to browse the information.  The same kind of reporting pack would be very useful for SSRS.  I know people ask from time to time for this kind of information in both products.  Hence the usefulness of these tools would be pretty high.</p>
<p><a href="https://www.sqlservercentral.com/blogs/new-version-of-sql-treeo-ssms-productivity-add-in-was-released">SQL Treeo</a>: Straight up, this tool was created to add customization to the tree view that you get with the default SSMS.  Some (many) find that the inability to customize this tree is inadequate.  This tool allows you the ability to create custom folders for the various objects.  This lends itself to being able to sort the tree in SSMS a bit differently.  Also, it can lead to being a bit more productive for many database professionals.</p>
<p>Check the tools out.  Test them and see if you like them.  Let the creator of each of these tools know what you think about their product.  Other than writing about the tools, I personally have no affiliation with any of the tools.  But I do think they would be good tools and are <strong>certainly worth the effort of testing for yourself</strong>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1442" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/11/15/a-trio-of-tools/">A Trio of Tools</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/11/15/a-trio-of-tools/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>SSSOLV November 2011 Meeting</title>
		<link>https://jasonbrimhall.info/2011/11/07/sssolv-november-2011-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sssolv-november-2011-meeting</link>
					<comments>https://jasonbrimhall.info/2011/11/07/sssolv-november-2011-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 07 Nov 2011 16:32:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1433</guid>

					<description><![CDATA[<p>Another month, another meeting.  Time really is flying.  And now with more Holidays fast approaching, I am sure that time will warp on us. The Las Vegas user group is happy to announce that we [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/11/07/sssolv-november-2011-meeting/">SSSOLV November 2011 Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Another month, another meeting.  Time really is flying.  And now with more Holidays fast approaching, I am sure that time will warp on us.</p>
<p>The Las Vegas user group is happy to announce that we have a new topic and new presenter (new to us anyway) for the month of November.  Norm Kelm is prepared to teach us a few things about his new hammer.</p>
<h3>POWERSHELL, THE NEW SQL HAMMER</h3>
<p>You&#8217;ve seen all the amazing scripts that use PowerShell, but writing your own is raising more questions. This session will help fill in the gaps by explaining all the moving parts of PowerShell 2.0, the integration with SQL Server and answer the following questions as well as others. Why is Invoke-Sqlcmd necessary? What is and why is there a Minishell for SQL Server? What makes the SQLSERVER: PS Drive so powerful? How does a remote SQL Server get added to the SQLSERVER: PS Drive?</p>
<h3>Norms Bio</h3>
<p>Norman Kelm is the owner of Gerasus Software, http://www.gerasus.com/, the maker of SSIS-DTS Package Search the only utility that can search SSIS and DTS packages. Norman has been working in IT for over 20 years. He worked as a FORTRAN and C developer for 8 years before making the jump to databases with Sybase. He then moved on to SQL Server working as a production and development DBA on SQL Server since version 6.5. He is also a founding member of the Tampa Bay SQL Server User Group.</p>
<p>We welcome all to attend (as we do every month).  Here is the online meeting information:</p>
<p><strong>LiveMeeting Information</strong>:<br />
Attendee URL: https://www.livemeeting.com/cc/UserGroups/join?id=2JK8TZ&amp;role=attend<br />
Meeting ID: 2JK8TZ</p>
<p><strong>In Person Attendees:</strong><br />
The meeting location has changed.  We will no longer be meeting at The Learning Center.  New meeting location is M Staff Solutions &amp; Training / 2620 Regatta Drive Suite 102 Las Vegas, NV 89128.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1433" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/11/07/sssolv-november-2011-meeting/">SSSOLV November 2011 Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/11/07/sssolv-november-2011-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Haunting a Database Near You</title>
		<link>https://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=haunting-a-database-near-you</link>
					<comments>https://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 31 Oct 2011 12:00:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Server]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1418</guid>

					<description><![CDATA[<p>Today, we have a special Halloween edition.  For me, Halloween and computer geek go quite well together.  And thinking about it, I wanted to try to better understand if there was a correlation.  As a [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/">Haunting a Database Near You</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today, we have a special Halloween edition.  For me, Halloween and computer geek go quite well together.  And thinking about it, I wanted to try to better understand if there was a correlation.  As a DBA, have you wondered the same thing?</p>
<p>Well, I have a short list of five things that may help you to correlate your affinity for Halloween with your love for Databases.</p>
<h3>Tombstones</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/tombstone.gif"><img loading="lazy" class="alignleft size-full wp-image-1419" title="tombstone" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/tombstone.gif" alt="" width="161" height="200" /></a>Did you know that a tombstone is a legitimate thing in SQL Server?</p>
<p>Tombstones are replica related.  They are deleted items in the replica and are used to make sure the deleted item doesn&#8217;t get put back in the replica inadvertently.</p>
<p>You can read a lot more about tombstones from the msdn article <a href="http://msdn.microsoft.com/en-us/library/bb902838(v=sql.100).aspx">here</a>.</p>
<p>Tombstones are not unique to SQL Server.  These are commonplace in Active Directory as well.</p>
<p>&nbsp;</p>
<h3 style="text-align: right;">Ghosts</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/ghost.jpg"><img loading="lazy" class="alignright size-medium wp-image-1420" title="ghost" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/ghost-191x300.jpg" alt="" width="191" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/10/ghost-191x300.jpg 191w, https://jasonbrimhall.info/wp-content/uploads/2011/10/ghost.jpg 288w" sizes="(max-width: 191px) 85vw, 191px" /></a>Not all rows that are deleted move on to the afterlife quickly like they should.  Some like to hang around due to unfinished business.</p>
<p>The unfinished business in this case is the server running a cleanup thread.  This has to be done when the server is not too busy and has enough free resources to help these records move on to the afterlife.</p>
<p>You can see the evidence of these ghosts with specialized equipment.  By the use of a DMO, we can see the ghost record count on a per index basis.  The DMO is sys.dm_db_index_physical_stats.  Take a look at the ghost_record_count column in the returned record set.</p>
<p>With more specialized equipment, the engine takes care of the cleanup and removal of these ghosts.  <a href="http://www.sqlskills.com/blogs/paul/post/inside-the-storage-engine-ghost-cleanup-in-depth.aspx">Here </a>is an in-depth foray into the world of SQL ghost hunting.  Whatever you do, don&#8217;t cross the streams.</p>
<h3>Zombies</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/zombie.jpg"><img loading="lazy" class="alignleft size-full wp-image-1421" title="zombie" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/zombie.jpg" alt="" width="172" height="220" /></a>It&#8217;s alive!!</p>
<p>No, I killed it!!</p>
<p>It can&#8217;t be&#8230;How is it still alive?</p>
<p>The transaction will not commit and may get rolled back.  The zombie has reared its&#8217; ugly head.  A transaction that cannot commit but keeps going (or rolls back) due to an unrecoverable error is a zombie transaction.</p>
<p>From <a href="http://msdn.microsoft.com/en-us/library/aa258325.aspx">MSDN</a>, here is a more specific definition of a zombie.</p>
<p>Rowsets can become zombies if the internal resource on which they depend goes away because a transaction aborts.</p>
<h3 style="text-align: right;">Spawn</h3>
<p><img loading="lazy" class="alignright" title="Spawn" src="http://1.bp.blogspot.com/_dEwYZDt09yI/Rc0OSvHf8zI/AAAAAAAAAVs/kLFFzNkBvBw/s320/DEADLY_SPAWN-14.jpg" alt="" width="320" height="246" />The spawn of SQL server is not so much like the Spawn character of the comics.  Nor is it much like the spawn shown to the right.</p>
<p>That is unless it is not managed very well.  SQL can spawn multiple threads if the optimizer deems it necessary for a query.  This is also known as parallelism.</p>
<p>Parallelism can be a good thing or it can be a bad thing.  Understanding it can help keep it on the good side.  <a href="http://sqlblog.com/search/SearchResults.aspx?q=parallelism&amp;s=91" class="broken_link">You might want to check out some of Paul White&#8217;s articles on the topic</a>.</p>
<h3>Children of the Corn</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/corn.jpg"><img loading="lazy" class="alignleft size-medium wp-image-1422" title="corn" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/corn-300x198.jpg" alt="" width="300" height="198" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/10/corn-300x198.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/10/corn.jpg 400w" sizes="(max-width: 300px) 85vw, 300px" /></a>Well, this one is not really something in SQL server.  That said, every time I think of orphaned users in SQL server &#8211; children of the corn comes to mind.</p>
<p>An orphaned user is one in which the login SID does not match for one reason or another.  This makes it so that the user can no longer log in to SQL server.</p>
<p>If you don&#8217;t know about these kids, they can really make for a frustrating day.  Read more <a href="http://msdn.microsoft.com/en-us/library/ms175475.aspx">here</a>.</p>
<h3>Bonus</h3>
<p>I have just covered five things in SQL server that correlate quite closely to Halloween.  But this by no means is an exhaustive list.  For instance, an obvious correlation is the &#8220;KILL&#8221; command.  Another good one is the monster known as the Blob (read more about that monster <a href="http://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/">here</a> and <a href="http://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/">here</a>).</p>
<p>With the opportunity to have Halloween every day, it&#8217;s no wonder I like being a DBA.</p>
<h3><span style="color: #ff6600;">Happy Halloween</span></h3>
<p><img loading="lazy" class="alignnone" title="DeathStar Jack" src="http://www.mentalfloss.com/wp-content/uploads/2008/10/440deathstar.jpg" alt="" width="352" height="326" /></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1418" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/">Haunting a Database Near You</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/10/31/haunting-a-database-near-you/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>An Interesting Sort</title>
		<link>https://jasonbrimhall.info/2011/10/12/an-interesting-sort/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=an-interesting-sort</link>
					<comments>https://jasonbrimhall.info/2011/10/12/an-interesting-sort/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 12 Oct 2011 13:00:58 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1402</guid>

					<description><![CDATA[<p>I just came across a pretty peculiar sort requirement.  The requirement made me sit and think a bit.  Since it was somewhat peculiar, I decided I would share the solution. So, let&#8217;s start with a [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/10/12/an-interesting-sort/">An Interesting Sort</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I just came across a pretty peculiar sort requirement.  The requirement made me sit and think a bit.  Since it was somewhat peculiar, I decided I would share the solution.</p>
<p>So, let&#8217;s start with a little sample data, and then I can go over the requirements.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">create table #tempSort
(
        MerchantID      varchar(16),    
        POS             varchar(2),
        Amount          int
)

INSERT into #tempSort
VALUES ('ABC4567812345678', Null, Null);

INSERT into #tempSort
VALUES ('ABC45678ABC45678', Null, Null);

INSERT into #tempSort
VALUES ('1234567812345678', Null, Null);

INSERT into #tempSort
VALUES ('12345678ABC45678', Null, Null);</pre><p>[/codesyntax]</p>
<p>Now, we only really have one field that is sortable in this dataset.  And as the title of this post alludes, the sort of that field is not straight forward.  For this data, we need to have the results sorted alpha first and then numeric.</p>
<p>I looked at this and thought, that should be fixed (based on the data) by simply adding a &#8216;DESC&#8217; to the order by.  Oh but not, that is not entirely accurate.  More test data was added to the sample set with more requirements.  So let&#8217;s expand the data set first.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">create table #tempSort
(
        MerchantID      varchar(16),    
        POS             varchar(2),
        Amount          int
)

INSERT into #tempSort
VALUES ('ABC4567812345678', Null, Null);

INSERT into #tempSort
VALUES ('ABC45678ABC45678', Null, Null);

INSERT into #tempSort
VALUES ('1234567812345678', Null, Null);

INSERT into #tempSort
VALUES ('12345678ABC45678', Null, Null);

INSERT into #tempSort
VALUES ('ABC45678ZXY4567', Null, Null);

INSERT into #tempSort
VALUES ('XYZ45678ZXY4567', Null, Null);</pre><p>[/codesyntax]</p>
<p>With this expanded data, it becomes obvious that a simple &#8216;DESC&#8217; will not fix the issue.  That would place anything the XYZ entry at the top of the list.  But wait, take a look at the second Alpha sequence in the strings.  That complicates things a tiny bit more.  That second alpha sequence also has to be sorted ahead of anything that is numeric.  To further complicate it &#8211; it must be in ASC order alpha then numeric as well.</p>
<h3>TaDa</h3>
<p>So, with a little testing and a nifty trick I was able to come up with something that works.  Let&#8217;s take a look at it.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT MerchantID
	from #tempSort
	ORDER BY CASE WHEN ISNUMERIC(LEFT(merchantID,3)) = 1 THEN 1 ELSE 0 END ASC
			,LEFT(merchantID,8) ASC
			,CASE WHEN ISNUMERIC(REVERSE(right(REVERSE(right(merchantid,LEN(MerchantID)-8)),3))) = 1 THEN 1 ELSE 0 END</pre><p>[/codesyntax]</p>
<p>You will see that I have three conditions in my Order By clause.  Two of those contain a case statement.  By checking to see if something is numeric, I can make sure alpha is placed before numeric.  By including the middle condition, I was able to ensure the correct order for the first alpha sequence.  Without this middle condition, the Alpha strings were all returned before the numeric, but the Alpha was not ordered properly.</p>
<h3>Recap</h3>
<p>Despite some really odd strings to be ordered and out of the ordinary sorting requirements, it is possible with a little thinking.  My biggest friend here in this requirement was the use of the case statement.  Using the CASE really helped to simplify what I needed to achieve.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1402" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/10/12/an-interesting-sort/">An Interesting Sort</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/10/12/an-interesting-sort/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>October 2011 LV UG Meeting</title>
		<link>https://jasonbrimhall.info/2011/10/11/october-2011-lv-ug-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=october-2011-lv-ug-meeting</link>
					<comments>https://jasonbrimhall.info/2011/10/11/october-2011-lv-ug-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Oct 2011 15:58:40 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1396</guid>

					<description><![CDATA[<p>Boo! OK, so it really isn&#8217;t that scary.  But it is that time of year and we happen to have something that could fix something that might be scary. It is time once again for [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/10/11/october-2011-lv-ug-meeting/">October 2011 LV UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/pumpkin.jpg"><img loading="lazy" class="alignleft size-medium wp-image-1397" title="pumpkin" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/pumpkin-300x208.jpg" alt="" width="300" height="208" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/10/pumpkin-300x208.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/10/pumpkin.jpg 488w" sizes="(max-width: 300px) 85vw, 300px" /></a>Boo!</h3>
<p>OK, so it really isn&#8217;t that scary.  But it is that time of year and we happen to have something that could fix something that might be scary.</p>
<p>It is time once again for our S3OLV Group meeting.  And this month we have two presentations.</p>
<p>Before jumping into more details on that, here is the rest of what the invite would look like if you received it in email.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/10/invite.jpg"><img loading="lazy" class="alignright size-medium wp-image-1398" title="invite" src="http://jasonbrimhall.info/wp-content/uploads/2011/10/invite-300x209.jpg" alt="" width="300" height="209" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/10/invite-300x209.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/10/invite.jpg 488w" sizes="(max-width: 300px) 85vw, 300px" /></a></p>
<p>&nbsp;</p>
<h3>Guts N Grime</h3>
<p>Presenting for us this month will be Charley Jones and Julie Rasnick.  (Not necessarily in that order.)</p>
<p>Julie is undertaking the ghoulish challenge of teaching us how to partition.  In our world of ever increasing data and requirements to continue to retain more and more data, partitioning could be a scary undertaking &#8211; yet very critical.</p>
<p>Charley is going to teach you everything you ever wanted to know about certificates and probably some things you didn&#8217;t want to know ;).  Again, this is another one of those topics that should be of high value in this day and age of increased need for data security.</p>
<p>In case you can&#8217;t see it in the image, the meeting is 13 October from 6:30 PM Pacific.</p>
<h3>Phantom Hauntings</h3>
<p>Many of you will not be able to attend in person.  That is perfectly fine.  Many will be attending the valuable offerings of Summit 2011 &#8211; I get that.  Come haunt our meeting anyway.  We are making the meeting available via livemeeting (or would that be deadmeeting?) for any of you wishing to get that little bit of extra content/learning.  I would love to flood the livemeeting servers with 2-300 Summit attendees for the Las Vegas Chapter meeting.</p>
<p>You can join our meeting for free via the following link.</p>
<p>Attendee URL: https://www.livemeeting.com/cc/UserGroups/join?id=9PWSCW&amp;role=attend!!<br />
Meeting ID: 9PWSCW</p>
<h3>It&#8217;s alive!!</h3>
<p>For any of you zombies out there that may not have heard, SQLSat Las Vegas is in the works.  We have reserved a date &#8211; March 10, 2012.  We have the venue as well.  Check out my other writeup on it <a href="http://jasonbrimhall.info/2011/09/14/what-happens-in-vegas/">here</a>.  We want to make this event work and hope to see many of you there &#8211; spread the word.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1396" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/10/11/october-2011-lv-ug-meeting/">October 2011 LV UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/10/11/october-2011-lv-ug-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Stored Procedures &#8211; Common Security Practice</title>
		<link>https://jasonbrimhall.info/2011/09/20/stored-procedures-common-security-practice/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stored-procedures-common-security-practice</link>
					<comments>https://jasonbrimhall.info/2011/09/20/stored-procedures-common-security-practice/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Sep 2011 20:58:16 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Audit]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1388</guid>

					<description><![CDATA[<p>In SQL Server a good practice is to access the data via calls through stored procedure.  Have a look at the document available in that link. To further this practice, one may create a database [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/09/20/stored-procedures-common-security-practice/">Stored Procedures – Common Security Practice</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In SQL Server a good practice is to <a href="http://www.microsoft.com/technet/prodtechnol/sql/2005/sql2005secbestpract.mspx" class="broken_link">access the data via calls through stored procedure</a>.  Have a look at the document available in that link.</p>
<p>To further this practice, one may create a database role, then add users to that role.  Permissions to execute the stored procedures would then be granted to the role.  A role is simple enough to create.  You can do that with the following code.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE ROLE db_executor</pre><p>[/codesyntax]</p>
<p>After creating this role, simply add users to that role.  The next part of the process is to ensure that you have granted the appropriate permissions to this role.  There are two methods to do that: 1) blanket execute to all procedures, and 2) pick and choose the procs to which you wish to grant permission.</p>
<p>Before we get to adding permissions, let&#8217;s create a little test proc for testing purposes.  I will reuse something from a past article to simplify.  In that article, I already did the setup for the table &#8211; you can get it from <a href="http://jasonbrimhall.info/2011/08/19/bitwise-operations/">here</a>.  The stored procedure is as follows.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE PROCEDURE colorwheel
	@ColorType INT = 3

AS
SET NOCOUNT ON
BEGIN 
	SELECT cp1.*
		FROM ColorPlate cp1
		WHERE cp1.colortype &amp;amp; @ColorType &amp;lt;&amp;gt; 0 
		ORDER BY ColorID;
END</pre><p>[/codesyntax]</p>
<p>Let&#8217;s also make sure that the user has been added to the role.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">exec sp_addrolemember 'db_executor', 'testu'</pre><p>[/codesyntax]</p>
<p>As for the exercise in how to create that database user and the associated login, I will leave that for you to do.</p>
<p>In order to test, we need to connect to the SQL Server as that user.  Once connected, run the following to verify that your session is connected as desired.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT SYSTEM_USER AS LoggedInUser</pre><p>[/codesyntax]</p>
<p>On my connection, running that query will show that the LoggedInUser is testu.  Now, having confirmed that I am connected as the appropriate user, I will try to execute that test proc we created.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">EXEC colorwheel</pre><p>[/codesyntax]</p>
<p>At this point, the expected results should be similar to this error message.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Msg 229, Level 14, State 5, Procedure colorwheel, Line 1
The EXECUTE permission was denied on the object 'colorwheel', database 'TestA', schema 'dbo'.</pre><p>[/codesyntax]</p>
<p>Now, I will switch over to the previous connection where I have administrative permissions.  I will now proceed to grant execute permissions following the first method &#8211; blanket grant.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">GRANT EXECUTE TO db_executor
go</pre><p>[/codesyntax]</p>
<p>And now, flip back to the user connection to test our permissions.  Try running that proc again, and your results should be similar to these.</p>
<table border="0">
<tbody>
<tr>
<td>ColorID</td>
<td>ColorPlate</td>
<td>ColorType</td>
</tr>
<tr>
<td>1</td>
<td>Red</td>
<td>1</td>
</tr>
<tr>
<td colspan="1">2</td>
<td colspan="1">Blue</td>
<td colspan="1">2</td>
</tr>
</tbody>
</table>
<p>That is good, but what else can this user now do?  The user can execute all user created stored procedures.  Do you necessarily want this?  What if your business requirements specify that certain user groups be able to execute only certain procs?</p>
<p>In that case, we now need to grant execute permissions on a more granular level.  A big problem with this method pops up right from the beginning.  What if there are thousands of stored procedures?  What if you need to grant execute permissions to hundreds of stored procedures for each role?</p>
<p>We have two avenues for these types of situations.  One avenue is to separate the various stored procedures via schema and then grant execute to the schema.  The other is via naming convention.</p>
<p>In the event you have a suitable naming convention to help mass assign permissions, here is a little script to help.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT 'Grant Execute on ' + NAME + 'to [db_executor]'
	FROM sys.objects
		WHERE type = 'p'
			AND Name LIKE '%usp_rs_%'</pre><p>[/codesyntax]</p>
<p>It is very simplistic, I know.  I also left an example of such a naming scheme.  In this example, the naming convention may imply that the procedure is a Reporting Services stored procedure.  I can query for all of the Reporting Services procs in the database, and then assign permissions to all of them much faster.</p>
<p>This method does not immediately grant permissions to the entire result set.  It does allow for you to review the results.</p>
<p>Are there more elaborate examples out there?  Certainly.  Find a method that suits you.  I would be very careful about using the first method though &#8211; it just might be too much granted to the user.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1388" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/09/20/stored-procedures-common-security-practice/">Stored Procedures – Common Security Practice</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/09/20/stored-procedures-common-security-practice/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Performance Tuning &#8211; Over the Top Biz Logic</title>
		<link>https://jasonbrimhall.info/2011/09/19/performance-tuning-over-the-top-biz-logic/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=performance-tuning-over-the-top-biz-logic</link>
					<comments>https://jasonbrimhall.info/2011/09/19/performance-tuning-over-the-top-biz-logic/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 19 Sep 2011 13:30:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[performance tune]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[TCPIP]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1368</guid>

					<description><![CDATA[<p>This month, Robert Pearl is helping to host a Performance Story contest.  The contest is being sponsored by Safe Peak, and you can see more about it &#8211; here. The timing on this contest actually [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/09/19/performance-tuning-over-the-top-biz-logic/">Performance Tuning – Over the Top Biz Logic</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This month, Robert Pearl is helping to host a Performance Story contest.  The contest is being sponsored by Safe Peak, and you can see more about it &#8211; <a href="http://www.safepeak.com/SQL-Performance-Contest-2011/?source=PearlKnowledge">here</a>.</p>
<p>The timing on this contest actually fits well with something I have already been working on.  The only delay has been related to getting everything scrubbed and obfuscated.  There is a lot that could be included with this particular experience, I plan on touching on two of the key areas.</p>
<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/trippyclock.jpg"><img loading="lazy" class="alignleft size-full wp-image-1369" title="trippyclock" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/trippyclock.jpg" alt="" width="216" height="216" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/09/trippyclock.jpg 450w, https://jasonbrimhall.info/wp-content/uploads/2011/09/trippyclock-150x150.jpg 150w, https://jasonbrimhall.info/wp-content/uploads/2011/09/trippyclock-300x300.jpg 300w" sizes="(max-width: 216px) 85vw, 216px" /></a>Backstory</h3>
<p>I have been working a lot lately with building reports in SSRS.  These reports had been working great from IE hitting directly to the SSRS Server in one environment.  When we migrated the reports to the production environment &#8211; we started seeing some serious timeout issues.</p>
<p>There was one report in particular that was giving more grief than others.  I had already gone through everything I could find with regards to SSRS in trying to help speed these reports up to acceptable times.</p>
<p>Having gone through what could be done in SSRS, I next turned my attention to the main stored procedure creating the data-set for the report.</p>
<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/double.jpg"><img loading="lazy" class="alignright size-full wp-image-1370" title="Seeing Double" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/double.jpg" alt="" width="270" height="237" /></a>Stored Procedure</h3>
<p>Although the report was not even making it to this particular stored procedure &#8211; I wanted to take a look at it and make any improvements there that I could.  It made sense to eliminate it as a possible source of the problem.</p>
<p>I opened up the stored procedure and found a fair amount if Business Logic.  I came to a section of the proc that contained code that at first sight, made my head spin a bit.  I thought for sure I was seeing double because of all of the logic.</p>
<p>Once I finally got my head wrapped around it, I noticed a lot of similarities and wanted to start from that particular section with my tuning.  Here is an obfuscated version of what I saw.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @CompareParam INT = 200

		SELECT tccv.MyColumn
			from dbo.table1 as cb
				INNER JOIN dbo.table2 tcfbt
					on cb.column1 = tcfbt.column1fk
    			INNER JOIN dbo.table3 as cpd
    				on cb.column2 = cpd.column2fk
				INNER JOIN dbo.table4 as tcfcpt
					on cpd.column3 = tcfcpt.column3fk
				INNER JOIN dbo.table5 as tcfcpct
					on cpd.column4 = tcfcpct.column4fk
				INNER JOIN dbo.table6 cp
					on cb.column5 = cp.column5fk
				INNER JOIN dbo.table7 cal
					on cp.column6 = cal.column6fk
				INNER JOIN dbo.table8 tgmc
					on cal.column7 = tgmc.column7fk
				INNER JOIN dbo.table9 tccv
					on tgmc.column8 = tccv.column8fk
				INNER JOIN dbo.table10 fps
					on cp.column9 = fps.column9fk
        where
            cb.column5 = @CompareParam
	        and
	        (
	            tcfbt.CodeVal = 'In-Progress'   -- use cases 1,2,3
	            and
                (
                    ( -- use case 1
                        cp.column5fk = @CompareParam
                        and fps.CodeVal not in ('Val1','Val2')
                        and tccv.Date1 between cp.Date2 and ISNULL(cp.Date3, cp.Date4)
                    )
                    --use case 2
                    or
                    ( cp.column5fk = @CompareParam
						and tccv.Date1 &amp;lt; cp.Date2
						and not exists (
							select 1
								from dbo.table11 cvcp
									INNER JOIN dbo.table6 prevcp
										on cvcp.column5 = prevcp.column5fk
									INNER JOIN dbo.table10 prevfps
										on prevfps.column9fk = prevcp.column9
								where prevcp.column6 = cp.column6
									and prevcp.Date4 &amp;lt; cp.Date2
									and cvcp.MyColumnfk = tccv.MyColumn
									and prevfps.CodeVal in ('Val1','Val2')
						)
						and exists (
							select 1
								from dbo.table6 as pastcp
									INNER JOIN dbo.table10 as pastfps
										on pastcp.column9 = pastfps.column9fk
								where pastcp.column6 = cp.column6
									and pastcp.Date4 &amp;lt; cp.Date2
									and tccv.Date1 between pastcp.Date2 and pastcp.Date4
									and pastfps.CodeVal in ('Val1','Val2')
						)
                    )
                )
             )
             or
             (
				-- same as the other side of 'OR' just above
                 tcfbt.CodeVal = 'Live'
				and not exists (
					select 1
						from dbo.table12 cvh
						where tccv.MyColumn = cvh.MyColumnfk
				 )
                 and
                 (
                    ( -- use case 1
                        cp.column5fk = @CompareParam
                        and fps.CodeVal not in ('Val1','Val2')
                        and tccv.Date1 between cp.Date2 and ISNULL(cp.Date3, cp.Date4)
                    )
                    --use case 2
                    or
                    (
						cp.column5fk = @CompareParam
						and tccv.Date1 &amp;lt; cp.Date2
						and not exists (
							select 1
								from dbo.table11 cvcp
									INNER JOIN dbo.table6 prevcp
										on cvcp.column5fk = prevcp.column5fk
									INNER JOIN dbo.table10 as prevfps
										on prevcp.column9 = prevfps.column9fk
								where prevcp.column6 = cp.column6
									and prevcp.Date4 &amp;lt; cp.Date2
									and cvcp.MyColumnfk = tccv.MyColumn
									and prevfps.CodeVal in ('Val1','Val2')
						)
						and exists (
							select 1
								from dbo.table6 as pastcp
								INNER JOIN dbo.table10 as pastfps
									on pastcp.column9 = pastfps.column9fk
							where pastcp.column6 = cp.column6
								and pastcp.Date4 &amp;lt; cp.Date2
								and tccv.Date1 between pastcp.Date2 and pastcp.Date4
								and pastfps.CodeVal in ('Val1','Val2')
						)
                    )
				)
	          )</pre><p>[/codesyntax]</p>
<p>I want you to look closely at both sides of that OR condition in the where clause before proceeding to look at the image of the execution plan that this query generates.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/Bizlogic_duped.jpg"><img loading="lazy" class="alignnone size-thumbnail wp-image-1371" title="Bizlogic_duped" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/Bizlogic_duped-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Again, my head started spinning when I first looked at the execution plan.  It was the size of the overall plan that was causing it this time.  Looking through it though, I quickly saw what I thought was the main point of slowness with this query (yes it was slow).  If you open the image of that execution plan and compare the red section to the yellow section, you will see that it is duplicated.  These sections also correlate to each side of the OR condition that was already mentioned.</p>
<p>When browsing this execution  plan in SSMS, I was also lured into these sections due to a bad estimate on the query cost (which you don&#8217;t see in this image).  All of the Index Spools and Index scans/seeks had a cost of 89% attached to them (within the red and yellow regions).  Seeing that both sections were identical &#8211; I was certain that the OR condition could be optimized.</p>
<h3>DeDuping</h3>
<p>Since the queries were soooo similar, I knew there had to be a way to combine both sides and make it less costly.  After working on it a bit, I came up with the following query.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @CompareParam INT = 200

		SELECT tccv.MyColumn
			from dbo.table1 as cb
				INNER JOIN dbo.table2 tcfbt
					on cb.column1 = tcfbt.column1fk
    			INNER JOIN dbo.table3 as cpd
    				on cb.column2 = cpd.column2fk
				INNER JOIN dbo.table4 as tcfcpt
					on cpd.column3 = tcfcpt.column3fk
				INNER JOIN dbo.table5 as tcfcpct
					on cpd.column4 = tcfcpct.column4fk
				INNER JOIN dbo.table6 cp
					on cb.column5 = cp.column5fk
				INNER JOIN dbo.table7 cal
					on cp.column6 = cal.column6fk
				INNER JOIN dbo.table8 tgmc
					on cal.column7 = tgmc.column7fk
				INNER JOIN dbo.table9 tccv
					on tgmc.column8 = tccv.column8fk
				INNER JOIN dbo.table10 fps
					on cp.column9 = fps.column9fk
        where
            cb.calendarPeriodID = @CompareParam
	        and
	        (
	           ( tcfbt.CodeVal = 'In-Progress'   -- use cases 1,2,3
						OR (tcfbt.CodeVal = 'Live'
							and not exists (
								select 1
									from dbo.table12 cvh
									where tccv.MyColumn = cvh.MyColumnfk
							)
						)
					)
	            and
                (
                    ( -- use case 1
                        cp.column5fk = @CompareParam
                        and fps.CodeVal not in ('Val1','Val2')
                        and tccv.Date1 between cp.Date2 and ISNULL(cp.Date3, cp.Date4)
                    )
                    --use case 2
                    or
                    ( cp.column5fk = @CompareParam
						and tccv.Date1 &amp;lt; cp.Date2
						and not exists (
							select 1
								from dbo.table11 cvcp
									INNER JOIN dbo.table6 prevcp
										on cvcp.column5fk = prevcp.column5fk
									INNER JOIN dbo.table10 prevfps
										on prevfps.column9fk = prevcp.column9
								where prevcp.[calendarID] = cp.[calendarID]
									and prevcp.Date4 &amp;lt; cp.Date2
									and cvcp.MyColumnfk = tccv.MyColumn
									and prevfps.CodeVal in ('Val1','Val2')
						)
						and exists (
							select 1
								from dbo.table6 as pastcp
									INNER JOIN dbo.table10 as pastfps
										on pastcp.column9 = pastfps.column9fk
								where pastcp.column6 = cp.column6
									and pastcp.Date4 &amp;lt; cp.Date2
									and tccv.Date1 between pastcp.Date2 and pastcp.Date4
									and pastfps.CodeVal in ('Val1','Val2')
						)
                    )
                )
             )</pre><p>[/codesyntax]</p>
<p>Now take a close look at the first part of the where clause.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">where
            cb.calendarPeriodID = @CompareParam
	        and
	        (
	           ( tcfbt.CodeVal = 'In-Progress'   -- use cases 1,2,3
						OR (tcfbt.CodeVal = 'Live'
							and not exists (
								select 1
									from dbo.table12 cvh
									where tccv.MyColumn = cvh.MyColumnfk
							)
						)
					)
	            and</pre><p>[/codesyntax]</p>
<p>That little change represents the only difference between the two sides of the Or condition in the prior query.  The result set is exactly the same.  Now we get a new execution plan that looks like this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/Bizlogic_deduped.jpg"><img loading="lazy" class="alignnone size-thumbnail wp-image-1374" title="Bizlogic_deduped" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/Bizlogic_deduped-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>In this execution plan, you can see that there is now only one section matching the red and yellow sections from the previous query.  This is a very good thing.  We can see that the plan looks simpler than the last one.  What about if we execute the two queries in a single batch for comparison?</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/bizlogic_directcompare1.jpg"><img loading="lazy" class="alignnone size-thumbnail wp-image-1376" title="bizlogic_directcompare" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/bizlogic_directcompare1-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>&nbsp;</p>
<p>The improvements we see are substantial.  Look at the difference in cost comparison between the two!!  The old query consumes 97% of the cost.  To further illustrate the improvements by making this little change in logic, let&#8217;s take a look at the time.</p>
<figure id="attachment_1377" aria-describedby="caption-attachment-1377" style="width: 270px" class="wp-caption alignleft"><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withExecplan.jpg"><img loading="lazy" class="size-medium wp-image-1377 " title="Timecompare_withExecplan" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withExecplan-300x172.jpg" alt="Timecompare_withExecplan" width="270" height="155" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withExecplan-300x172.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withExecplan.jpg 314w" sizes="(max-width: 270px) 85vw, 270px" /></a><figcaption id="caption-attachment-1377" class="wp-caption-text">Timecompare_withExecplan</figcaption></figure>
<figure id="attachment_1378" aria-describedby="caption-attachment-1378" style="width: 212px" class="wp-caption alignright"><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withoutExecplan.jpg"><img loading="lazy" class="size-full wp-image-1378" title="Timecompare_withoutExecplan" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/Timecompare_withoutExecplan.jpg" alt="Timecompare_withoutExecplan" width="212" height="123" /></a><figcaption id="caption-attachment-1378" class="wp-caption-text">Timecompare_withoutExecplan</figcaption></figure>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Looking at the time it takes to run these queries should also be a strong indicator of the performance gains made by simplifying that where clause.  Let&#8217;s also take a look at another couple of screen-shots that helps to show some of the different improvements made by simplifying that &#8220;OR&#8221; condition.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dupe.jpg"><img loading="lazy" class="alignnone size-full wp-image-1379" title="stats_dupe" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dupe.jpg" alt="" width="1055" height="38" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dupe.jpg 1055w, https://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dupe-300x10.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dupe-1024x36.jpg 1024w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dedupe.jpg"><img loading="lazy" class="alignnone size-full wp-image-1380" title="stats_dedupe" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dedupe.jpg" alt="" width="907" height="37" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dedupe.jpg 907w, https://jasonbrimhall.info/wp-content/uploads/2011/09/stats_dedupe-300x12.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>Notice the old plan has an index scan, sort operation and 61 parallel operations.  The new plan has a key lookup.  Now look at the glaring difference between the two in estimated rows.  That is significant.</p>
<p>That is not all that was done with the query itself to improve performance.  Other things like index tuning and more work on the rest of the query was also done with some improvements in overall execution of the query.  But none were as significant as this.</p>
<h3>TCP/IP</h3>
<p>The other place where significant improvement was made in the performance of this query came from something outside of SQL Server.  A key part of this exercise has not yet been mentioned.  The reports were all taking 30-60 seconds to even load without any parameters having been selected.  Then they would take another 30 seconds or so after that to bring up the next parameter.</p>
<p>We ran a trace between the two servers to see what we could find.  After some more troubleshooting, we decided to try <a href="http://blogs.msdn.com/b/psssql/archive/2008/10/01/windows-scalable-networking-pack-possible-performance-and-concurrency-impacts-to-sql-server-workloads.aspx">disabling the TCP Chimney</a>.  This change had a significant impact in loading the reports from SSRS.  From within IE, these reports were now immediately loading and the prompt flow became very responsive.</p>
<h3>Conclusion</h3>
<p>Taking a little bit of extra time when writing out the logic for your queries can have a profound impact on the responsiveness of your queries.  In this case, simplifying the code but retaining the logic had a tremendous effect on overall performance.</p>
<p>In addition to what can be done in SQL Server, sometimes one needs to look outside of SQL to the network or disk layer for further tuning.  Working with the appropriate teams to accomplish those goals can go miles to having a positive effect on co-workers and application experience by the business users.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1368" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/09/19/performance-tuning-over-the-top-biz-logic/">Performance Tuning – Over the Top Biz Logic</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/09/19/performance-tuning-over-the-top-biz-logic/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #22 – Data Presentation</title>
		<link>https://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-22-data-presentation</link>
					<comments>https://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 13 Sep 2011 17:54:30 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1349</guid>

					<description><![CDATA[<p>Data Presentation is not just about the look of a report.  Data Presentation involves performance, accuracy, display and the business requirements.  By giving proper attention to each of these facets, the Data presented will be both remarkable and acceptable to the end-user.</p>
The post <a href="https://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/">T-SQL Tuesday #22 – Data Presentation</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.sqlservercentral.com/blogs/invitation-for-t-sql-tuesday-22-%e2%80%93-data-presentation"><img loading="lazy" class="alignleft size-full wp-image-1350" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2011/09/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>Tuesday is upon us.  It also happens to be the second Tuesday of the month and you know what that means.  It is time for TSQL Tuesday.  This month, Robert Pearl, a friend, is hosting.  Read his invitation <a href="https://www.sqlservercentral.com/blogs/invitation-for-t-sql-tuesday-22-%e2%80%93-data-presentation">here</a>.</p>
<p>As the invitation suggests, this topic is wide open.  There are many ways to present data.  Some of those methods may be better than others.  There are a few things of note with Data Presentation that will impact how much better your Data Presentation will be.</p>
<p>The items I will discuss that will help your data be better presented are: Performance, Accuracy, Display, and Business Requirements.  I will use a few scripts to progress through each of these topics.  Let&#8217;s start with Performance.</p>
<h3>Performance</h3>
<p>Why is performance included in this discussion?  How does performance relate to data presentation?  Well, have you ever had an end-user complain that a report was utterly useless because it was too slow?  If the report is too slow, it won&#8217;t matter if the data is accurate in the eyes of some.  They needed to have the data yesterday and it simply took too long.</p>
<p>Here is an example of a query that could be optimized a bit more (admittedly this query does not perform soooo slowly that a user would give up on it &#8211; by the end you will see that it could perform better).</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @StartDate DATETIME = '2011-09-08'
		,@EndDate DATETIME = '2013-11-09'
		,@numMonths TINYINT
DECLARE @calendarTable TABLE (monthNum TINYINT, monthDays TINYINT)

SET @numMonths = (SELECT DATEDIFF(m,@StartDate,@EndDate) + 1)

WHILE @numMonths &amp;gt;= 1
        BEGIN
                INSERT INTO @calendarTable SELECT MONTH(@StartDate), DATEDIFF(d, @startDate, DATEADD(m, 1, DATEADD(d, 1 - DAY(@StartDate), @StartDate)))
                SET @numMonths = @numMonths - 1
                SET @StartDate = (SELECT DATEADD(m, 1, DATEADD(d, 1 - DAY(@StartDate), @StartDate)))
                --SELECT @StartDate
        END

SELECT * FROM @calendarTable

Go</pre><p>The requirements for this script are simple.  Provide the number of days in a month in a given date range.  If the starting date provided is not the first of the month, then we must only provide the number of days from that date to the end of the month.</p>
<p>As you can see, this script utilizes a looping mechanism to provide this information.  The loop inserts into a table variable one record at a time.  When examining the execution plan and the execution time on this query, one would see that the insert is the most expensive part of the query.  One would also find that this query does take a fair amount of time to run &#8211; despite its&#8217; simplicity.  On my machine, it takes about 1.3 seconds to execute.</p>
<p>Certainly, if this were a more complicated query, one would see that this type of query could cause some delays in data rendering and subsequently cause grief for the end-user and you.</p>
<p>There is one more issue with the provided query in that it doesn&#8217;t meet all requirements.  I neglected to mention that the date format needs to accept date/month/year format.  Yes it is nitpicking, but it was a requirement and an invalid date is far too easy to submit with this query.</p>
<h3>Accuracy</h3>
<p>There should be no question on how accuracy affects data presentation.  No matter how pretty the rest of the data/report may look, wrong data will render the report useless in the eyes of many business users.</p>
<p>Again, this example is not extreme &#8211; but it does create sufficient concern that the query should not be used &#8211; unless fixed.</p><pre class="urvanov-syntax-highlighter-plain-tag">SET DATEFORMAT DMY

DECLARE @StartDate      DATE = '05/06/2011'
        ,@EndDate       DATE = '31/08/2012'

;
WITH getmonths AS (
        SELECT cast(Convert(varchar,'01/' + cast(MonthNum as varchar) + '/' + cast(yr.yr as varchar)) as Date) as Moy
                FROM ( VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) Mnths (MonthNum)
                Cross Apply (Select Year(@StartDate) as yr
                                                Union
                                                Select Year(@EndDate) as yr
                                        ) yr
), inputdates as (
        Select dates from (values (@StartDate),(@EndDate)) D (Dates)
        )

select DateName(m,g.moy) as MonthInRange,year(g.moy) as YrInRange
                ,DatePart(d,dateadd(mm, datediff(mm, 0, g.moy)+1, 0)-1)
                        - Case When datepart(d,id.Dates) = DatePart(d,dateadd(mm, datediff(mm, 0, g.moy)+1, 0)-1)
                                                Then 0
                                        When datepart(d,g.moy) &amp;lt; datepart(d,id.Dates)
                                                Then datepart(d,id.Dates)
                                        Else Isnull(datepart(d,id.Dates),datepart(d,g.moy)-1)
                                End as DaysInMonthInRange
        From getmonths g
                Left Outer Join inputdates Id
                        On datepart(m,g.moy) = datepart(m,id.Dates)
                        And year(g.moy) = year(id.Dates)
        Where g.moy between @StartDate and @EndDate
                Or id.Dates between @StartDate and @EndDate

Go</pre><p>Though this query works faster than the first query, it is not entirely accurate.  This query only supports a max of 12 months.  Also, this query is overly complex.  There is value in keeping this particular query more simple.</p>
<h3>Display</h3>
<p>This topic could be deemed to be largely a matter of preference.  That said, there is great value in how you display the data to the end user.  Displaying the data involves such things as useful column headings, and meaningful data.  For instance, naming a column &#8220;Month&#8221; but displaying a year value in it &#8211; is not very useful.  This could also overlap with the prior topic of accurate data.</p>
<p>Personally, when I am displaying the month, I like to see month names.  In my experience, displaying the name of the month is more easily recognizable than the month number for many users.</p><pre class="urvanov-syntax-highlighter-plain-tag">Set Statistics Time On
SET DATEFORMAT DMY

DECLARE @StartDate   DATETIME = '05/06/2011',
        @EndDate     DATETIME = '31/08/2013'

Begin
	WITH Nbrs_2( n ) AS (SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 0),
			Nbrs_3( n ) AS ( SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2 CROSS JOIN Nbrs_2 n3)
	, tally (n) as (SELECT ROW_NUMBER() OVER (ORDER BY n)
							   FROM Nbrs_3
							   )
	,cteMonthEnd AS
	(
	 SELECT t.N,
			MonthEnd = DATEADD(mm,DATEDIFF(mm,0,@StartDate) + t.N, 0) - 1
	   FROM Tally t
	  WHERE t.N BETWEEN 1 AND DATEDIFF(mm,@StartDate,@EndDate) + 1
	)
	 SELECT MonthEnd
		,NumDays     = DATEPART(dd,MonthEnd) - CASE WHEN N &amp;gt; 1 THEN 0 ELSE DATEPART(dd,@StartDate) END
	   FROM cteMonthEnd
	   Order By MonthEnd asc
End</pre><p>In this case, the Column Heading matches the data and works.  However, a little change could make this query and output more useful to an end user who is quickly scanning over the results.</p><pre class="urvanov-syntax-highlighter-plain-tag">Set Statistics Time On
SET DATEFORMAT DMY

DECLARE @StartDate   DATETIME = '05/06/2011',
        @EndDate     DATETIME = '31/08/2013'

Begin
	WITH Nbrs_2( n ) AS (SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 1 UNION all
					SELECT 0),
			Nbrs_3( n ) AS ( SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2 CROSS JOIN Nbrs_2 n3)
	, tally (n) as (SELECT ROW_NUMBER() OVER (ORDER BY n)
							   FROM Nbrs_3
							   )
	,cteMonthEnd AS
	(
	 SELECT t.N,
			MonthEnd = DATEADD(mm,DATEDIFF(mm,0,@StartDate) + t.N, 0) - 1
	   FROM Tally t
	  WHERE t.N BETWEEN 1 AND DATEDIFF(mm,@StartDate,@EndDate) + 1
	)
	 SELECT DateName(m,MonthEnd) as [Month],Year(MonthEnd) as [Year]
		,NumDays     = DATEPART(dd,MonthEnd) - CASE WHEN N &amp;gt; 1 THEN 0 ELSE DATEPART(dd,@StartDate) END
	   FROM cteMonthEnd
	   Order By MonthEnd asc
End</pre><p>To this point, each query has progressively increased in performance.  This last query (both versions) also matches the need to accurately display the data.</p>
<p>The display of data is closely coupled with the next topic &#8211; Business Requirements.</p>
<p><span class="Apple-style-span" style="font-size: 14px; font-weight: bold; line-height: 18px;">Business Requirements</span></p>
<p>When looking at the results of the last two queries, which one is more accurate?  Well, that entirely depends on what the business has specified as acceptable output for this query.  In this case, both could be correct or both could be wrong.</p>
<p>It is essential to have the requirements written down and understood by all parties so as to avoid any misconception or misunderstanding of what the query should display.  Matching your output to the specified business requirements will help to provide an overall impression of accuracy and usefulness.  It will also help to achieve faster sign-off by the business.</p>
<h3>Conclusion</h3>
<p>Data Presentation is not just about the look of a report.  Data Presentation involves performance, accuracy, display and the business requirements.  By giving proper attention to each of these facets, the Data presented will be both remarkable and acceptable to the end-user.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1349" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/">T-SQL Tuesday #22 – Data Presentation</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/09/13/t-sql-tuesday-22-data-presentation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hustle and Bustle to Kick off September</title>
		<link>https://jasonbrimhall.info/2011/09/07/hustle-and-bustle-to-kick-off-september/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hustle-and-bustle-to-kick-off-september</link>
					<comments>https://jasonbrimhall.info/2011/09/07/hustle-and-bustle-to-kick-off-september/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 07 Sep 2011 15:23:05 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1346</guid>

					<description><![CDATA[<p>September is kicking off with a boom for me.  In one week, it seems I will be here, there and everywhere.  Between SQL, PASS, Family, and User Group &#8211; this is shaping up to be [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/09/07/hustle-and-bustle-to-kick-off-september/">Hustle and Bustle to Kick off September</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>September is kicking off with a boom for me.  In one week, it seems I will be here, there and everywhere.  Between SQL, PASS, Family, and User Group &#8211; this is shaping up to be quite the week.</p>
<p>Here&#8217;s a quick run down of this weeks agenda.</p>
<h4>Cross Country</h4>
<p>My oldest son is running varsity cross country.  This week there are two meets.  One is in-state and the other is in Idaho.  We are really looking forward to these meets.  He is enjoying the sport, team, atmosphere and success he is having.  The first meet is Wednesday and the second is this weekend.</p>
<h4>Soccer</h4>
<p>We also have a son starting soccer practice this week.  His first match is this weekend.  He has played before and really enjoys playing soccer.  Mostly, I think he likes kicking the ball hard.</p>
<h4>Softball</h4>
<p>I sponsor a co-ed softball team.  We just wrapped up the summer season finishing second in the season ending tournament and first in the regular season.  Fall season starts Wednesday and this should be a lot of fun.</p>
<h4>Volleyball</h4>
<p>My wife captains a co-ed volleyball team.  The league was created as a fundraiser for the high school volleyball team.  She has three matches on Wednesday.  This keeps her pretty busy while I am busy with the kids.  The league is about to wrap it up &#8211; so the schedule gets a little less congested after this.</p>
<h4>PASS</h4>
<p>24 Hours of PASS starts Wednesday.  I am scheduled to moderate a session for Allan Hirt that begins at 19H00 GMT.  I invite you to attend this session.  It should be a good session and well worth your time.  Now where is that record button?  <a href="http://www.sqlpass.org/24hours/fall2011/SessionsbySchedule/MultiSiteFailoverClusteringWithSQLServer200.aspx">Here is more info on that particular session</a>.</p>
<p>You can find more about the rest of 24HOP <a href="http://www.sqlpass.org/24hours/fall2011/">here</a>.  The schedule line up is pretty good.</p>
<h4>S3OLV</h4>
<p>Thursday evening (yes 24HOP is on Thursday too) we will be having our regularly scheduled monthly meeting for the Las Vegas SQL Users Group.  You can read more about that <a href="http://jasonbrimhall.info/2011/09/06/s3olv-september-2011/">here</a>.  This meeting is open to all wishing to get some more learning out of the day than what is available through the means of 24 Hours of PASS.</p>
<h4>SQLSaturday 94</h4>
<p>SQL Saturday 94 is being held this Saturday, September 10.  You can read more about what I have already blogged about it &#8211; <a href="http://jasonbrimhall.info/2011/08/22/sql-saturday-94/">here</a>.  As you can see from the above entries, I already have conflicts on this day.  I am hoping that the timing works out to be available to all three things.</p>
<p>&nbsp;</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1346" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/09/07/hustle-and-bustle-to-kick-off-september/">Hustle and Bustle to Kick off September</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/09/07/hustle-and-bustle-to-kick-off-september/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Precision and Scale</title>
		<link>https://jasonbrimhall.info/2011/08/24/precision-and-scale/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=precision-and-scale</link>
					<comments>https://jasonbrimhall.info/2011/08/24/precision-and-scale/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 24 Aug 2011 13:30:09 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1322</guid>

					<description><![CDATA[<p>As is the case with many of my topics of late, I came across this one by helping somebody else.  In SQL, we should be well aware of Precision and Scale of certain datatypes. The [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/08/24/precision-and-scale/">Precision and Scale</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/digital-calipers-precision-237.jpg"><img loading="lazy" class="alignleft size-full wp-image-1323" title="Precision" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/digital-calipers-precision-237.jpg" alt="Precision" width="314" height="210" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/digital-calipers-precision-237.jpg 314w, https://jasonbrimhall.info/wp-content/uploads/2011/08/digital-calipers-precision-237-300x200.jpg 300w" sizes="(max-width: 314px) 85vw, 314px" /></a>As is the case with many of my topics of late, I came across this one by helping somebody else.  In SQL, we should be well aware of Precision and Scale of certain datatypes.</p>
<p>The particular case I was working on was focused on the decimal datatype, and so we will work with that throughout this post explicitly.</p>
<h3>What are these attributes?</h3>
<p>According to <a href="http://msdn.microsoft.com/en-us/library/ms187912.aspx">MSDN</a>, these attributes have the following definitions.</p>
<p><strong>Precision</strong> &#8211; specifies the number of digits an object can hold</p>
<p><strong>Scale</strong> &#8211; specifies the number of digits to the right of the decimal point that an object can hold.</p>
<p>Based on those definitions, it seems pretty straight forward, right?  Well, it is until you start doing a bit of math.  Microsoft has formulas for figuring out what the resultant precision and scale will be for various math operations.  You can read about that <a href="http://msdn.microsoft.com/en-us/library/ms190476.aspx">here</a>.</p>
<p>Throughout our example, we will be focusing on multiplication and division.  We will demonstrate a few different results and configurations as well.</p>
<p>First, let&#8217;s get some formulas out of the way.  The formulas for precision and scale, as they show in MSDN at the link above, are as follows:</p><pre class="urvanov-syntax-highlighter-plain-tag">Multiplication
	Precision
	p1 + p2 + 1
	Scale
	s1 + s2
Division
	Precision
	p1 - s1 + s2 + max(6, s1 + p2 + 1)
	Scale
	max(6, s1 + p2 + 1)</pre><p>As is described in the MSDN article, p represents precision and s represents scale.  The number annotations with p and s represent the corresponding expressions in the mathematical operation.  The equation that we will be trying to solve is as follows:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ROUND(((@numerator*@multiplier)/@divisor1)*@anothermultiplier,2)</pre><p>[/codesyntax]</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/scales.jpg"><img loading="lazy" class="alignright size-full wp-image-1326" title="Scale" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/scales.jpg" alt="Scale" width="278" height="320" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/scales.jpg 278w, https://jasonbrimhall.info/wp-content/uploads/2011/08/scales-260x300.jpg 260w" sizes="(max-width: 278px) 85vw, 278px" /></a>But for the majority of these exercises, we will be focusing on this part of the formula.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ((@numerator*@multiplier)/@divisor1)</pre><p>[/codesyntax]</p>
<p>This will provide us with ample example of the math involved when calculating the resultant precision and scale of a SQL math operation.</p>
<p>Here is an example of the above query with values.  This query results in a value that is consistent with such calculators as MS Excel ( ;0) ).</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ((5000000000.00*2.0250000000)/111883775187.72)</pre><p>[/codesyntax]</p>
<p>However, if we use variables in lieu of those values, we start to see different results.  And thank goodness for that, because there wouldn&#8217;t be much to talk about otherwise.  So, let&#8217;s dump those values into some variables and see what starts happening.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @divisor1	DECIMAL(18,6) = 111883775187.72
		,@numerator	DECIMAL(18,2) = 5000000000.00
		,@multiplier	DECIMAL(10,3) = 2.0250000000
		,@multiplier1	DECIMAL(18,3) = 2.0250000000
		,@stage1		DECIMAL(18,2)
		,@anothermultiplier	DECIMAL(18,2) = 932364.79</pre><p>[/codesyntax]</p>
<p>And the formula(s).  I say formulas, because I will be demonstrating two results here.  Notice quickly that I have two similar multiplier variables &#8211; they differ only in name and precision.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT ((@numerator*@multiplier1)/@divisor1)
SELECT ((@numerator*@multiplier)/@divisor1)</pre><p>[/codesyntax]</p>
<p>If you execute those two queries, you should get very similar results.  Both should return 0.090xxx, but the second has more scale, extending the decimal out 8 places rather than 6 places.  For the second query our result is 0.09049569.  When you combine this difference at this point, it could make for some accounting nightmares.  Especially given this difference in result occurs early on in the equation.</p>
<p>Notice in my variables there is one called stage.  Let&#8217;s use that one now and see how using a staging variable plays into this.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @divisor1	DECIMAL(18,6) = 111883775187.72
		,@numerator	DECIMAL(18,2) = 5000000000.00
		,@multiplier	DECIMAL(10,3) = 2.0250000000
		,@multiplier1	DECIMAL(18,3) = 2.0250000000
		,@stage1		DECIMAL(18,2)
		,@anothermultiplier	DECIMAL(18,2) = 932364.79

SELECT @stage1 = @numerator*@multiplier
SELECT @stage1/@divisor1
SELECT @stage1 = @numerator*@multiplier1
SELECT @stage1/@divisor1</pre><p>[/codesyntax]</p>
<p>Do you see what just happened?  Both multipliers now produce the same result.  How could that be?  Let&#8217;s look at that.  This time, let&#8217;s post calculations for precision and scale along-side each of those queries.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT @stage1 = @numerator*@multiplier		--P = 18+10+1 = 29, S = 2+3 = 5
SELECT @stage1/@divisor1					--P = 18-2+6+max(6, 2+18+1) = 43, S = max(6, 2+18+1) = 21 --Actual P = 38 S = 16
SELECT @stage1 = @numerator*@multiplier1	--P = 18+18+1 = 37, S = 2+3 = 5
SELECT @stage1/@divisor1					--P = 18-2+6+max(6, 2+18+1) = 43, S = max(6, 2+18+1) = 21 --Actual P = 38 S = 16</pre><p>[/codesyntax]</p>
<p>Looking this over, you should be able to quickly pick out some anomalies.  Let&#8217;s start with the anomalies present in the calculations for the second query.  First, you can see that the value for p1 is 18.  One might fairly think that it should be the resultant precision of the first query.  But, the variable is created as Decimal(18,2) and that precision and scale is used in calculations involving that variable.</p>
<p>The second thing one should notice is that the resultant precision is 43.  Then why did I change it to 38 at the end?  Max precision is 38.  If the resultant precision of a mathematical operation exceeds 38, then it must be reduced to 38.  This has an impact on scale &#8211; which is the next item of note.  In the aforementioned MSDN article, scale is simply reduced by the difference between resultant(p) and final(p).  That simple calculation holds true for these particular queries.  But, if we look at the following queries, we can clearly see that it is behaving differently.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @divisor1	DECIMAL(18,6) = 111883775187.72
		,@numerator	DECIMAL(18,2) = 5000000000.00
		,@multiplier	DECIMAL(10,3) = 2.0250000000
		,@multiplier1	DECIMAL(18,3) = 2.0250000000
		,@stage1		DECIMAL(18,2)
		,@anothermultiplier	DECIMAL(18,2) = 932364.79

SELECT (@numerator*@multiplier1)/@divisor1
SELECT (@numerator*@multiplier)/@divisor1</pre><p>[/codesyntax]</p>
<p>And the correlating notes regarding precision and scale calculations.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT (@numerator*@multiplier1)/@divisor1	--P = 37-5+6+max(6, 5+18+1) = 62, S = max(6, 5+18+1) = 24 --Actual P = 38 S = 6
SELECT (@numerator*@multiplier)/@divisor1	--P = 29-5+6+max(6, 5+18+1) = 54, S = max(6, 5+18+1) = 24 --Actual P = 38 S = 8</pre><p>[/codesyntax]</p>
<p>Look at the final(s) for that first query.  Scale is actually 6, but that does not match the math.  Resultant(p) = 62, Final(p) = 38 and that means the difference is 24.  Resultant(s) is 24, from which I subtract 24 and should get 0.  Well, there is a part of that formula that needs better explanation maybe in the documentation.  The final(s) should actually include the max(6, Resultant(s) &#8211; (resultant(p) &#8211; final(p))).  The final(s) cannot be less than 6, and thus the reason that we see 6 digits to the right of the decimal in the result of that first query.</p>
<p>Now let&#8217;s change that divisor scale up a bit.  The requirements dictate that the divisor be a Decimal(18,2) &#8211; I used 18,6 as one of my test sets.  In this case, the only thing that changes is the final(s).  And in this particular case (though, I don&#8217;t recommend shortcutting &#8211; it just works for this case), we can simply add 4 to the final(s) of the second query.  The first remains unchanged.</p>
<p>Let&#8217;s look at the resulting value now.  This difference alone is cause enough for significant differences in the results of the larger formula.</p>
<p>First query = 0.090495, Second query = 0.090495695046.  To this point, I have shown why this happens.  The calculations performed exceed the limitations for precision which impacts scale &#8211; which affects accuracy of the formula.</p>
<p>I showed one method, without saying as much, on how to avoid this.  My use of an intermediary step to perform these calculations via variable helped to correct the precision/scale/accuracy problem.  Another viable option is to use appropriate precision and scale for the data being used.  Changing precision and scale to match expected data can have a significant impact on the resultant accuracy of the calculation.</p>
<p>I used two multipliers to demonstrate that last suggestion.  The more accurate result came from the second query which used a more appropriate precision and scale for the data (see the variable @multiplier).</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1322" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/08/24/precision-and-scale/">Precision and Scale</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/08/24/precision-and-scale/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Bitwise Operations</title>
		<link>https://jasonbrimhall.info/2011/08/19/bitwise-operations/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=bitwise-operations</link>
					<comments>https://jasonbrimhall.info/2011/08/19/bitwise-operations/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 19 Aug 2011 13:00:16 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1315</guid>

					<description><![CDATA[<p>Some time ago, I wrote an introductory post about bitwise operations in SQL Server.  I had fully intended on writing a follow-up to that.  Alas the opportunity has passed for the idea I was working [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/08/19/bitwise-operations/">Bitwise Operations</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Some time ago, I wrote an <a href="http://jasonbrimhall.info/2011/03/10/sql-bitwise-operations/">introductory post</a> about bitwise operations in SQL Server.  I had fully intended on writing a follow-up to that.  Alas the opportunity has passed for the idea I was working on back then.</p>
<p>As luck would have it though, I encountered a new opportunity to share something on this topic.  This one came to me by once again helping out in the forums.  And, since I worked it out, I will be using the same problem posed in the forum and the solution I proposed.</p>
<p>First we need a little setup.  Let&#8217;s create a simple table and populate that table with some data.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE ColorPlate (ColorID INT PRIMARY KEY IDENTITY(1,1),ColorPlate VARCHAR(10), ColorType INT)

INSERT INTO ColorPlate (ColorPlate,ColorType)
Select 'Red',1
UNION ALL 
SELECT 'Blue',2
UNION ALL
Select 'Yellow',4</pre><p>[/codesyntax]</p>
<p>As I said, this setup is rather simple.  The solution is not much more complex.  However, before we get to the solution, we need to know what we need the solution to do.  From this table, I need to be able to determine the primary colors that make up a different color based on input of an ID relating to that color.  I know.  I know.  We don&#8217;t have all of the colors and their ColorTypes presented to us at this point &#8211; but let&#8217;s just go with it for a bit.  I would imagine that the other colors and the number assigned to their colortype would be populated at some other time.</p>
<p>For now, we are only working with seven color variations &#8211; so any number from 1-7 is a valid input.  How do we find all of the colors that are required for the number that we input?  Well, we use some smoke and mirrors.  Just kidding.  Seriously though, we use bitwise operations as well as a neat trick called &#8220;cross apply.&#8221;</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @ColorType INT = 3

Select cp1.* 
	From ColorPlate cp1
	CROSS APPLY ColorPlate cp2
	CROSS APPLY ColorPlate cp3
Where cp1.colortype &amp;amp; cp2.colortype &amp;amp; cp3.colortype &amp;amp; @ColorType &amp;lt;&amp;gt; 0 

Order by ColorID;</pre><p>[/codesyntax]</p>
<p>Do you see what is being done there?  I have known values in this table of 1,2, and 4.  I know that 7 is the max number I am allowing for input at this time.  Because of that, I know that I need three values in order to arrive at a value of 7.  Due to this requirement, I know I must Cross Apply the ColorPlate table twice beyond the first select from it.  That will permit me to sum three values from the ColorPlate table.</p>
<p>Now that I have access to three possible values, I need to compare those values using the Bitwise And operator.  This is denoted by ampersand ( &amp; ).  Note that the where clause checks each of the three tables as well as the variable.  Then, I want to make sure that their bitand operation is not 0.  Pretty slick eh?</p>
<p>Let&#8217;s put it to action.  If I run the above query with a value of 6 for the @ColorType variable, I will get a two record result set.  The results returned would be the primary colors for green (which are Blue and Yellow).  If I use 7 for that same variable, I will get a three record result-set which would include red, blue and yellow.</p>
<p>This was a rather simple solution and scenario for a bitwise operation.  There are plenty of other examples out there of how to use these types of solutions.  Some more elaborate than others &#8211; but many good examples nonetheless.</p>
<p>I am interested in finding more solutions that involve these types of operations.  Who knows, maybe I will even be able to remember the neat stuff I learned while writing the last article on the topic and be able to put that up before too long.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1315" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/08/19/bitwise-operations/">Bitwise Operations</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/08/19/bitwise-operations/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Derived Table Column Alias</title>
		<link>https://jasonbrimhall.info/2011/08/18/derived-table-column-alias/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=derived-table-column-alias</link>
					<comments>https://jasonbrimhall.info/2011/08/18/derived-table-column-alias/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 18 Aug 2011 13:00:24 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[derived table]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[subquery]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1310</guid>

					<description><![CDATA[<p>By now, you have heard of subqueries.  You have also heard of Common Table Expressions.  I am sure you know what a derived table is and that you get a derived table through either a [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/08/18/derived-table-column-alias/">Derived Table Column Alias</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>By now, you have heard of subqueries.  You have also heard of Common Table Expressions.  I am sure you know what a derived table is and that you get a derived table through either a subquery or CTE.  How familiar are you with the subquery flavor of a derived table though?</p>
<p>I encountered something about derived tables recently that I had never seen, let alone heard of up to that point.  Let&#8217;s start with the Microsoft documentation on the topic.  If you browse to this <a href="http://msdn.microsoft.com/en-us/library/ms177634.aspx">page</a>, you will find a description for <em>column_alias</em> immediately following the description of derived table.  What you don&#8217;t get is an example of how it is applicable.  Or do you?</p>
<p>If you look in the example of the derived table on that same page, you will see the following code (formatting added for readability).</p>
<p>[codesyntax lang=&#8221;php&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT *
	FROM (
			VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10)
		) AS MyTable(a, b);</pre><p>[/codesyntax]</p>
<p>Here, we can see that <em>column_alias</em> is optionally supplied after the <em>table_alias</em> for the derived table.  In this example, we have supplied two new column aliases called <strong>a</strong> and <strong>b</strong>.</p>
<p>If we want, we can take this a step further and see the same sort of example supplied by <a href="http://infocenter.sybase.com/help/topic/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug419.htm">Sybase</a>.</p>
<p>[codesyntax lang=&#8221;sql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select dt_b.book_title, dt_b.tot_sales
   from (select title, total_sales
            from titles) dt_b (book_title, tot_sales)
   where dt_b.book_title like &quot;%Computer%&quot;</pre><p>[/codesyntax]</p>
<p>You can read the documentation about derived table syntax in Sybase, <a href="http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.ase_15.0.sqlug/html/sqlug/sqlug411.htm">here</a>, if you so desire.  The point of this is to show similar code and documentation between SQL Server and its resuscitated predecessor.</p>
<p>And for grins, you actually have the same sort of optional syntax available for the derived table known as a CTE.  You can see the documentation, from Microsoft, on that <a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx">here</a>.</p>
<p>So, how do we put this to use?  Well, I am glad you asked that.  I have an example ready to go.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @StudentId INT = 1
		,@RequestDate DATE = '7/1/2011'
		,@RequestNbr INT = 2
		,@SchoolYear INT = 2011
		,@RequestTypeID INT = 1

;
WITH Request AS (
				SELECT RequestNbr = 2
					, RequestDate = @RequestDate
					, StudentId = 1
					, SchoolYear = 2011
					, RequestTypeID = 1
					, CompletionDate = null)
SELECT	 Request.StudentId
		,Request.RequestNbr
		,Request.RequestDate
FROM Request
JOIN (SELECT StudentId AS StudentNumber, max(RequestNbr) AS RequestNb
		FROM Request
		WHERE RequestTypeId = @RequestTypeId
			AND StudentId = @StudentId
			AND CompletionDate IS NULL
			AND SchoolYear	= @SchoolYear
		GROUP BY StudentId) AS Latest (StudentId, RequestNbr)
	ON Request.StudentId = Latest.StudentId
	AND Request.RequestNbr = Latest.RequestNbr</pre><p>[/codesyntax]</p>
<p>In this example, I have a derived table implemented through a subquery.  The alias of this derived table is &#8220;Latest.&#8221;  Note that there is an additional set of parenthesis after that table alias.  Inside this set of parenthesis, you will see a couple of column names.  Those columns are called StudentId and RequestNbr.</p>
<p>Now, I want you to take a look inside that derived table and note the names of the columns I provided in the aliases there.  See how those <em>column_aliases</em> are different than the <em>column_aliases</em> provided after the table_alias?  By looking at the query, can you tell which takes precedence?  Aliases supplied for columns in the optional <em>column_alias</em> outside of the derived table override the <em>column_aliases</em> of those provided inside the derived table.  You can verify that by looking at the join conditions provided after those aliases were defined.</p>
<p>Running this script, you will see it execute without error.  Using this kind of syntax could be useful in certain cases.  I think that it could make finding those column names considerably easier.  It could also help with readability.</p>
<p>Let&#8217;s take a quick look at the same kind of setup, but using a CTE instead.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @StudentId INT = 1
		,@RequestDate DATE = '7/1/2011'
		,@RequestNbr INT = 2
		,@SchoolYear INT = 2011
		,@RequestTypeID INT = 1

;
WITH Request AS (
				SELECT RequestNbr = 2
					, RequestDate = @RequestDate
					, StudentId = 1
					, SchoolYear = 2011
					, RequestTypeID = 1
					, CompletionDate = NULL
), Latest (StudentId, RequestNbr) AS (
		SELECT StudentId AS StudentNumber, max(RequestNbr) AS RequestNb
			FROM Request
			WHERE RequestTypeId = @RequestTypeId
				AND StudentId = @StudentId
				AND CompletionDate IS NULL
				AND SchoolYear	= @SchoolYear
			GROUP BY StudentId
)
SELECT	 Request.StudentId
		,Request.RequestNbr
		,Request.RequestDate
FROM Request
JOIN Latest AS Latest
	ON Request.StudentId = Latest.StudentId
	AND Request.RequestNbr = Latest.RequestNbr</pre><p>[/codesyntax]</p>
<p>Note that I moved that entire derived table from subquery to be a new CTE defined immediately after Request.  Now take note of the difference in declaration between Request and Latest.  In Latest, I define the column names up front and have the columns aliased differently inside the CTE.  I do not define the <em>column_alias</em> list for the Request derived table.  You can also note that the <em>colum_alias</em> defined prior to the guts of the Latest derived table take precedence over any <em>column_alias</em> defined inside that particular derived table.</p>
<p>I hope this was new information to somebody else.  If you learned something new, let me know.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1310" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/08/18/derived-table-column-alias/">Derived Table Column Alias</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/08/18/derived-table-column-alias/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Sudoku</title>
		<link>https://jasonbrimhall.info/2011/08/17/tsql-sudoku/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-sudoku</link>
					<comments>https://jasonbrimhall.info/2011/08/17/tsql-sudoku/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 17 Aug 2011 13:00:25 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL Script]]></category>
		<category><![CDATA[Sudoku]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1307</guid>

					<description><![CDATA[<p>I am a big Sudoku fan.  Typically if I need a break, I will break out a Sudoku puzzle from any of a number of different sources (Websudoku, Android Apps, Puzzle Books).  Over time, I [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/08/17/tsql-sudoku/">TSQL Sudoku</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I am a big Sudoku fan.  Typically if I need a break, I will break out a Sudoku puzzle from any of a number of different sources (<a href="http://www.websudoku.com/">Websudoku</a>,<a href="http://code.google.com/p/opensudoku-android/"> Android Apps</a>, Puzzle Books).  Over time, I have come across a solution here or there to solve these puzzles via TSQL.</p>
<p>There are a few of these solutions out there already, such as one by <a href="https://web.archive.org/web/20121214031508/http://www.sqlmag.com:80/article/tsql3/solve-sudoku-puzzles-with-t-sql">Itzik Ben-Gan</a> (which I can&#8217;t get to download without the file corrupting so I still haven&#8217;t seen it), or this one on <a href="http://www.sqlservercentral.com/scripts/T-SQL/62978/">SSC</a> (which works most of the time but does provide inaccurate results from time to time).  I still wanted something to do this via CTE (much like the solution by Itzik is described to be at the link provided &#8211; if you have that code, I want to SEE it).</p>
<p>Just a couple of years ago, there was a <a href="http://www.sqlservercentral.com/Forums/Topic812541-338-1.aspx">post at SSC</a> asking for some help converting a solution from Oracle to TSQL.  I checked out that code and worked on it for a day or two.  Then I got busy with other work that replaced the pet project.  I hadn&#8217;t given the idea much thought until just a few days ago as I was browsing my Topic list I had been building for articles.</p>
<p>This solution stuck with me this time around and I wanted to finish it up.  The Oracle solution for whatever reason made a lot more sense to me this time around, and I made great progress quickly.  It was actually this project that I was working on that prompted another <a href="http://jasonbrimhall.info/2011/08/16/top-5-oracle-nuances-i-learned-today/">post</a>.  While working through the solution, I learned a fair amount about both flavors of SQL.  So, in preface to continuing to read here, you may want to check out the other article real quick since it pertains to some of the conversions done in this project.</p>
<h3>Problems First</h3>
<p>The OP supplied the Oracle solution asking for help in creating a TSQL Solution.  Here is that Oracle version.</p>
<p>[codesyntax lang=&#8221;sql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">with x( s, ind ) as
( select sud, instr( sud, ' ' )
  from ( select '53  7    6  195    98    6 8   6   34  8 3  17   2   6 6    28    419  5    8  79' sud from dual )
  union all
  select substr( s, 1, ind - 1 ) || z || substr( s, ind + 1 )
       , instr( s, ' ', ind + 1 )
  from x
     , ( select to_char( rownum ) z
         from dual
         connect by rownum &amp;lt;= 9
       ) z
  where ind &amp;gt; 0
  and not exists ( select null
                   from ( select rownum lp
                          from dual
                          connect by rownum &amp;lt;= 9
                        )
                   where z = substr( s, trunc( ( ind - 1 ) / 9 ) * 9 + lp, 1 )
                   or    z = substr( s, mod( ind - 1, 9 ) - 8 + lp * 9, 1 )
                   or    z = substr( s, mod( trunc( ( ind - 1 ) / 3 ), 3 ) * 3
                                      + trunc( ( ind - 1 ) / 27 ) * 27 + lp
                                      + trunc( ( lp - 1 ) / 3 ) * 6
                                   , 1 )
                 )
)
select s
from x
where ind = 0
/</pre><p>[/codesyntax]</p>
<p>If you read that other post I mentioned, you will quickly identify 5 functions/objects in use in this script that just don&#8217;t work in TSQL.  Those are:  dual, instr, substr, connect by, and trunc.  I did not mention mod in my other post, but mod is also done differently in TSQL than in Oracle.  I thought this one was a bit obvious and stuck with the top 5 ;).</p>
<h3>Solution</h3>
<p>After figuring out some of the subtle differences between commands and the best way to approach this, I was able to come up with a TSQL solution that works.  Take not first of that last where clause in the CTE of the Oracle solution.  That clause is very similar to what I refer to as the train-stop method to get unique paths in a hierarchy.  There are several methods to do similar functionality &#8211; I have concatenated strings with Stuff as wells cast to produce this functionality.</p>
<p>So here goes with the first rendition of this query.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @SudokuGivens VARCHAR(100)
SET @SudokuGivens = '53  7    6  195    98    6 8   6   34  8 3  17   2   6 6    28    419  5    8  79'
;
WITH
      E1(N) AS ( --=== Create Ten 1's
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 --10
               )
,dual(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT N)) FROM E1)
,x( s, ind ) as
( select CONVERT(VARCHAR(100),sud), CHARINDEX(' ',Ss.sud ) AS ind
	from 
		( select @SudokuGivens AS sud from dual ) Ss
  union all
  select CONVERT(VARCHAR(100),substring( s, 1, ind - 1 ) + z + substring( s, ind + 1 ,LEN(s)))
       , CHARINDEX( ' ', s, ind + 1 ) AS ind
  from x
    CROSS APPLY ( select convert(VARCHAR(25), N ) z
         from dual
         Where N &amp;lt;= 9
       ) z
  where ind &amp;gt; 0
  and not exists ( select null
                   from ( select N AS lp
                          from dual
                          Where N &amp;lt;= 9
                        ) ww
					where z = substring( s, ( ind - 1)% 9  - 8 + lp * 9, 1 )
						or    z = substring( s, ( ( ind - 1 ) / 9 ) * 9 + lp, 1 )
						or    z = substring( s, (( ( ind - 1 ) / 3 )%3) * 3
                                      + ( ( ind - 1 ) / 27 ) * 27 + lp
                                      + ( ( lp - 1 ) / 3 ) * 6
                                   , 1 )
                 )
)
select DISTINCT s
	from x
	where ind = 0</pre><p>[/codesyntax]</p>
<p>Notice that I have chosen to use an Itzik style numbers table/CTE.  This functions as my &#8220;dual&#8221; table translation and is necessary in the remainder of the query.  The final where clause of the CTE is simplified in TSQL by simply removing the TRUNC commands.  The original solution was merely removing the decimal precision.  In TSQL, the conversion is done to INT implicitly in this case.  I need to test a few more cases, but so far it works without error.</p>
<h3>What this does not do&#8230;</h3>
<p>This is the first rendition of the script.  Currently, it only returns the number sequence in one big long string.  I am working on modifying this script to produce a grid layout with the solution.  I envision this will require the use of PIVOT and possibly UNPIVOT to get me close.  In addition, I expect that further string manipulation will be needed &#8211; such as stuffing commas and then splitting it to make the PIVOT/UNPIVOT easier.  I&#8217;ll have to try some things and figure it out.  Also, I expect that some explicit conversions may be best in this query.  That could help improve performance a tad.</p>
<p>This, to this point, has been a fun diversion.  This has helped to learn a bit about Oracle, hierarchies, and to do a little math &#8211; all in one.  Better yet is that there is still work to be done on it and more learning.  If you have ideas how to make it better &#8211; I am very interested.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1307" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/08/17/tsql-sudoku/">TSQL Sudoku</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/08/17/tsql-sudoku/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>SSRS Export En Masse</title>
		<link>https://jasonbrimhall.info/2011/08/08/ssrs-export-en-masse/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssrs-export-en-masse</link>
					<comments>https://jasonbrimhall.info/2011/08/08/ssrs-export-en-masse/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 08 Aug 2011 13:00:11 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Tools]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[SSRS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1275</guid>

					<description><![CDATA[<p>Have you ever found yourself in need of exporting all of the reports from a Report Server?  I have found myself in need of extracting all RDLs from a Report Server on more than one [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/08/08/ssrs-export-en-masse/">SSRS Export En Masse</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Have you ever found yourself in need of exporting all of the reports from a Report Server?  I have found myself in need of extracting all RDLs from a Report Server on more than one occasion.  Reporting Services 2008 would rather have you do that in a rather monotonous and repetitive style.  That doesn&#8217;t work very well for me &#8211; and especially not if you have a ton of reports to export.</p>
<p>I combed the internet to see if there was a quick to implement way to do this &#8211; and found some recommendations.  Most of these  required the installation of another utility or the purchase of other software.  I found one site however that was extremely useful for what I wanted.  Brett Stateham used some queries to display the XML for these reports that is stored in the Catalog for Report Server.  You can read about that <a href="https://web.archive.org/web/20111103113346/http://blogs.netconnex.com/2011/05/extracting-ssrs-report-rdl-xml-from.html">here</a>.</p>
<p>Reading his blog post on the topic, I got the distinct idea that I could use a query to extract the xml and save it to an RDL file.  To verify this, I copied the XML (as returned by the queries on Bretts page) to a notepad file and save the file with an RDL extension.  Then I added that file back into a solution in Visual Studio and ran the report &#8211; sweet.  It worked.</p>
<p>Now that I know it can be done as simply as he displayed, it was time to take it a step further.  I now need to create something that will help me export numerous reports to their own individual files.  Hmmm, what could I use?  Having done something similar in the past for a single xml file in SSIS, I decided I would just use SSIS.  Thinking it through, I figured this should be pretty simple in appearance (a file destination object, an execute sql task, a data source, a file source, a foreach loop &#8211; you get the idea).</p>
<p>As I started to work through the solution, I found that I was over thinking it a bit and the solution could possibly be easier.  That made me wonder if a script task would be helpful here.  I decided to research and see if there was a quick way to write the xml to a file via a script task.  Guess what, there is.  Using VB .Net, there are simple methods inside a script task to write to the filesystem.</p>
<p>So, without further ado, let&#8217;s take a look at the package.</p>
<p>First, let&#8217;s create a few variables for use throughout the package.</p>
<ul>
<li>objReport &#8211; This is of type object and will be used to store the results of our TSQL statement from an Execute SQL Task.</li>
<li>ReportExportPath &#8211; Type is String and will be the destination file path.  The last character for this variable should be a &#8220;\&#8221;</li>
<li>ReportName &#8211; Type is String and is for use by the ForEach Loop.  This variable will receive the report name from each iteration through the objReport and then be used by the Script Object to later give a name to the output RDL file.</li>
<li>ReportSourcePath &#8211; Type is String.  This variable is to help extract only the reports from a specific location.  In many cases, reports are stored in different folder paths and you may not need all folders&#8217; contents.</li>
<li>ReportXML &#8211; Type is String.  Similar in function to ReportName</li>
<li>DBName &#8211; Type is String.  This value will be used to override the Initial Catalog of the Connection String</li>
<li>ServerName &#8211; Type is String.  This value will be used to override the Server Name of the Connection String.</li>
</ul>
<p>Next, we need to create a connection object to create a data source for this package.  I created an ADO.Net connection object and named it ReportSourceDB.  Once created, use expressions from the properties tab to overwrite the Initial Catalog and Server Name values with the already mentioned variables.</p>
<p>Now that we have that stuff out of the way, we can begin work on creating the data flow.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/ControlFlow.jpg"><img loading="lazy" class="size-full wp-image-1276 alignnone" title="ControlFlow" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/ControlFlow.jpg" alt="" width="523" height="173" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/ControlFlow.jpg 523w, https://jasonbrimhall.info/wp-content/uploads/2011/08/ControlFlow-300x99.jpg 300w" sizes="(max-width: 523px) 85vw, 523px" /></a></p>
<p>Above is displayed the entire data flow for this package.  I adapted, albeit ever so slightly, the script we discussed at the beginning to the following for use in this package.</p><pre class="urvanov-syntax-highlighter-plain-tag">WITH ItemContentBinaries AS 
( 
  SELECT 
     ItemID,Name,[Type] 
   ,CASE Type 
      WHEN 2 THEN 'Report' 
      WHEN 5 THEN 'Data Source' 
      WHEN 7 THEN 'Report Part' 
      WHEN 8 THEN 'Shared Dataset' 
      ELSE 'Other' 
     END AS TypeDescription 
   ,CONVERT(varbinary(max),Content) AS Content    
   FROM ReportServer.dbo.Catalog 
   WHERE Type IN (2,5,8) 
	And left(Path,len(@ReportPath)) = @ReportPath
), 
--The second CTE strips off the BOM if it exists... 
ItemContentNoBOM AS 
( 
  SELECT 
     ItemID,Name,[Type],TypeDescription 
    ,CASE 
      WHEN LEFT(Content,3) = 0xEFBBBF 
        THEN CONVERT(varbinary(max),SUBSTRING(Content,4,LEN(Content))) 
      ELSE 
        Content 
    END AS Content 
  FROM ItemContentBinaries 
) 
--The outer query gets the content in its varbinary, varchar and xml representations... 
SELECT 
  NAME
,CONVERT(xml,Content) AS ContentXML                --xml 
FROM ItemContentNoBOM</pre><p>This script is in the ExecuteSQL task.  The task is configured to retrieve the full result set and store it in objReport.  A parameter is specified and passed to the above query in the first CTE.  The following images should help clarify the configuration a bit.</p>
<p>General Tab:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_general.jpg"><img loading="lazy" class="alignnone size-full wp-image-1277" title="execsql_general" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_general.jpg" alt="" width="509" height="131" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_general.jpg 509w, https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_general-300x77.jpg 300w" sizes="(max-width: 509px) 85vw, 509px" /></a></p>
<p>Parameter Mapping Tab:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_parammap.jpg"><img loading="lazy" class="alignnone size-full wp-image-1278" title="execsql_parammap" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_parammap.jpg" alt="" width="662" height="47" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_parammap.jpg 662w, https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_parammap-300x21.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Result Set Tab:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_resultset.jpg"><img loading="lazy" class="alignnone size-full wp-image-1279" title="execsql_resultset" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_resultset.jpg" alt="" width="556" height="56" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_resultset.jpg 556w, https://jasonbrimhall.info/wp-content/uploads/2011/08/execsql_resultset-300x30.jpg 300w" sizes="(max-width: 556px) 85vw, 556px" /></a></p>
<p>So far so good.  This is now getting all of the data that we need from the ReportServer database.  We can now pass this information to the ForEach Loop container and write the XML out to RDL files.  The configuration of the ForEach Loop is not too complicated and looks like this:</p>
<p>Collection Tab:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_collection.jpg"><img loading="lazy" class="alignnone size-full wp-image-1280" title="foreach_collection" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_collection.jpg" alt="" width="531" height="263" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_collection.jpg 531w, https://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_collection-300x148.jpg 300w" sizes="(max-width: 531px) 85vw, 531px" /></a></p>
<p>Variable Mappings Tab:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_varmap.jpg"><img loading="lazy" class="alignnone size-full wp-image-1281" title="foreach_varmap" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_varmap.jpg" alt="" width="522" height="111" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_varmap.jpg 522w, https://jasonbrimhall.info/wp-content/uploads/2011/08/foreach_varmap-300x63.jpg 300w" sizes="(max-width: 522px) 85vw, 522px" /></a></p>
<p>Inside of this ForEach Loop container we have that script task that was displayed.  This was probably the trickiest (yet extremely simple) part of the whole exercise for myself.  I have used script tasks in the past for various tasks and was worried this might be a bit more complicated.  So let&#8217;s start with a couple of pictures.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/08/scripttask_variables.jpg"><img loading="lazy" class="alignnone size-full wp-image-1282" title="scripttask_variables" src="http://jasonbrimhall.info/wp-content/uploads/2011/08/scripttask_variables.jpg" alt="" width="685" height="314" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/08/scripttask_variables.jpg 685w, https://jasonbrimhall.info/wp-content/uploads/2011/08/scripttask_variables-300x137.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>There is no need to use a ReadWrite variable in this task.  This task simply reads the variable and then writes the contents of that variable out to a file.  Note that the script language is set to VB 2008.  The default (for me) was C# &#8211; and I changed that.  Once the variables are specified for ReadOnlyVariables, click the Edit Script button at the bottom of the screen.</p>
<p>In the new window that opens, highlight everything and overwrite it all with the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime

&lt;System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")&gt; _
&lt;System.CLSCompliantAttribute(False)&gt; _
Partial Public Class ScriptMain
	Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

	Enum ScriptResults
		Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
		Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
	End Enum

    Public Sub Main()
        My.Computer.FileSystem.WriteAllText(Dts.Variables("ReportExportPath").Value + Dts.Variables("ReportName").Value + ".rdl", Dts.Variables("ReportXML").Value.ToString, False)
        Dts.TaskResult = ScriptResults.Success
    End Sub

End Class</pre><p>The line that is important here is the line containing My.Computer.FileSystem inside Public Sub Main().  Note how I am using the variables we have created to this point to create the file name (first parameter series inside WriteAllText()) and also to write the contents of the file based on the ReportXML variable (that is the second parameter inside WriteAllText()).</p>
<p>From here, it is simply a matter of testing the package.  Run the package and check the directory you specified in the ReportExportPath variable.  This little project will save me an enormous amount of time in just exporting the reports to files from the database.  Yay, no more repetitive download task done through report manager.</p>
<p>Enjoy, and put it to good use.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1275" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/08/08/ssrs-export-en-masse/">SSRS Export En Masse</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/08/08/ssrs-export-en-masse/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Activity Monitor and Profiler</title>
		<link>https://jasonbrimhall.info/2011/07/28/activity-monitor-and-profiler/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=activity-monitor-and-profiler</link>
					<comments>https://jasonbrimhall.info/2011/07/28/activity-monitor-and-profiler/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 28 Jul 2011 21:05:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1266</guid>

					<description><![CDATA[<p>Today I came across a link to a neat little script for SQL 2005 / 2008 to help derive the head blocker in a blocking chain.  That script can be found here.  I was looking [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/07/28/activity-monitor-and-profiler/">Activity Monitor and Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today I came across a link to a neat little script for SQL 2005 / 2008 to help derive the head blocker in a blocking chain.  That script can be found <a href="http://sqlfrndz.com/2011/06/09/activity-monitor-script-to-find-head-blocker-sql-server-2005-2008-and-later/" class="broken_link">here</a>.  I was looking at the script and thought it looked pretty cool and also wondered why it might look a little familiar.  Not too big of a concern since many admin type scripts can look familiar.</p>
<p>Then I noticed that the title contained the words Activity Monitor.  I wondered to myself, was this taken from activity monitor?  So, I decided to play with Profiler for a bit to see if I could generate the same query.  The process really isn&#8217;t too difficult.  Here is what I did.</p>
<ol>
<li>Open Activity Monitor.  Simple enough to do.  Right click the instance (in SSMS) you wish to monitor, select Activity Monitor from the context menu.</li>
<li>Open Profiler.  Again from within SSMS, click the tools menu and then select SQL Server Profiler.</li>
<li>Start a New trace.  When starting the trace ensure that you are connecting to the same instance as you started Activity Monitor.  Select the TSQL-Replay template (other tsql will probably work, this is the one that I used).  Goto the events selection tab and click on the Column Filters button.  Select &#8220;LoginName&#8221; and then expand &#8220;Like&#8221; on the right hand side.  In the new text box, type the login you are using to authenticate to the SQL Instance in question (domain\user or SQLLogin).</li>
<li>Click run and browse through the results for a bit.  It shouldn&#8217;t take too long for that query to pop up.</li>
<li>Once you find the query, make sure you stop the trace.</li>
</ol>
<div>What is the point in this?  Well, as explained in that other blog, sometimes it is just better to run a query than to run Activity Monitor.  Furthermore, you can take this method and trap many of the queries that Microsoft built into that tool.  You can either use them for learning or troubleshooting.  This is just one more tool to have in your arsenal in order to become better at your job.</div>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1266" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/07/28/activity-monitor-and-profiler/">Activity Monitor and Profiler</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/07/28/activity-monitor-and-profiler/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>July 2011 S3OLV Meeting</title>
		<link>https://jasonbrimhall.info/2011/07/06/july-2011-s3olv-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=july-2011-s3olv-meeting</link>
					<comments>https://jasonbrimhall.info/2011/07/06/july-2011-s3olv-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 06 Jul 2011 18:49:34 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1258</guid>

					<description><![CDATA[<p>We have had a bit of a lag between meetings for the User Group of Las Vegas.  In June, a meeting was scheduled but did not happen.  The cause of that was due to being [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/07/06/july-2011-s3olv-meeting/">July 2011 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We have had a bit of a lag between meetings for the User Group of Las Vegas.  In June, a meeting was scheduled but did not happen.  The cause of that was due to being locked out once again by our meeting place.  That should not happen this month &#8211; nor anytime in the near future.  The Venue has changed for our little group this month.</p>
<p>Starting with our July meeting, we will be holding our gatherings at <strong><a href="http://mstaffsolutions.com/contact_us"><strong>M</strong> Staff<strong> Solutions</strong> &amp;</a><strong><a href="http://mstaffsolutions.com/contact_us">Training</a>. </strong></strong>They have been gracious enough to bring us on and they have provided us with a key.  Woot!!</p>
<p>Our topic for July will be the same as it was supposed to be for June.</p>
<p>For any who are interested, The S3OLV meeting will be held Thursday July 14 at 18h30 PDT.</p>
<p>This month Charley Jones will be test driving a new presentation.  He has been working feverishly to learn about cubes and how to create them.  He will be teaching us this month how to do this from the mind-set of an OLTP DBA in his presentation titled “OLTP Moving to OLAP.”  I think this will be a great opportunity for those of us who are weak or strong in OLAP to learn a bit and see how this transition may make sense from an OLTP perspective.</p>
<p>This month we will be conducting this meeting in person and also via livemeeting.  Here are the livemeeting details.</p>
<p>Attendee URL: https://www.livemeeting.com/cc/UserGroups/join?id=Z8DZWK&amp;role=attend<br />
Meeting ID: Z8DZWK</p>
<p>In other news, we have a newsletter that we are publishing thanks to the paper.li service.  You can find that newsletter <a href="http://paper.li/sqlrnnr/1308943349">here</a>.  Beyond the distribution via twitter, we are looking to distribute weekly newsletters to the group.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1258" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/07/06/july-2011-s3olv-meeting/">July 2011 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/07/06/july-2011-s3olv-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Statistics &#8211; another Spin</title>
		<link>https://jasonbrimhall.info/2011/07/01/sql-statistics-another-spin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-statistics-another-spin</link>
					<comments>https://jasonbrimhall.info/2011/07/01/sql-statistics-another-spin/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 01 Jul 2011 15:00:45 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[statistics]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1252</guid>

					<description><![CDATA[<p>I was reading a blog by Pinal Dave that was about using catalog views to obtain information about stats for the entire database.  While reading the blog, I was reminded about an interesting tidbit of [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/07/01/sql-statistics-another-spin/">SQL Statistics – another Spin</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I was reading a <a href="http://blog.sqlauthority.com/2011/06/29/sql-server-find-details-for-statistics-of-whole-database-dmv-t-sql-script/">blog</a> by Pinal Dave that was about using catalog views to obtain information about stats for the entire database.  While reading the blog, I was reminded about an interesting tidbit of information I had seen once upon a time concerning statistics naming in SQL Server.</p>
<p>This got me looking for that information and burrowing down the rabbit hole.  I found the reference for the naming convention concerning auto generated statistics.  That reference is from Paul Randal and can be found <a href="http://www.sqlskills.com/BLOGS/PAUL/How-are-auto-created-column-statistics-names-generated/" class="broken_link">here</a>.  In that article, Paul outlines the five parts of the name of an auto-created statistic &#8211; with each part being separated by an underscore.  This got the wheels churning a bit more.</p>
<p>I had to go do a bit more research in order to put all the pieces together.  Based on the naming convention, I knew I needed to convert Hex to Integer, so I could see the object id (column or table).  You might think this would be straight forward, but the value in the name of the statistic is not a true Hex Value.  That value is a hex string and needs a bit of manipulation in order to convert from string to Hex.</p>
<p>After some searching, I found the solution.  Peter Debetta created this handy little function for this very purpose.  I found that script <a href="http://sqlblog.com/blogs/peter_debetta/archive/2007/03/09/t-sql-convert-hex-string-to-varbinary.aspx" class="broken_link">here</a>.  After some testing, and comparing results I was pleased with how well it worked.  Now that I had the pieces necessary, I could venture further down that little rabbit hole.</p>
<p>First though, there is one more piece that I want to discuss.  Remember that naming scheme for that auto created statistics?  I noted that the name is separate by an underscore &#8211; each element of the name anyway.  I decided that I would use that underscore as my string delimiter and implement a string split function to break out the name parts.  Any number of splitter functions would work.  I chose to use the same function that was written about by Jeff Moden <a href="http://www.sqlservercentral.com/articles/Tally+Table/72993/">here</a>.</p>
<p>Now all of the pieces have been referenced and are in play.  Let&#8217;s take a look at the query and some of those catalog views.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">with autostatnames as (  	
	SELECT split.itemnumber as Statnum,S.name, split.item as Statnamepart,s.object_id
		From sys.stats S
		CROSS APPLY dbo.DelimitedSplit8K(s.name,'_') split
		Where s.auto_created = 1
), statpart1 as (
	Select asn.name,CONVERT(INT,master.dbo.HexStrToVarBin('0x' + asn.Statnamepart)) as StatCol
		From autostatnames asn
		Where asn.Statnum = 4
), statpart2 as (
	Select asn.name,CONVERT(INT,master.dbo.HexStrToVarBin('0x' + asn.Statnamepart)) as StatObj
		From autostatnames asn
		Where asn.Statnum = 5
)

Select DISTINCT s.name as StatName, OBJECT_NAME(s2.StatObj) as TableName,COL_NAME(s2.StatObj,s1.StatCol) as ColName
		,s.auto_created
		,s.user_created
		,s.no_recompute
		,STATS_DATE(s.[object_id], s.stats_id) AS LastUpdated
	From statpart1 s1
		Inner Join statpart2 s2
			On s1.name = s2.name
		Inner Join sys.stats s
			On s.name = s1.name
Union All
SELECT DISTINCT
		OBJECT_NAME(s.[object_id]) AS TableName,
		COL_NAME(s.object_id,sc.column_id) as ColName,
		s.name AS StatName,
		s.auto_created,
		s.user_created,
		s.no_recompute,
		STATS_DATE(s.[object_id], s.stats_id) AS LastUpdated
	FROM sys.stats s 
		Inner Join sys.stats_columns sc 
			ON sc.[object_id] = s.[object_id] 
			AND sc.stats_id = s.stats_id
	Where s.auto_created = 0
	Order By s.name desc</pre><p>[/codesyntax]</p>
<p>I started this little script out with three quick CTEs.  The first is simply to gather the auto created stats.  It is in this first CTE that the string splitter is utilized.  The next two help me to separate out the data so I can work with it.  The second CTE is to manage the data related to the column part of the statistics name.  In this CTE, you will note that I employ the use of that Hex function.  The third CTE is just like the second, but it treats the data related to the table part of the statistics name.</p>
<p>When splitting the data in that first CTE, and due to the naming format, we see that the column is always the fourth part of the name and the table is the fifth part.  The first part is really an empty result due to the name leading off with an underscore.</p>
<p>Once the data is grouped into those CTEs, I can then return it in a friendlier result set.  Here I use more functions that are built in with SQL server.  This reduces the number of catalog views to which I need to JOIN.  And since the CTEs are only working with statistics that are auto generated, I need to UNION in another query to pull in those statistics that are not auto created.  Note that this query only looks at two catalog views.</p>
<p>What is the point of such an elaborate query in the first part to get this information when I can simply use the second part to do all of it?  Not a whole lot of point other than to prove a point.  There is consistency between the queries.  There is consistency between the naming of those statistics and the object data that can be found in those catalog views.</p>
<p>Any of these methods will return the desired results concerning statistics in the database.  You have essentially two methods displayed by me, and then the method employed by Pinal.  Have fun with it!!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1252" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/07/01/sql-statistics-another-spin/">SQL Statistics – another Spin</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/07/01/sql-statistics-another-spin/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #19 – Disasters &#038; Recovery</title>
		<link>https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-19-disasters-recovery</link>
					<comments>https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 14 Jun 2011 18:38:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1230</guid>

					<description><![CDATA[<p>There are three types of disasters that are seldom expected. Read about the fun of dealing with these different types of disasters.</p>
The post <a href="https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/">T-SQL Tuesday #19 – Disasters & Recovery</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>When I first read this article, I thought to myself &#8220;I have no clue on this one.  What could I write that would be unique or interesting?&#8221;</p>
<h2><a href="http://www.allenkinsel.com/archive/2011/06/invitation-for-t-sql-tuesday-19-disasters-recovery/"><img loading="lazy" class="alignright size-full wp-image-1232" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2011/06/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>My Disasters</h2>
<p>Have you heard that old axiom that bad things come in sets of three?  For me, I have three such tales and two of them have a correlation to SQL Server (at least in some degree).</p>
<h3>Disaster the First &#8211; You Can see it Coming</h3>
<p>This one is a slow, ongoing process.  We are in a state of watch and wait.  But it at least gives us a chance to prepare and thus be prepared.  We live in an area where a flood plain exists but once every 20-25 years.  It just so happens that this is one of those years.  Our neighborhood is preparing by digging ditches, building dykes and sandbagging the most likely flow areas.  We see it coming and we are making plans.</p>
<h3>Disaster the Second &#8211; Efforts Didn&#8217;t Go According to Plan</h3>
<p>Last Friday I was applying a software patch.  As you would have guessed, the patch did not go according to plan.  The patch actually corrupted windows files and caused windows to fail reboots.  I tried to repair the corrupted files (default action with Win7).  I also tried to restore to a previous checkpoint.  Last effort was to re-install Windows.  You know that means I had to re-install all of my apps as well.  Any settings in the apps (such as SSMS) would be lost.</p>
<p>In this case, I should have imaged my machine immediately prior to installing the patch.  In this case, I wanted to retrieve all of my SSMS registered servers.  In order to do that (even though I did not export the registered servers) I needed to locate the prior RegSvr.XML from the backup that the Windows Installation makes of an existing windows install.  In some cases this prior install will be relocated to windows.Old.  Search in that directory for the RegSvr.XML file and copy it to %username%\AppData\Roaming\Microsoft\Microsoft SQL Server\100\Tools\Shell.  This will RECOVER the registered servers in SSMS that you had there prior to the reinstall.  Of course you would first need to reinstall SQL Server Tools prior to attempting this.</p>
<h3>Disaster the Third &#8211; UnPlanned</h3>
<p>After successfully recovering from that minor disaster, I encountered a new disaster only after two days of laptop use.  Upon arriving on-site yesterday morning (and mind you the laptop worked at the hotel) in Chicago (which is out of state for me), my laptop froze, rebooted and came back to &#8220;No Boot Disk.&#8221;  Well, I was completely unprepared for this midlevel disaster.  I didn&#8217;t have my reinstall discs with me.  I did not have my laptop backed up from the Friday disaster &#8211; I was still trying to get everything back to normal.  I had but one option &#8211; buy a new laptop and try to recover the hard drive later.</p>
<p>In trying to make sure it was not going to boot, I booted the system to a Boot CD (UBCD and a couple others) to be certain.  I was getting Int13h errors trying to find the drive.  I checked CMOS and CMOS did not see the drive.  I bought the new laptop and first tried to boot the new laptop from that HDD.  It too did not recognize it.  The drive was not even spinning up at that time.</p>
<p>Today, I have attached that drive to an external cage and connected via USB.  It&#8217;s alive!!  The data is still there but some clusters are corrupt.  That is fine so long as I get the data.  In this case, I don&#8217;t normally take daily backups of my laptop drives.  In the future, I will be taking more frequent backups of the laptop drives.  And now I have a backup laptop for cases just like this.</p>
<p>And once this last disaster is recovered, I will be copying settings from apps on that laptop to the new laptop &#8211; might save a little time.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1230" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/">T-SQL Tuesday #19 – Disasters & Recovery</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/06/14/t-sql-tuesday-19-disasters-recovery/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>CTE, Recursion and Math</title>
		<link>https://jasonbrimhall.info/2011/05/23/cte-recursion-and-math/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cte-recursion-and-math</link>
					<comments>https://jasonbrimhall.info/2011/05/23/cte-recursion-and-math/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 23 May 2011 19:08:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[TSQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1215</guid>

					<description><![CDATA[<p>Earlier this month we had a TSQL Tuesday on the topic of CTEs.  I bailed on my submission because I already posted some CTE examples and was bone dry on what I could write about. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/05/23/cte-recursion-and-math/">CTE, Recursion and Math</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Earlier this month we had a TSQL Tuesday on the topic of CTEs.  I bailed on my <a href="http://jasonbrimhall.info/2011/05/10/t-sql-tuesday-18-ctes/">submission</a> because I already posted some CTE examples and was bone dry on what I could write about.</p>
<p>Later I saw a request for some help on creating combinations and permutations from TSQL.  I thought about this request and finally came up with the idea to use CTEs to do it.  The idea came about based on seeing multiple suggestions in that thread and then combining some of the pieces together.  Though not a suggestion, per-se, but seeing in the code submitted that a factorial was being used along with the sum of all integers from 1 to the given integer (or summation), I decided I would incorporate that into my solution.</p>
<p>I thus set out to create a solution that would use a CTE to generate those permutations, the summation, and the factorial.  In this article I will just be focusing on how I came to produce the factorial and summation using a little bit of Recursive CTE.  Also, we will see an alternative solution to calculating the summation.  For help in setting up the structure of a recursive CTE, you may want to refer to this <a href="http://msdn.microsoft.com/en-us/library/ms186243.aspx">article</a>.</p>
<p>Here is the script first, and then I will explain later.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @FactNum INT
SET @FactNum = '50';

WITH E1(N) AS ( --=== Create Ten 1's
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 UNION ALL
                 SELECT 1 UNION ALL SELECT 1 --10
               ),
      E2(N) AS (SELECT 1 FROM E1 a, E1 b),   --100
      E4(N) AS (SELECT 1 FROM E2 a, E2 b),   --10,000
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT N)) FROM E4  
),CTEMathN(N,Factorial,Aggreg,Iteration) AS ( 
	SELECT N
			,CAST(1 AS NUMERIC(38,0)) AS Factorial
			,N AS Aggreg
			,CAST(1 AS INT) AS Iteration
		FROM ctetally 
		WHERE N &amp;lt;= @FactNum
			AND @FactNum &amp;lt;= 33
	UNION ALL
	SELECT t.N
			,t.n * CAST(f1.Factorial AS NUMERIC(38,0)) AS Factorial
			,t.N + Aggreg AS Aggreg
			,CAST(f1.Iteration + 1 AS INT) AS Iteration
		FROM CTEMathN f1
			INNER JOIN cteTally T
				ON t.n = f1.n +1
				AND t.N &amp;lt;= @FactNum
),CTEMathF(N,Factorial,Aggreg,Iteration) AS ( 
	SELECT N
			,CAST(1 AS FLOAT) AS Factorial
			,N AS Aggreg
			,CAST(1 AS INT) AS Iteration
		FROM ctetally 
		WHERE N &amp;lt;= @FactNum
			AND @FactNum &amp;gt; 33
	UNION ALL
	SELECT t.N
			,t.n * CAST(f1.Factorial AS FLOAT) AS Factorial
			,t.N + Aggreg AS Aggreg
			,CAST(f1.Iteration + 1 AS INT) AS Iteration
		FROM CTEMathF f1
			INNER JOIN cteTally T
				ON t.n = f1.n +1
				AND t.N &amp;lt;= @FactNum
)

SELECT ISNULL(CAST(CN.N AS VARCHAR(100)),CAST(CF.N AS VARCHAR(100))) AS N
		,ISNULL(CAST(CN.Factorial AS VARCHAR(100)),CAST(CF.Factorial AS VARCHAR(100))) AS Factorial
		,ISNULL(CAST(CN.Aggreg AS VARCHAR(100)),CAST(CF.Aggreg AS VARCHAR(100))) AS Aggreg
	FROM CTEMathN CN
	FULL OUTER JOIN CTEMathF CF
		ON CN.N = CF.N
	WHERE ISNULL(CN.Iteration,CF.Iteration) = @FactNum</pre><p>[/codesyntax]</p>
<p>As you can see, I am using several CTEs in this script.  The first group of CTEs is to create a Dynamic Tally (Numbers) table.  The last two CTEs are performing the same thing but with a bit of filtering applied.  When you look at them, you should note that the first one is Casting the Factorial to a Numeric data type.  The last CTE is casting the Factorial to a FLOAT data type.  This isn&#8217;t necessarily required but more of an aesthetic for myself.  So any number greater than 33 will use the FLOAT data type and anything less than 34 will use the numeric data type.</p>
<p>The FLOAT data type will support those smaller numbers &#8211; that&#8217;s not an issue.  The Numeric data type will not support the larger values (it is limited to 38 characters).  We start running into arithmetic overflow at 34! and must use the FLOAT at that point.  The problem is that I prefer to avoid the overflow style of displaying the numbers except when necessary.  For simplicity sake, you could eliminate the filtering between the CTEs and simply use the FLOAT across the board.</p>
<p>Since I am trying to filter between the two and create a single row result set, I also have a second issue that is created by this code.  That issue is resolved and seen when performing the final select from the CTEs.  If the query requires the use of FLOAT, I will get an error message with an arithmetic overflow again unless I Convert the Numeric and Float results into something that is compatible between the two.  I chose to use VarChar(100) in this case.</p>
<p>Note, also, that I am using a FULL OUTER Join in the final query.  This is due to the fact that I will see results in either the CTEMathN or CTEMathF CTE but not both.</p>
<p>Now down into the nitty gritty.  Let&#8217;s look at CTEMathN to see how we are getting the factorial and the summation.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT N
			,CAST(1 AS NUMERIC(38,0)) AS Factorial
			,N AS Aggreg
			,CAST(1 AS INT) AS Iteration
		FROM ctetally 
		WHERE N &amp;lt;= @FactNum
			AND @FactNum &amp;lt;= 33
	UNION ALL
	SELECT t.N
			,t.n * CAST(f1.Factorial AS NUMERIC(38,0)) AS Factorial
			,t.N + Aggreg AS Aggreg
			,CAST(f1.Iteration + 1 AS INT) AS Iteration
		FROM CTEMathN f1
			INNER JOIN cteTally T
				ON t.n = f1.n +1
				AND t.N &amp;lt;= @FactNum</pre><p>[/codesyntax]</p>
<p>First we have the required anchor definition.  Second we have the recursion definition joined by the Union All and referencing the same CTE where both of these pieces reside.</p>
<p>The factorial is easy enough.  Since a Factorial is n! or n(n-1) we can multiply n by the previous n in the sequence.  We can get both of those values through our join statement where we join back out to the Tally CTE and showing an increment in the number (here I am join CTETally.n to CTEMathN +1).  This ensures we will move through the record set (or recurse).</p>
<p>The same principle applies for the summation.  We add each number in the sequence from 1 to n to retrieve our result.  So, much the same as the factorial, I add n to the previous value of n and proceed from there through the record set.</p>
<p>Note also that I threw an additional limiting factor on the where clause.  I want to make sure that I do not try to recurse through a record set that includes numbers outside of my range.</p>
<p>Now, since I only really care about the factorial and summation for the number I inserted in the variable at the beginning, I want to make sure that I have a filter added to the final select clause.  Here is that final filter&#8230;</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">WHERE ISNULL(CN.Iteration,CF.Iteration) = @FactNum</pre><p>[/codesyntax]</p>
<p>This enforces a single record will be returned by selecting only the last iteration.  Iteration is another column in the CTEs that is used during our recursion process.  The iteration column just increments by a value of one with each pass.</p>
<p>Pretty easy eh?</p>
<p>Now, if all you need is a summation and it is not used to control result sets (like mine will be in the next bit where we discuss permutations), then you could rip out the aggregation stuff and just use this in the final select statement&#8230;</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">((@FactNum * @FactNum)+ @FactNum )/ 2 AS Summation</pre><p>[/codesyntax]</p>
<p>That would be in place of this bit&#8230;</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">ISNULL(CAST(CN.Aggreg AS VARCHAR(100)),CAST(CF.Aggreg AS VARCHAR(100))) AS Aggreg</pre><p>[/codesyntax]</p>
<p>Have fun with it!!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1215" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/05/23/cte-recursion-and-math/">CTE, Recursion and Math</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/05/23/cte-recursion-and-math/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQLSat 83 &#8211; Johannesburg</title>
		<link>https://jasonbrimhall.info/2011/04/28/sqlsat-83-johannesburg/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlsat-83-johannesburg</link>
					<comments>https://jasonbrimhall.info/2011/04/28/sqlsat-83-johannesburg/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 28 Apr 2011 22:03:51 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1176</guid>

					<description><![CDATA[<p>Awesome news.  I submitted a presentation for SQLSat 83 in Johannesburg South Africa for May 7, 2011.  I saw that they were opening up the presentation schedule a little bit to allow for remote presenters [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/04/28/sqlsat-83-johannesburg/">SQLSat 83 – Johannesburg</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Awesome news.  I submitted a presentation for SQLSat 83 in Johannesburg South Africa for May 7, 2011.  I saw that they were opening up the presentation schedule a little bit to allow for remote presenters and I decided to give it a try.</p>
<p>I got an email notification yesterday that my presentation has been accepted and I will be presenting &#8211; woohoo.  If you are interested, you can see the presentation schedule <a href="http://www.sqlsaturday.com/83/schedule.aspx">here</a>.  My presentation will be similar to the last time I presented at SQLSaturday in Salt Lake City &#8211; but with some refinements and hopefully a better overall presentation.  I will be sharing some of the tools/scripts I use to help learn more about an environment as I inherit a database.</p>
<p>Here&#8217;s the fun part &#8211; I will be presenting from my home in Utah which is 8 hours behind Johannesburg.  At the time of my presentation (12:15 PM there) it will be 4:15AM local for me.  That should make for an interesting presentation if I am groggy. <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>If you are in the area at the time of the event (in Johannesburg), I highly recommend you make it out to some sessions.  From looking at the lineup, there appears to be some really good stuff to be presented.  As we get closer to May 7th, I will post more information.  For now, I need to go clean up my slidedeck and get it submitted.</p>
<p>Parting note:  I am glad I was selected for this SQLSaturday.  If you read my SQLPeople interview (<a href="https://andyleonard.blog/2011/05/sqlpeople-interviews-and-news-for-april-2011/">here</a>), you may recall that I lived in the area for a couple of years.  I only passed through Johannesburg when returning home but have always wanted to go back and visit.  It has been quite some time and I have yet to make it back.  At least now I can do it virtually!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1176" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/04/28/sqlsat-83-johannesburg/">SQLSat 83 – Johannesburg</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/04/28/sqlsat-83-johannesburg/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQLPeople Interview</title>
		<link>https://jasonbrimhall.info/2011/04/25/sqlpeople-interview/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlpeople-interview</link>
					<comments>https://jasonbrimhall.info/2011/04/25/sqlpeople-interview/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 25 Apr 2011 16:53:33 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[SQLPeople]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1171</guid>

					<description><![CDATA[<p>Have you heard about this new project out there called SQLPeople?  It is a new (relatively) project that is the brainchild of Andy Leonard.  Andy is trying to help the community to get to know [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/04/25/sqlpeople-interview/">SQLPeople Interview</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Have you heard about this new project out there called SQLPeople?  It is a new (relatively) project that is the brainchild of Andy Leonard.  Andy is trying to help the community to get to know each other better than they already do.</p>
<p>Part of this initiative is to conduct interviews and post them to <a href="http://sqlpeople.net" class="broken_link">SQLPeople.net</a> on a regular basis.  Well, Friday April 22nd was the day that my interview was published.  It&#8217;s a standard set of questions to be answered by each person on the site.  You can read about me and my answers <a href="https://andyleonard.blog/2011/05/sqlpeople-interviews-and-news-for-april-2011/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1171" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/04/25/sqlpeople-interview/">SQLPeople Interview</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/04/25/sqlpeople-interview/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SSIS Job Ownership</title>
		<link>https://jasonbrimhall.info/2011/04/11/ssis-job-ownership/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssis-job-ownership</link>
					<comments>https://jasonbrimhall.info/2011/04/11/ssis-job-ownership/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 11 Apr 2011 14:00:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1157</guid>

					<description><![CDATA[<p>I was strolling along one day when I saw somebody asking how to find out who owns a maintenance plan.  That evolved into finding out who owns the the job associated with the maintenance plan. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/04/11/ssis-job-ownership/">SSIS Job Ownership</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I was strolling along one day when I saw somebody asking how to find out who owns a maintenance plan.  That evolved into finding out who owns the the job associated with the maintenance plan.  All of this in SQL 2005 and SQL 2008.</p>
<p>Well, we were stumped for a bit trying to figure the link between the job tables in the msdb database and the ssis table in the same database.  Linking the two together is not very obvious and we struggled with it for a bit.  After some research and trying this that and the other, I was able to come up with the below script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Display SSIS Package Owners and Job Owners SQL 2008
 Select dts.[name]
        ,dts.[description]
        ,dts.createdate
        ,dts.ownersid
        ,p.name As PackageOwner
        ,JOB.name as JobOwner
        ,SSISPackageType =
			case dts.packagetype
				when 0 then 'default value'
				When 1 Then 'SQL Server Import and Export Wizard'
				When 2 Then 'DTS Designer in SQL Server 2000'
				When 3 Then 'SQL Server Replication'
				When 5 Then 'SSIS Designer'
				When 6 Then 'Maintenance Plan Designer or Wizard'
			End
   From msdb.dbo.sysssispackages       dts
	Left Join master.sys.server_principals   p
		On p.sid = dts.ownersid
	Left Outer Join msdb.dbo.sysjobsteps SJS
		On dts.name = substring(SJS.command,CHARINDEX('\',sjs.command)+1,charindex('&quot;',sjs.command,CHARINDEX('\',sjs.command))-CHARINDEX('\',sjs.command)-1)
		And SJS.subsystem = 'ssis'
	Left Outer Join msdb.dbo.sysjobs SJ
		On SJS.job_id = SJ.job_id
	Left Outer Join master.sys.server_principals JOB
		On JOB.sid = SJ.owner_sid
Go</pre><p>[/codesyntax]</p>
<p>This script is set to work out of the gate with SQL 2008.  Should you want it to work with SQL 2005 the change is simple.  Change the sysssispackages table to sysdtspackages90.  As you can see, the query joins the SSIS table to the jobsteps table with a pretty nasty string extraction.  There are other ways of extracting this information (I&#8217;m sure of it).  This works quite well for what it is intended.</p>
<p>Using this script, you can find out the jobowner, the packageowner, and the packagetype.  This is pretty good information to have on hand if you have several ssis packages that are stored in msdb and are run from a job.  One thing this script does not yet handle is if the SSIS file is stored on the file system.  Note that I only coded it so far to work with files stored in SQL.  When looking in the jobsteps table, you can tell the difference quickly by seeing that those stored in msdb have a /SQL at the beginning of the command string.  Those in the filesystem have a /FILE en lieu of that /SQL.</p>
<p>In a future revision I will work on parsing the package name out of that string that represents those stored in the file system.  And despite that nasty join, this runs quickly on my systems.  I am open to suggestions or other solutions that can provide this kind of insight.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1157" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/04/11/ssis-job-ownership/">SSIS Job Ownership</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/04/11/ssis-job-ownership/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>S3OLV April 2011</title>
		<link>https://jasonbrimhall.info/2011/04/05/s3olv-april-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=s3olv-april-2011</link>
					<comments>https://jasonbrimhall.info/2011/04/05/s3olv-april-2011/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 05 Apr 2011 19:17:12 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1148</guid>

					<description><![CDATA[<p>Are you ready to learn again?  The Las Vegas SQL Users Group is ready to have our April meeting.  The meeting is to be held April 14, 2011 at 6:30 PST. This month we have [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/04/05/s3olv-april-2011/">S3OLV April 2011</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Are you ready to learn again?  The Las Vegas SQL Users Group is ready to have our April meeting.  The meeting is to be held April 14, 2011 at 6:30 PST.</p>
<p>This month we have a BI presentation lined up and some top notch talent to present to us.  Erika Bakse will be teaching some excellent tips and tricks revolving around MDX and SSRS.</p>
<p>Abstract:<br />
Reporting Services is a powerful tool that can make designing reports a snap&#8230;most of the time. But every once in a while you have to format a report very specifically, and the data just isn&#8217;t available in the form you need it to do that.  Enter Clever Queries!  Learn about how to use named sets, dummy members, and other MDX tricks to craft your data query in a way that allows you to conquer the trickiest report layouts.</p>
<p>This month, Erika will be presenting in person at the Learning Center.  But don&#8217;t be dismayed if you cannot attend in person.  We will be broadcasting the event via Livemeeting once again.</p>
<p>To access the meeting via livemeeting, just follow these steps:</p>
<p><span style="font-family: Tahoma; font-size: x-small;">To join the meeting? Follow these steps:</span></p>
<ol>
<li><span style="font-family: Tahoma; font-size: x-small;">Copy this address and paste it into your web browser: </span><br />
<span style="font-family: Tahoma; font-size: x-small;">https://www.livemeeting.com/cc/UserGroups/join</span></li>
<li><span style="font-family: Tahoma; font-size: x-small;">Copy and paste the required information: </span><br />
<span style="font-family: Tahoma; font-size: x-small;">Meeting ID: F598S6 </span><span style="font-family: Tahoma; font-size: x-small;"><br />
</span><span style="font-family: Tahoma; font-size: x-small;">Location: https://www.livemeeting.com/cc/UserGroups</span></li>
</ol>
<p>We hope to see you there (either in person or via livemeeting).</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1148" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/04/05/s3olv-april-2011/">S3OLV April 2011</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/04/05/s3olv-april-2011/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Indexing Just Got Easy</title>
		<link>https://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=indexing-just-got-easy</link>
					<comments>https://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 01 Apr 2011 11:00:17 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[April 1]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Myth]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1130</guid>

					<description><![CDATA[<p>As a database professional one of the things that we should be familiar with is the use of indexes.  In SQL Server an index helps to improve query performance &#8211; when properly implemented.  There are [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/">Indexing Just Got Easy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As a database professional one of the things that we should be familiar with is the use of indexes.  In SQL Server an index helps to improve query performance &#8211; when properly implemented.  There are some penalties in play when an index is created.  These penalties are typically associated with the insert update and delete operations.  Other penalties might revolve around a poorly defined index that may cause more work to be done for a given query.  As a database professional, it is within our best interest to strike a harmony between benefit and penalty through analysis and tuning of these indexes.  We want the benefits to offset the penalties for the index to be of worth to the query and system.</p>
<p>In SQL Server we have been given an array of tools over time to help us with this effort.  Microsoft gave us the Index Wizard in SQL 2000.  Then we got a decent upgrade with the Database Tuning Advisor in SQL 2005.  Microsoft has been attempting to continue to make a better more agile product for the database professional so s/he can spend time doing other equally important duties.  It appears that we now have a new tool to help us do just that.</p>
<p>First, let&#8217;s recap the predecessors.</p>
<h3>Index Tuning Wizard</h3>
<p>This tool was born in SQL 2000.  The intent was to give the Database Professional a view into the big picture.  Not just look at one index for one query isolated from other tables, views, and queries.  When used properly, this tool could give the professional a decent idea of the indexes that were needed throughout the system.  A common faux-pas was a blanket acceptance of the proposed indexes &#8211; good or bad.  Yes, this tool did recommend many bad indexes.  You can learn more about the tool if you would like, from <a href="http://technet.microsoft.com/en-us/library/cc966541.aspx"><span style="color: #339966;"><strong>here</strong></span></a>.</p>
<h3>Database Engine Tuning Advisor</h3>
<p>This tool was introduced by Microsoft with SQL 2005.  DTA made significant advancements over the predecessor.  The main purpose is much the same as the Index Tuning Wizard.  DTA did produce more reliable results (IMHO) and seemed to be more efficient at doing it.  Unfortunately, there was still the possibility of getting some bad recommendations.  And yes, the bigger issue is that there was blanket acceptance of all indexes.  You can learn more about this tool <a href="http://technet.microsoft.com/en-us/library/ms173494.aspx"><span style="color: #339966;"><strong>here</strong></span></a>.  This tool is available in SQL 2005, 2008 and 2008 R2.</p>
<h3>GAIHA (pronounced like GAIA / GAYA)</h3>
<p>GAIHA is Genetic Algorithm Index Heuristic Automation.  This name was chosen for multiple reasons, one of which is the pronunciation similarity with Gaya.  For some Gaya infers &#8220;enlighten.&#8221;  The hope for this product is to really help the database reach that next level and appear to be enlightened because it runs that much more seamlessly and effortlessly.</p>
<p>Rumor has it that GAIHA is on the docket to be released with a future version of SQL Server.  This tool has the same prime directive as the predecessors.  As the name implies though &#8211; it&#8217;s like DTA on steroids.  Furthermore, it is entirely automated.  Just like you can enable auto-update of statistics you will be able to enable GAIHA.  Much the same as new statistics get created based on data usage and data volume &#8211; indexes will auto-create based on query usage.</p>
<p>The automation of GAIHA will use advanced algorithms and heuristics.  Think of the <a href="http://en.wikipedia.org/wiki/Heuristic"><span style="color: #339966;"><strong>heuristics</strong></span></a> as the recording of usage patterns and the system learning how the system is used over and over again.  Then it triggers an algorithm to run hundreds of generations of possible indexes and then picking one that would be the best fit.  Your query that ran in ten seconds today will run in ten milliseconds tomorrow.  What&#8217;s more, all you did was use the system.</p>
<p>Is there the potential for bad indexes &#8211; yes.  Would you still be able to create your own indexes &#8211; yes.  If enabled, would this be entirely maintenance free &#8211; no.  I don&#8217;t imagine it to be entirely maintenance free.  Take the auto update on your statistics for example.  Though you may have that enabled, you still have to do manual statistics updates on occasion.  I envision the same kind of behavior in the future.</p>
<h2>Conclusion</h2>
<p>There you have it.  The tools keep getting better and better.  This is true especially when the next generation tool is entirely fictional.  There is no such tool and it was completely derived from imagination.  Would it be nice to have &#8211; sure.  I envision the DTA being many magnitudes better if it were recreated to be similar to a product by Quest called <a href="https://web.archive.org/web/20130522212843/http://toadforsqlserver.com:80/index.jspa"><strong><span style="color: #339966;">TOAD</span></strong></a>.  I liked the feature in TOAD from many moons ago that allowed me to input a query and see it refactored 100 different ways with varying performance gains.  This would be extremely useful for many Database Professionals.</p>
<p>If you would like to see a genetic algorithm at work in SQL Server, check out this <a href="http://sqlinthewild.co.za/index.php/2011/02/22/and-now-for-a-completely-inappropriate-use-of-sql-server/"><strong><span style="color: #339966;">blog</span></strong></a> by Gail Shaw.</p>
<p><span style="color: #ff0000;">Happy April Fools</span>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1130" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/">Indexing Just Got Easy</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/04/01/indexing-just-got-easy/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Do You Solution?</title>
		<link>https://jasonbrimhall.info/2011/03/29/do-you-solution/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=do-you-solution</link>
					<comments>https://jasonbrimhall.info/2011/03/29/do-you-solution/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 29 Mar 2011 14:00:49 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SSMS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1116</guid>

					<description><![CDATA[<p>Do you ever find yourself working on different scripts at once?  Maybe you are working on something that tests certain functionality in SQL Server, you have some presentation scripts you are working on, and possibly [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/03/29/do-you-solution/">Do You Solution?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Do you ever find yourself working on different scripts at once?  Maybe you are working on something that tests certain functionality in SQL Server, you have some presentation scripts you are working on, and possibly three or four scripts related to a project at work.  I find myself in a situation like this from time to time &#8211; multiple scripts open checking this or that.</p>
<p>How do you organize your scripts?  Do you leave them all open in SSMS?  Do you create a folder structure on your disk somewhere and set yourself a reminder task?  I have left them all open in SSMS on occasion because I wanted to come back to them and work on them and it can help remind me where I am in the thought process and what needs to be done next.</p>
<p>Did you know that there is a feature in SSMS to help you with organizing yourself?  It&#8217;s not there just to help you get organized &#8211; but it can also help with efficiency and recoverability of files.  I&#8217;ll explain the recoverability a bit later.</p>
<p><img loading="lazy" class="alignright size-full wp-image-1118" title="SolutionExplorer" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/SolutionExplorer.jpg" alt="" width="238" height="182" /></p>
<p>SSMS has a feature called &#8220;Solution Explorer.&#8221;  Much like Visual Studio or BIDs (which is Visual Studio), you have the ability to create a solution file to manage your projects.  This solution can then be stored on disk and updated as you progress through the solution or projects.</p>
<p>If you want to display this feature, click the View Menu from the toolbar and then select &#8220;Solution Explorer.&#8221;  This will open a new pane in your management studio from which you can add new or existing projects as well as rename the solution.  To the right is an example of one of my solutions.  In this image, you can see that I have two projects displayed associated with this particular solution.  In these projects, I have loaded numerous script files for each of the projects as I work on them.  Some of these scripts are testing the results of stored procs, while others may be stored procs, and yet others may be tables.  What the script performs immaterial to Solution Explorer.</p>
<p>Should I decide that I need multiple files open from the project, I can highlight them all and open them all at once.  Nothing earth shattering, but now I have an easy way to see the files associated with each task or project as I work on the task/project.</p>
<p>The project files are stored in XML format and are saved off to disk in a directory of your liking.  An unfortunate problem with this kind of storage is the sorting of your scripts in the project.  Despite this problem there is a way to fix it.  I found the fix for that at this <a href="https://web.archive.org/web/20111027222359/http://beyondrelational.com/blogs/jacob/archive/2009/08/22/xquery-lab-48-sorting-query-files-in-sql-server-management-studio-ssms-solution-project.aspx">blog</a>.  It is nice to have scripts sorted properly to your liking.  I recommend giving that blog a read and I would recommend the use of this feature in SSMS &#8211; if you aren&#8217;t doing something already (for instance in Visual Studio, SVN or something like that).</p>
<p>I like having the ability to see all of the scripts quickly that I may need on the same screen I am working in.  I can bounce quickly between the scripts as needed and I don&#8217;t necessarily have to keep them open indefinitely while working out the task at hand.</p>
<p>I mentioned earlier that it also helps with the recoverability of files.  Let me explain a bit.  Have you ever been in the middle of working on a script and then the dreaded forced shutdown occurs due to updates?  Just in case you did not get your files saved, SSMS has an autorecover feature as well as an autosave feature.  Files that are Autorecover and Autosave (recovered) are saved commonly in Solution1.  They are stored in your user profile directory and can be brought back so you can continue working on them.</p>
<p>Should you need to find these files, here is a common path you can use to retrieve them.</p>
<p>%userprofile%\Documents\SQL Server Management Studio\Backup Files\Solution1</p>
<p>Do you want to learn more about this feature?  Check out the Microsoft documentation on the topic.  You can view that <a href="http://msdn.microsoft.com/en-us/library/ms174161.aspx">here</a>.</p>
<p><img loading="lazy" class="alignleft size-full wp-image-1119" title="movequerytoproject" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/movequerytoproject.jpg" alt="" width="356" height="194" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/movequerytoproject.jpg 356w, https://jasonbrimhall.info/wp-content/uploads/2011/03/movequerytoproject-300x163.jpg 300w" sizes="(max-width: 356px) 85vw, 356px" /></p>
<p>Something that I really like about this feature is the ability to create a script either directly in the project, add an existing script, or take a script that you started working on outside of the project and move it into the project from within SSMS.  It took me a bit of looking to find how to add a script from SSMS directly to the project (when not initiated from within the project).  It is really easy to do once you find it.  Here is how to do it.</p>
<p>With the focus in SSMS active on the script you wish to move, click on the File menu.  From the File menu you will have an option to Move the script that you are currently working on in SSMS.  From there Select the appropriate project and it is that simple.</p>
<p>*Note: In the example of the image being displayed, you can see that the query was SQLQuery1.sql that I wanted to move.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1116" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/29/do-you-solution/">Do You Solution?</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/29/do-you-solution/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server Startup</title>
		<link>https://jasonbrimhall.info/2011/03/23/sql-server-startup/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-startup</link>
					<comments>https://jasonbrimhall.info/2011/03/23/sql-server-startup/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 23 Mar 2011 14:00:16 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Database Maintenance]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1101</guid>

					<description><![CDATA[<p>From time to time I see a question asking how to determine the last time a SQL Server was either restarted or when the last time was that the database was used.  For the first [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/03/23/sql-server-startup/">SQL Server Startup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>From time to time I see a question asking how to determine the last time a SQL Server was either restarted or when the last time was that the database was used.  For the first question there is a pretty common answer that works for SQL 2000 and up.  In answering both questions though, I am going to show you three quick similar scripts that can be used to find this information.  The catch is that these queries will not work on SQL 2000.  On the flipside, it should give you an idea of what can be done to find out the same info for SQL 2000.</p>
<h3>TempDB</h3>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">with lastDBaccess as (
	Select 
		DB_NAME(database_id) AS DatabaseName,
		MAX(coalesce(last_user_seek,last_user_scan,last_user_lookup)) as LastRead,
		MAX(last_user_update) as LastWrite
	FROM sys.dm_db_index_usage_stats
	Group By database_id
)
Select CDate.create_date as ServerStartupDate
	,LA.* from lastDBaccess LA
	Cross Apply (Select create_date From sys.databases
					Where name = 'tempdb') CDate
	Order By DatabaseName</pre><p>[/codesyntax]</p>
<p>A common answer to the question of when was SQL Server last started is to check the Create_Date of the tempdb database.  Since tempdb is recreated every time SQL Server is restarted, it is a pretty accurate timestamp of the server start.  This query was written to work for SQL 2005 and above, but you can still find the create_date of the tempdb database in SQL 2000 by using a different query.</p>
<h3>sys.dm_exec_requests</h3>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">with lastDBaccess as (
	Select 
		DB_NAME(database_id) AS DatabaseName,
		MAX(coalesce(last_user_seek,last_user_scan,last_user_lookup)) as LastRead,
		MAX(last_user_update) as LastWrite
	FROM sys.dm_db_index_usage_stats
	Group By database_id
)
Select CDate.start_time as ServerStartupDate
	,LA.* from lastDBaccess LA
	Cross Apply (Select start_time From sys.dm_exec_requests
					Where session_id = 1) CDate
	Order By DatabaseName</pre><p>[/codesyntax]</p>
<p>In this query we access one of those Dynamic Management views available in SQL 2005 and up.  In this case, we look at the first process id similar to what one may have done with sysprocesses in sql 2000.  Now is probably a good time to also note something that is happening inside the CTE.  Notice the COALESCE that is being used?  I am taking the Max from those fields that are associated with read type of activities in a database.  This information is being pulled from a DMV called sys.dm_index_usage_stats.  This query will get me the most recent activity for reads and writes in each database (notice the group by).</p>
<h3>Default Trace</h3>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @TraceFile varchar(256)

Select @TraceFile = convert(varchar(256),value) from [fn_trace_getinfo](NULL) 
WHERE [property] = 2;

;
with lastDBaccess as (
	Select 
		DB_NAME(database_id) AS DatabaseName,
		MAX(coalesce(last_user_seek,last_user_scan,last_user_lookup)) as LastRead,
		MAX(last_user_update) as LastWrite
	FROM sys.dm_db_index_usage_stats
	Group By database_id
)
Select CDate.StartTime as ServerStartupDate
	,LA.* from lastDBaccess LA
	Cross Apply (SELECT StartTime 
					FROM [fn_trace_gettable](@TraceFile, DEFAULT) 
					Where EventSequence = 1
						And IsSystem = 1) CDate
	Order By DatabaseName</pre><p>[/codesyntax]</p>
<p>The last one is to make use of the default trace in SQL 2005, 2008 and 2008 R2.  The default trace records the time of certain events that occur in the database and that includes when the database is starting up.  To find the server startup time in this case, I am checking the EventSequence and IsSystem fields for a value of 1.  As you can see, I also dumped the filepath for the default trace file into a variable and use that in the function to get the data.</p>
<p>When comparing performance of these three options, they pretty much came out even.  Each took its turn performing faster &#8211; with regards to time.  However, the default trace method did return a more expensive execution plan every single time.  With how fast these queries run, I&#8217;m not real sure that that is very conclusive nor that it would be a heavy concern.  These queries are designed more for the occasional run by the DBA rather than to be executed millions of times a day.  You decide which will be best for you.  I think with the use of the function to get the default trace info, I was mildly surprised that the query performed that well.</p>
<p>Another thing to note is that each of these methods will return a slightly different timestamp.  For instance, the tempdb timestamp gives me 3:21:28 and the sys.dm_exec_requests produces a timestamp of 3:21:36 and the tracefile shows a timestamp of 3:21:24.  I don&#8217;t have any hard foundation for why that is &#8211; just speculation that seems to make sense.  I will just leave it at that though.</p>
<p>In addition to these methods there is also the option of checking the system event logs to determine the SQL Service startup time.  This information should help you when investigating your databases and server and would be something handy to keep in your toolbox.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1101" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/23/sql-server-startup/">SQL Server Startup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/23/sql-server-startup/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Resource</title>
		<link>https://jasonbrimhall.info/2011/03/22/sql-resource/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-resource</link>
					<comments>https://jasonbrimhall.info/2011/03/22/sql-resource/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 22 Mar 2011 14:00:33 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Internals]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1089</guid>

					<description><![CDATA[<p>By now, I am sure that you are well aware of the Resource Database.  Starting with SQL Server 2005, a new system database was made available &#8211; the Resource Database.  In SQL 2005 you could [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/03/22/sql-resource/">SQL Resource</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>By now, I am sure that you are well aware of the Resource Database.  Starting with SQL Server 2005, a new system database was made available &#8211; the Resource Database.  In <a href="http://msdn.microsoft.com/en-us/library/ms345408(v=SQL.90).aspx">SQL 2005</a> you could move the Resource Database &#8211; but in <a href="http://msdn.microsoft.com/en-us/library/ms345408(v=SQL.100).aspx">2008</a> and beyond you cannot.  If you plan your install accordingly, your databases should install where you would like them (i.e. the program files directory that is the default installation directory can be changed during setup).</p>
<p>That is all well and good, but what is in this database and how can we take a look into it?  I thought about this as I was reading a <a href="http://thomaslarock.com/2011/03/march-madness-sql-server-system-tables-sysdatabases/">blog</a> by Thomas LaRock where he discusses system tables and system views.  I started thinking about the underpinnings of these views and if we could see them in the resource databse.  Taking a peek into the Resource Database is rather trivial.  I will show you how to copy that database and attach it as an alternate database.</p>
<p>The first step in taking a peek is to locate the directory where the data and log file for the hidden database are stored.  You can find the path by referring back to the SQL 2005 and 2008 links earlier in this post.  In my case, the path (I am using SQL 2008 SP2) for me is displayed in the next image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/orig_filepath1.jpg"><img loading="lazy" class="alignnone size-full wp-image-1092" title="orig_filepath" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/orig_filepath1.jpg" alt="" width="679" height="157" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/orig_filepath1.jpg 679w, https://jasonbrimhall.info/wp-content/uploads/2011/03/orig_filepath1-300x69.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Take the two highlighted files, copy them and place them into a new directory.  I copied and renamed the files &#8211; placing the files into my &#8220;Data&#8221; directory as follows.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/copiedto_path.jpg"><img loading="lazy" class="alignnone size-full wp-image-1094" title="copiedto_path" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/copiedto_path.jpg" alt="" width="682" height="161" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/copiedto_path.jpg 682w, https://jasonbrimhall.info/wp-content/uploads/2011/03/copiedto_path-300x70.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>As you can see, the database is rather small &#8211; and you could probably do this procedure multiple times ;).</p>
<p>Once you have the files copied to the new locations, you are now ready to attach the database.  I am just using the GUI to attach the database &#8211; for illustrative purposes.  While attaching, I think there is an interesting thing that should stand out.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource.jpg"><img loading="lazy" class="alignnone size-full wp-image-1095" title="attach_resource" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource.jpg" alt="" width="949" height="414" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource.jpg 949w, https://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource-300x130.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>Now look closely at the image just above &#8211; pay attention to the current file path.  This is the screen you will see after you browse to your new directory location and choose to add the mdf file for the Resource database.  You will see that this file path does not match either of the file paths that I have already shown.  Take a closer look:</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/resource_filepath2.jpg"><img loading="lazy" class="alignnone size-full wp-image-1096" title="resource_filepath" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/resource_filepath2.jpg" alt="" width="484" height="64" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/resource_filepath2.jpg 484w, https://jasonbrimhall.info/wp-content/uploads/2011/03/resource_filepath2-300x39.jpg 300w" sizes="(max-width: 484px) 85vw, 484px" /></a></p>
<p>You can see that the file path references a path for e:\sql10_katmai_t\sql&#8230;  I find that pretty interesting.  I don&#8217;t know the reason for that path persisting like that.  The file paths shown need to be changed to the appropriate file path where we placed the copied files &#8211; as follows.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource_correctedpath.jpg"><img loading="lazy" class="alignnone size-full wp-image-1097" title="attach_resource_correctedpath" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource_correctedpath.jpg" alt="" width="846" height="413" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource_correctedpath.jpg 846w, https://jasonbrimhall.info/wp-content/uploads/2011/03/attach_resource_correctedpath-300x146.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>There is one more thing that I think you should change.  This really is a matter of preference and is good housekeeping.  Change the name of the database in the Attach As field.  I appended _test to the end of the database name.  This should make it obvious that this database is NOT the system database.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/attachas.jpg"><img loading="lazy" class="alignnone size-full wp-image-1098" title="attachas" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/attachas.jpg" alt="" width="659" height="64" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/attachas.jpg 659w, https://jasonbrimhall.info/wp-content/uploads/2011/03/attachas-300x29.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>With these few steps, you now have the resource database attached as a User Database.  With that, you now can take a look at the inner makings of some of the system views.  Take the following queries for example:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select * from master.dbo.sysdatabases
select * from mssqlsystemresource_test.sys.sysdatabases</pre><p>[/codesyntax]</p>
<p>Both of these queries return exactly the same thing.  Both of these queries are only provided as a means of backwards compatibility.  You can actually see master.sys.sysdatabases (just like mssqlsystemresource_test.sys.sysdatabases).  One thing you can do though is script out that view and see what the source of the data is.  Well&#8230;with the resource database attached as described, you can now script it out.  When you script out the view, make sure you try to script the correct version of it.  Just like any user database, you will get a category of system tables and one of system views.  The objects under those categories cannot be scripted.  The objects, however, are also represented in this database as &#8220;user&#8221; objects &#8211; which can be scripted.</p>
<p>After you script out the object, sys.sysdatabases you will see that the source of the data is the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">FROM sys.databases d
	LEFT JOIN sys.master_files$ f</pre><p>[/codesyntax]</p>
<p>There you have it &#8211; this view is predicated on the newer view called sys.databases.  As has been said over and over again, it only exists as a backwards compatibility view until Microsoft decides to remove it.  Also note that the other part of the foundation for the sysdatabases view is the sys.master_files$ view.  You can now see this in the system views collection inside the Resource database that we attached.  Unfortunately you can&#8217;t script it, but at least you can see the columns that it would return.  You also can&#8217;t query directly to that view &#8211; you have to reach it through the system views.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1089" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/22/sql-resource/">SQL Resource</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/22/sql-resource/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Dedupe Data CTE</title>
		<link>https://jasonbrimhall.info/2011/03/21/dedupe-data-cte/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dedupe-data-cte</link>
					<comments>https://jasonbrimhall.info/2011/03/21/dedupe-data-cte/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 21 Mar 2011 14:00:44 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1082</guid>

					<description><![CDATA[<p>As a DBA working with SQL Server, some data issues arise that need to be fixed.  One such data issue is the duplication of data.  Duplicate data can happen for a number of reasons.  One [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/03/21/dedupe-data-cte/">Dedupe Data CTE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As a DBA working with SQL Server, some data issues arise that need to be fixed.  One such data issue is the duplication of data.  Duplicate data can happen for a number of reasons.  One such reason is the absence of constraints such as Primary Keys.</p>
<p>Luckily, there are ways for the Data Professional to clean up such a quagmire.  First, let&#8217;s set the stage with a really simple example.</p><pre class="urvanov-syntax-highlighter-plain-tag">Create Table DupeDemo (DemoID Int, SomeInt Int)

Insert Into DupeDemo
SELECT TOP 10000
        DemoID       = ABS(CHECKSUM(NEWID()))%100+1,
		SomeInt      = ABS(CHECKSUM(NEWID()))%50+1
	FROM Master.dbo.SysColumns t1
CROSS JOIN Master.dbo.SysColumns t2</pre><p>Here, we are simply creating a table and populating the table with two columns of randomized data.  This should give us a significant amount of duplicate data and a good enough test bed to demonstrate how to quickly fix this issue.  Due to the random nature of these inserts, we will get a significant range of duplicates for some values and maybe no duplicates at all for other values.  (Did that make sense?)</p>
<p>Let&#8217;s check our work and see how well we did with the duplicate creation.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select *
	From DupeDemo
	Order By DemoID,SomeInt</pre><p>Each time I have run this, I have come up with a good test bed.  It should work relatively well for you as well.  Now, we can work on eliminating those duplicates.  To better illustrate that we have dupes and the distribution, let&#8217;s have a look at this query.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select DemoID,SomeInt, COUNT(SomeInt) as Counted
	From DupeDemo
	Group By DemoID,SomeInt
	Order By DemoID,SomeInt</pre><p><img loading="lazy" class="alignright size-full wp-image-1084" title="DupeDetect" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/DupeDetect.jpg" alt="" width="207" height="383" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/DupeDetect.jpg 207w, https://jasonbrimhall.info/wp-content/uploads/2011/03/DupeDetect-162x300.jpg 162w" sizes="(max-width: 207px) 85vw, 207px" /></p>
<p>This query will yield results like what we see in the image to the right.</p>
<p>Similarly, I can run a query that would be contained within a CTE and take advantage of the ROW_Number() function to help find where I may have dups.</p><pre class="urvanov-syntax-highlighter-plain-tag">with dedupe as (
	Select DemoID, SomeInt
		,ROW_NUMBER() over (partition by DemoID,SomeInt order by Someint) as Rownum
		From DupeDemo
		)
Select * From dedupe
	Where Rownum &gt; 1
		Order By DemoID,SomeInt</pre><p>Now that we know for certain that we have a large amount of dupes, lets finally work on eliminating them.  We can use a query just like the last one and alter it a bit to make it work so we can delete the dups.  Under normal circumstances, I would make absolutely certain that the tables to be affected by these deletes were backed up.  You can accomplish that by either copying the data in the table into a new table or you can run a database backup.</p><pre class="urvanov-syntax-highlighter-plain-tag">with dedupe as (
	Select DemoID, SomeInt
		,ROW_NUMBER() over (partition by DemoID,SomeInt order by Someint) as Rownum
		From DupeDemo
		)
Delete dedupe
	Where Rownum &gt; 1</pre><p>Really easy script.  This will delete all source table records that are dupes.  You can validate that by rerunning either of the first two queries used to demonstrate that duplicate data existed.  This is illustrated in the following image.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/03/Deduped1.jpg"><img loading="lazy" class="alignnone size-full wp-image-1085" title="Deduped1" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/Deduped1.jpg" alt="" width="191" height="362" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/Deduped1.jpg 191w, https://jasonbrimhall.info/wp-content/uploads/2011/03/Deduped1-158x300.jpg 158w" sizes="(max-width: 191px) 85vw, 191px" /></a></p>
<p>Since SQL 2005, removing bad duplicate data has become substantially easier.  This example should help to demonstrate that as well as provide a method to create a repeatable test while learning the technique.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1082" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/21/dedupe-data-cte/">Dedupe Data CTE</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/21/dedupe-data-cte/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Server Standard Reports Winforms</title>
		<link>https://jasonbrimhall.info/2011/03/16/sql-server-standard-reports-winforms/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-standard-reports-winforms</link>
					<comments>https://jasonbrimhall.info/2011/03/16/sql-server-standard-reports-winforms/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 16 Mar 2011 14:30:55 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[SQL Maintenance]]></category>
		<category><![CDATA[SSMS Reports]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1075</guid>

					<description><![CDATA[<p>In SQL Server, there is a good set of preloaded reports to help you monitor the Instance.  These reports can be found under the Standard Reports and can be reached via context menu.  To find [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/03/16/sql-server-standard-reports-winforms/">SQL Server Standard Reports Winforms</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" class="alignright size-full wp-image-1076" title="ssms_standardreports" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/ssms_standardreports.jpg" alt="" width="694" height="476" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/03/ssms_standardreports.jpg 694w, https://jasonbrimhall.info/wp-content/uploads/2011/03/ssms_standardreports-300x205.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></p>
<p>In SQL Server, there is a good set of preloaded reports to help you monitor the Instance.  These reports can be found under the Standard Reports and can be reached via context menu.  To find them, right click your Instance in Object Explorer from within SSMS.  Then navigate the context menu &#8211; much like the menus shown here.</p>
<p>You can see from the image that there is a decent amount of good reports available to choose.</p>
<p>When you run one of these reports, it is like a report that you would run from SSRS.  However, SSRS is not required to be installed in order to run these reports.</p>
<p>Occasionally, you may encounter an error when trying to run these reports.  The error that you may encounter is as follows:</p>
<blockquote><p>The file &#8216;Microsoft.ReportViewer.WinForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&#8217; cannot be opened.</p></blockquote>
<p>This error message seems to pop up commonly after an upgrade to SQL Server is performed (CU or SP).  Sometimes, it can crop up without an upgrade having been recently performed.</p>
<p>In the event that you encounter this particular error, you should try installing BIDS.  Though it is not necessarily a pre-requisite &#8211; it is a good idea to have it installed anyway and it also resolves this error message.</p>
<p>Another method that has worked for me to resolve this error is to install <a href="http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&amp;FamilyID=bb196d5d-76c2-4a0e-9458-267d22b6aac6">Microsoft Report Viewer 2008 SP1</a>.</p>
<p>Additionally, besides looking into these Standard reports and hopefully helping you circumvent the aforementioned error, there is another recommendation.  In SQL 2005, there is a download for the Performance Dashboard Reports.  And in SQL 2008 there is a new feature called Management Data Warehouse.</p>
<p>You can download the Performance Reports from <a href="http://www.microsoft.com/downloads/en/details.aspx?familyid=1d3a4a0d-7e0c-4730-8204-e419218c1efc&amp;displaylang=en">here</a>.</p>
<p>You can see how to configure the Management Data Warehouse <a href="http://msdn.microsoft.com/en-us/library/dd939169(v=sql.100).aspx">here</a>.</p>
<p>Oh, and if you want to retrofit SQL 2008 with the 2005 Performance Dashboard, you will have to tweak it a bit.  You can read up on that <a href="http://blogs.technet.com/b/rob/archive/2009/02/18/performance-dashboard-reports-for-sql-server-2008.aspx">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1075" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/16/sql-server-standard-reports-winforms/">SQL Server Standard Reports Winforms</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/16/sql-server-standard-reports-winforms/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #016: Aggregates and Statistics</title>
		<link>https://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-016-aggregates-and-statistics</link>
					<comments>https://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Mar 2011 18:49:10 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1059</guid>

					<description><![CDATA[<p>For my data analysis and trending, I wanted to find a simple distribution across quartiles.</p>
The post <a href="https://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/">T-SQL Tuesday #016: Aggregates and Statistics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Data Size Collection and Analysis</h2>
<p><a href="http://blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/come-one-come-all-to"><img loading="lazy" class="alignleft size-full wp-image-1060" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2011/03/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>By now you should be well acquainted with this phenomenon we call TSQL Tuesday.  This party is being hosted this month by Jes Schultz Borland (<a href="http://twitter.com/#!/grrl_geek" target="_blank" rel="noopener">Twitter </a>| <a href="http://blogs.lessthandot.com/author/jes-borland" target="_blank" rel="noopener" class="broken_link">Blog</a>).  She has challenged us to write something about aggregations and aggregation functions in SQL Server.</p>
<p>I stewed on this topic for a while trying to figure out something that would be relevant yet a little unique.  I think that is the real challenge &#8211; finding some application of the topic that may be somewhat unique or at least informative for somebody.</p>
<p>It dawned on me finally that I already have a topic in queue waiting to be written.  It was supposed to be a follow-up to my entry for last month.  (You can read that entry <a href="http://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/">here</a>.)  I concluded that entry with an admission that I hurried through the article to get it done in time.  Well, I was hoping to find the time to write the rest of my process &#8211; but now it fits quite well with this months theme.</p>
<h3>Recap</h3>
<p>Quickly, let&#8217;s recap what I did in that post and then I will proceed from there to tie this month to last month (as far as TSQL Tuesday goes).</p>
<p>In last months entry, I shared a script (an ugly one) that I created to cycle through all of the tables and columns of a database to get me some relevant data concerning the size of the data in my tables.  Well, actually I took a 2% sample of that information so I could run further statistical analysis.  The end goal was to have relevant data from an existing system and the R&amp;D databases to create appropriate data sizes in the new database prior to releasing it to production.  With all of that data aggregated into a staging table, I was ready to being the next phase.</p>
<p>One thing I did not mention in that prior article was the creation of another table for this aggregation process.  I didn&#8217;t mention it because it used much the same process (though considerably faster because it didn&#8217;t do the same thing).   This table had a prime objective of collecting the max length of each column of each table of each database.  The structure is simple:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE [dbo].[DataAnalysis](
	[DatabaseName] [sysname] NOT NULL,
	[TableName] [sysname] NOT NULL,
	[ColumnName] [sysname] NOT NULL,
	[MaxLength] [int] NULL,
	[ColDataType] [varchar](20) NULL,
	[MaxColLength] [int] NULL
) ON [PRIMARY]</pre><p>I mention this table now because I will be using it in my final aggregation.</p>
<h3>Statistics and Aggregation</h3>
<p>For my data analysis and trending, I wanted to find a simple distribution across quartiles.  A quartile is: One of the three numbers (values) that divide a range of data into four equal parts.  A quartile is used in statistical analysis and is commonly a part of a box plot.  Other statistical values that work well with the quartile include the MAX value.  Since I had usable data to be able to produce my quartile ranges, I used the following query to further aggregate and even used a function that provides the quartile.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT DLA.DatabaseName,DLA.TableName,DLA.ColumnName, DA.ColDataType
	,DLA.ColLens,count(DLA.ColLens) as NumOccurence
	,case when DA.MaxColLength = -1 then 2000000 else DA.MaxColLength end as MaxSupportedLen
	,DA.MaxLength as MaxDataLen
    ,NTILE(4) OVER (partition by DLA.DatabaseName,DLA.TableName,DLA.ColumnName ORDER BY DLA.ColLens) AS 'Quartile'
Into DataStats
FROM DataLenStats_Alt DLA
	Left Outer Join DataAnalysis DA
		On DLA.DatabaseName = DA.DatabaseName
		And DLA.TableName = DA.TableName
		And DLA.ColumnName = DA.ColumnName
	Group By DLA.DatabaseName,DLA.TableName,DLA.ColumnName,DLA.ColLens,DA.MaxColLength,DA.MaxLength, DA.ColDataType
	Order By DLA.DatabaseName,DLA.TableName,DLA.ColumnName,DLA.ColLens</pre><p>From this script, you can see that I am taking data from the first two staging tables and dumping it into a third table.  With this query I am taking advantage of the NTILE() function that is available in SQL Server (2005 and up).  And since my data that has been accumulated is for more than one table, more than one database, and more than one column &#8211; I needed to partition that function based on those attributes.</p>
<p>With this data now available, I could see the trend of the data for any data field that may have been collected.  For instance, if I wanted to figure out the proper size (based on current data) of the phone number in my new database, I could now query the DataStats table like this:</p><pre class="urvanov-syntax-highlighter-plain-tag">select * from DataStats DS
	 where DS.ColumnName like '%phone'</pre><p>I would then be able to determine where that field exists and the distribution of data across the quartiles and in comparison to the max data size for that field.  This helps to more intelligently assign a data size to fields based on existing data.  I could quickly ascertain that most of the data is within the second quartile (for instance) and that I have few outliers in the third and fourth quartiles and maybe an extreme case where the max is way out of scope in comparison.  At this point I could make an educated judgement call as to an appropriate size based on distribution, outliers and risk.</p>
<h3>Conclusion</h3>
<p>This exercise was a particularly challenging one.  It was challenging due to the desire to create quartiles for analysis.  I had wanted to break it down into Standard Deviations for further analysis (and still may).  This is highly useful when in the R&amp;D or development phase.  I wouldn&#8217;t run the query from the first post on a production system because it is a long running process and can be resource intensive (I need to optimize it more).  This kind of script can really help to get better acquainted with the data as well.  I learned a lot by doing this and am looking forward to how I can improve upon it.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1059" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/">T-SQL Tuesday #016: Aggregates and Statistics</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/03/08/t-sql-tuesday-016-aggregates-and-statistics/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQLServerPedia Blogger Awards</title>
		<link>https://jasonbrimhall.info/2011/02/16/sqlserverpedia-blogger-awards/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlserverpedia-blogger-awards</link>
					<comments>https://jasonbrimhall.info/2011/02/16/sqlserverpedia-blogger-awards/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 17 Feb 2011 05:00:38 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1026</guid>

					<description><![CDATA[<p>Several moons ago I learned that I had won one of the categories for the 2010 SQLServerpedia Blogger Awards.  You can read about that here.  Of all of the promises made in that post, I [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/02/16/sqlserverpedia-blogger-awards/">SQLServerPedia Blogger Awards</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/02/sqlserpedia_2010_bloggeraward.jpg"><img loading="lazy" class="alignleft size-medium wp-image-1027" title="SAMSUNG" src="http://jasonbrimhall.info/wp-content/uploads/2011/02/sqlserpedia_2010_bloggeraward-300x225.jpg" alt="" width="300" height="225" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/02/sqlserpedia_2010_bloggeraward-300x225.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2011/02/sqlserpedia_2010_bloggeraward-1024x768.jpg 1024w" sizes="(max-width: 300px) 85vw, 300px" /></a>Several moons ago I learned that I had won one of the categories for the 2010 SQLServerpedia Blogger Awards.  You can read about that <a href="http://jasonbrimhall.info/2010/11/09/blogger-awards/">here</a>.  Of all of the promises made in that post, I have yet to fulfill two of them (one is being fulfilled now).  I can&#8217;t fulfill the other promise because I do not have a cubicle at work &#8211; just an open work area.  That said, I am prominently displaying my trophy in my work area.</p>
<p>As you can see in the image, I have displayed my trophy (though the photo does not prove that it is at work).</p>
<p>Again, I am thankful to have won and I will continue to blog and try to put out useful information to the blogosphere.</p>
<p>Thanks to all who voted for my entry (which was really just one part of a series).</p>
<p>P.S.  I have a really good reason for this post coming out so late too.  My award was delivered in the middle of me moving from Vegas back to Utah.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1026" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/02/16/sqlserverpedia-blogger-awards/">SQLServerPedia Blogger Awards</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/02/16/sqlserverpedia-blogger-awards/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Feb 2011 S3OLV Meeting</title>
		<link>https://jasonbrimhall.info/2011/02/09/feb-2011-s3olv-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=feb-2011-s3olv-meeting</link>
					<comments>https://jasonbrimhall.info/2011/02/09/feb-2011-s3olv-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 09 Feb 2011 22:53:55 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1020</guid>

					<description><![CDATA[<p>I am getting this out extremely late.  I seriously have good excuses for that.  Due to my location and Charley feeling ill, we will be doing the S3OLV UG meeting entirely virtual this month. Here [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/02/09/feb-2011-s3olv-meeting/">Feb 2011 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I am getting this out extremely late.  I seriously have good excuses for that.  Due to my location and Charley feeling ill, we will be doing the S3OLV UG meeting entirely virtual this month.</p>
<p>Here is the note on the invite:</p>
<p>Please join us this month for a Virtual UG meeting.  We will not be meeting at The Learning Center.</p>
<p><strong><span style="text-decoration: underline;">Livemeeting Details:</span></strong></p>
<p>Follow these steps:</p>
<ol>
<li>Copy this address and paste it into your web browser: https://www.livemeeting.com/cc/UserGroups/join</li>
<li>Copy and paste the required information: Meeting ID: <strong>89TDFP</strong></li>
</ol>
<p>Randy Knight of SQLSolutions Group will be presenting.  He has some insight to help both the Oracle and SQL DBA.</p>
<p>Randy Knight (MCITP) is an IT Professional who has been working with Microsoft technology for over 20 years, focusing on SQL Server for the last 14. He has worked in a variety of settings, including six years as a Database Architect for Match.com, one of the largest and most successful dot coms.</p>
<p>We welcome anybody who is able, to attend this virtual meeting.</p>
<h2>The meeting will be held February 10, 2011 at 6:30 PST.</h2>
<p>I mentioned that Randy will be teaching us some useful info for both SQL and Oracle DBAs.  Here is the abstract for the presentation he will be giving.</p>
<blockquote><p>In today&#8217;s enterprise environments, it is becoming increasingly necessary to integrate data from a variety of sources. As SQL Server continues its march into the enterprise, the days of focusing 100% on one platform are over. At a bare minimum, we need to be able to communicate with DBA&#8217;s for other platforms. Terminology as simple as Instance and Database mean very different things in Oracle than they do in SQL Server. In this session, we will compare and contrast the two platforms in terms of features and terminology. We will also discuss some of the best practices and pitfalls when integrating the two.</p></blockquote>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1020" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/02/09/feb-2011-s3olv-meeting/">Feb 2011 S3OLV Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/02/09/feb-2011-s3olv-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #15 DBA Automaton</title>
		<link>https://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-15-dba-automaton</link>
					<comments>https://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 09 Feb 2011 00:14:28 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Scripts]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=1012</guid>

					<description><![CDATA[<p>Often, we hear about DBA's automating everything under the sun.  Why?  It simplifies the job and creates time to work on other projects.</p>
The post <a href="https://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/">T-SQL Tuesday #15 DBA Automaton</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://sqlasylum.wordpress.com/2011/02/01/invitation-to-t-sql-tuesday-15-automation-in-sql-server/"><img loading="lazy" class="size-full wp-image-1013 alignright" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2011/02/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>I have been incognito for the last couple of weeks and nearly missed TSQL Tuesday this month.  If it weren&#8217;t for somebody pinging me requesting the link to the list of upcoming hosts, I would have missed it entirely.  The topic merges well with the work I have been doing for the past few weeks.  In fact, there are so many things that DBA&#8217;s do on a regular basis to automate things &#8211; there should be plenty of items to cherry pick for a topic.  Unfortunately, that doesn&#8217;t make this topic any easier for me.  My decision process for this is partially based on thinking through what might be unique without having read what others may have written.  (While thinking about reading blogs, it would be nice if there was an automated method to ingest all of the blogs into my head without having to iterate through them one at a time &#8211; manually.)</p>
<p>This month the party is hosted by Pat Wright (<a href="http://sqlasylum.wordpress.com/" target="_blank" rel="noopener">blog</a> | <a href="http://twitter.com/sqlasylum" target="_blank" rel="noopener">twitter</a>).  Pat has asked us to describe some of the things we automate &#8211; or some of our automation that we have implemented.  Often, we hear about DBA&#8217;s automating everything under the sun.  Why?  It simplifies the job and creates time to work on other projects.  With all of the automation, I wonder if DBA&#8217;s are related to Hephaestus in any fashion.  If we had our way, it seems that our databases would be&#8230;<a href="http://en.wikipedia.org/wiki/Automaton">Automatons</a>.</p>
<h3>A Lesser Automation</h3>
<p>Now that I have rambled for a good bit, I guess it is time to get to the meat of the topic.  First, we need to understand automation.  So, what is automation?</p>
<ol>
<li>The automatic operation or control of equipment, a process, or a system.</li>
<li>The techniques and equipment used to achieve automatic operation or control.</li>
</ol>
<p>A closely related word to automation is:</p>
<ol>
<li>Computerization &#8211; the control of processes by computer</li>
</ol>
<p>In other words, for a DBA, automation is the implementation of a process or control for the computer to operate without the DBA doing the work.  This is typically something that is repetitive or menial or tedious or frequently done.  But that is not always the case.  This can also be something that is fun and/or only done once or twice a year.</p>
<p>I have one of those cases where I may use the automation even less often than once a year, or maybe it could come about more frequently.  It all depends on the needs of designing and testing new databases.</p>
<p>This process is to help in properly sizing the database before the database is finally released to production.  With good project requirements, you may have a good idea of what the fields and sizes of those fields should be.  In some cases, you will be getting data from an external source in some fashion or another.  This data does not always come with storage requirements or data size parameters.  You can make guesses at it by looking at the data &#8211; but sometimes, something more is required.</p>
<p>It is when more is required that this script comes in a bit handy for me.  The script is ugly, but it does the deed.  The base idea is to retrieve the data length for a sample of data from each of the tables (after import into a staging database).  This is done so I can run statistical analysis on the data later.  And cringe now because I use a nested cursor to get at what I want.</p>
<p>So Here is the script that will load a sample of data from every table in every database for every column and give you the length of the pertinent columns (I have excluded obvious columns such as numeric types and certain LOB types).</p><pre class="urvanov-syntax-highlighter-plain-tag">If exists (select name from sys.objects where name = 'DataLenStats_Alt')
Begin
	Drop table DataLenStats_Alt
End

CREATE TABLE DataLenStats_Alt (DatabaseName sysname,TableName SYSNAME, ColumnName SYSNAME, ColLens INT)

Declare dbfetch cursor static for
Select name
	From sys.databases
	Where database_id &amp;gt; 4
		And Name &amp;lt;&amp;gt; 'Admin'
	Order By Name

OPEN dbfetch;
declare @sql1 varchar(max), @dbname varchar(128)

FETCH NEXT FROM dbfetch 
INTO @dbname;

WHILE @@FETCH_STATUS = 0
BEGIN

	Set @sql1 = '
	Use ' + @dbname +';
	DECLARE datalens_cursor CURSOR Static FOR 
	SELECT Distinct IST.TABLE_NAME,IST.Column_Name
	FROM Information_schema.Columns IST
		Inner Join sys.dm_db_partition_stats AS st
			On object_id(IST.TABLE_NAME) = st.object_id
	WHERE ObjectProperty(object_id(Table_Name),''Ismsshipped'') = 0
		And Table_Name not like ''sysdi%''
		And DATA_TYPE not in (''XML'',''uniqueidentifier'',''image'') 
		And isnull(numeric_precision,0)=0
	Group By Table_Name,Column_name
	Having Sum(st.row_count) &amp;gt; 0
	ORDER BY Table_name;

	OPEN datalens_cursor;
	declare @sql varchar(max), @table sysname, @column sysname

	FETCH NEXT FROM datalens_cursor 
		INTO @table,@column;

	WHILE @@FETCH_STATUS = 0
	BEGIN
	Set @sql=''''

		select @sql=@sql+''select top 2 Percent db_name(),''''''+@table+'''''',''''''+@column+'''''', len(isnull(convert(varchar(max),''+@column+''),''+''0''+'')) from [''+@table+''] '' 
							From information_schema.columns 
								Where table_name=''''+@table+''''
									And column_name = ''''+@column+''''

		Begin Tran
			--print @sql
			Insert Into Admin.dbo.DataLenStats_Alt
			exec(@sql)
		Commit Tran
	FETCH NEXT FROM datalens_cursor 
		INTO @table, @column;
	END

	CLOSE datalens_cursor
	DEALLOCATE datalens_cursor
	--Checkpoint
	Use Tempdb;
	Checkpoint
	'
exec (@sql1)
FETCH NEXT FROM dbfetch INTO @dbname;
print @sql1
END

CLOSE dbfetch
DEALLOCATE dbfetch</pre><p>And yeah, I rushed through this to get it finished up quickly.  I hope to have more time to delve into it later.  At least with this script, I can load a table with adequate data to be able to generate histograms on the data length/size distribution and then make appropriate sizing decisions based on the statistics.  Be warned &#8211; though automated it is slow and should not be run on a production server.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=1012" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/">T-SQL Tuesday #15 DBA Automaton</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/02/08/t-sql-tuesday-15-dba-automaton/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Confessions 02 SSRS Encryption</title>
		<link>https://jasonbrimhall.info/2011/01/25/sql-confessions-02-ssrs-encryption/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-confessions-02-ssrs-encryption</link>
					<comments>https://jasonbrimhall.info/2011/01/25/sql-confessions-02-ssrs-encryption/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 25 Jan 2011 22:46:37 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SQL Confessions]]></category>
		<category><![CDATA[SSRS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=995</guid>

					<description><![CDATA[<p>In December 2010, I started a little series called SQL Confessions.  The idea of this series is as a learning exercise when I come across something that I either did wrong or couldn&#8217;t find a [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/01/25/sql-confessions-02-ssrs-encryption/">SQL Confessions 02 SSRS Encryption</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In December 2010, I started a little series called SQL Confessions.  The idea of this series is as a learning exercise when I come across something that I either did wrong or couldn&#8217;t find a better way of doing it at the time.  In that <a href="http://jasonbrimhall.info/2010/12/13/sql-confessions/">first episode</a>, I admitted to the use of a cursor (drat).  I should go back and update that posting because I got a recommendation of an alternative way to do that.  As of yet, I haven&#8217;t tested and it was a one time run (phwew).</p>
<p>This time around, the consequences were a bit bigger.  This time it was a failure and it is related to SSRS.  I came away from the experience with a few options that I want to test and see which method will work best in the event the same thing happens.</p>
<p>In this case, the ReportServer databases were backed up and the backups were good (I used them to restore a secondary database).  We even had SSRS installed on the failover server.  From that one can deduce that a recent failover was required for SSRS &#8211; and this was not a test.  Well, if you have the database backed up and a standby server ready to go &#8211; what is missing?</p>
<p>What was missing was the encryption key backup.  Life in recovery is a lot easier if that backup key exists.  I could not find it.  This did not prevent me from being able to recover SSRS though &#8211; it just meant a little more work.</p>
<p>If you lose your encryption key, then you have an issue with any data that may be encrypted.  Some of the things that are encrypted in SSRS 2008 are:  Connections and Subscriptions.</p>
<p>When you lose the encryption key you lose those items too.  If you have good documentation you can most likely recover them.  In my case I was able to recreate the Connections (DSNs) and bring the reports back up.  I don&#8217;t want to reveal the process I used just yet because I do want to test this a bunch more and find the better method to use.</p>
<p>As for the recommended method, here are some articles for reference:</p>
<p>1. <a href="https://web.archive.org/web/20160312040136/http://sqlwebpedia.com/content/how-move-reporting-services-new-server">Move to a new Server SSRS 2005</a> (useful even for 2008).</p>
<p>2.  MSDN &#8211; <a href="http://msdn.microsoft.com/en-us/library/ms400729(v=vs.80).aspx">Backup the Encryption Key</a></p>
<p>I hope you find this useful, and the followup should be useful.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=995" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/01/25/sql-confessions-02-ssrs-encryption/">SQL Confessions 02 SSRS Encryption</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/01/25/sql-confessions-02-ssrs-encryption/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>January &#8217;11 Meeting Reminder</title>
		<link>https://jasonbrimhall.info/2011/01/12/january-11-meeting-reminder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=january-11-meeting-reminder</link>
					<comments>https://jasonbrimhall.info/2011/01/12/january-11-meeting-reminder/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 13 Jan 2011 04:50:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=983</guid>

					<description><![CDATA[<p>If you saw my blog post the other day, you know that S3OLV has a meeting this Thursday (Jan 13, 2010) at 6:30 PM PST.  If not, then you can read that post from here, [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2011/01/12/january-11-meeting-reminder/">January ’11 Meeting Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>If you saw my blog post the other day, you know that S3OLV has a meeting this Thursday (Jan 13, 2010) at 6:30 PM PST.  If not, then you can read that post from <a href="http://jasonbrimhall.info/2011/01/10/january-2011-s3olv/">here</a>, and then read the rest of this post.</p>
<p>Over the past few months we at S3OLV have been having a tremendous amount of problems with our meetings.  Some of those problems have to deal with the technology.  Some of the problems have to deal with low attendance.  Well, this post is mostly an update on both of those fronts.</p>
<p>As of this evening, we have ~20 people committed to attending this meeting.  That is the highest number I have seen in the last year.  I am real excited to have this many people show up.  We have had decent numbers show up when only 7 or 8 people commit.  If we have people attend that did not commit &#8211; that is awesome.  This month I sent out a few reminders of the upcoming event.  That seems to have helped.</p>
<p>On the technology front, I went through a dry-run of the livemeeting with our Presenter Wayne Sheffield.  We made sure audio, bandwidth, and video all worked.  Wayne also spotted a few things he wants to improve between now and tomorrow.  Prior to the meeting we will do another &#8220;mic&#8221; check to confirm again that all is well.</p>
<p>A third problem was the meeting location locking us out last month.  Oh that was extremely perturbing.  The center has apologized and has confirmed that the space will be available and open tomorrow.  We&#8217;ll see on that one if they follow through &#8211; but at least they apologized.</p>
<p>I will be signing on at about 6PM PST (7 MST and 9 EST) to do the &#8220;mic&#8221; check and get the meeting rolling from Utah (hence the MST).  Even from remote, I plan on helping in any way I can with the Las Vegas UG.  For instance, some of the things I can do from remote would be to continue to line up speakers, do presentations, get the newsletter effort rolling, site transition to blog, and move our mailing list to a database on SQL Server that we can manage (less dependency on outside sources).</p>
<p>We are looking for comments and recommendations.  Furthermore we are looking for talented people to help in these efforts.  One area we could really use some help is with the MARKETING.  If you know what you are doing and how we could better advertise our SQL Group to the area &#8211; then please drop us a line.</p>
<p>I hope to see many of you online on January 13th at 6:30 PST (UTC -8).  This meeting will be good!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=983" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/01/12/january-11-meeting-reminder/">January ’11 Meeting Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/01/12/january-11-meeting-reminder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Tuesday 14: Committed</title>
		<link>https://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-tuesday-14-committed</link>
					<comments>https://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 Jan 2011 16:46:45 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Goals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=977</guid>

					<description><![CDATA[<p>For this TSQL Tuesday post, I will just add a short list of my professional goals for this next year.  Otherwise, this post would be mostly about my non-professional goals.</p>
The post <a href="https://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/">TSQL Tuesday 14: Committed</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Woohoo, It&#8217;s TSQL Tuuuuuuuuuuuuuuuuuuesday!!!<a href="http://www.midnightdba.com/Jen/2011/01/tsql-tuesday-014/"><img loading="lazy" class="alignright size-full wp-image-978" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2011/01/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a> This month we are being hosted by one-half of the MidnightDBA &#8211; Jen McCown (<a href="http://www.midnightdba.com/Jen/">Blog </a>| <a href="http://twitter.com/midnightdba">Twitter</a>), and she has asked us to speak on resolutions.</p>
<p>If we look in the dictionary we will find that resolution is closely related to several other words such as resolve and commit.  One form of resolution is the formal act of declaring your personal resolve or personal commitments.  For me, maybe it is just the act of having been committed.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2011/01/straightjack.jpg"><img loading="lazy" class="alignleft size-full wp-image-979" title="straightjack" src="http://jasonbrimhall.info/wp-content/uploads/2011/01/straightjack.jpg" alt="" width="200" height="200" srcset="https://jasonbrimhall.info/wp-content/uploads/2011/01/straightjack.jpg 200w, https://jasonbrimhall.info/wp-content/uploads/2011/01/straightjack-150x150.jpg 150w" sizes="(max-width: 200px) 85vw, 200px" /></a>More seriously &#8211; a resolution is just a fancy way of saying that you are making a personal commitment or personal goal.  As with all goals, you should track it.  Otherwise it&#8217;s not really a goal, nor is it really a strong commitment.</p>
<h2>My Commitments</h2>
<p>For this TSQL Tuesday post, I will just add a short list of my professional goals for this next year.  Otherwise, this post would be mostly about my non-professional goals.</p>
<p>This goals are nothing earth shattering.  But at least they are goals to keep me going, even with all of the other stuff still going on.</p>
<ol>
<li><strong><span style="text-decoration: underline;">Certification</span></strong> &#8211; I will complete my MCITP certification this year.  I wanted to do it last year, but never really focused on it or gave myself a firm deadline.</li>
<li><strong><span style="text-decoration: underline;">Build out a Virtual Environment</span></strong> &#8211; this involves setting some VMs for Oracle, MySQL, FireBird, and SQL Server.  I may add other RDBMS&#8217; to that list.  I want to use this environment to learn how to interface between them using SSIS.</li>
<li><strong><span style="text-decoration: underline;">Public Speaking</span></strong> &#8211; Through brown bags, SQLSaturdays and User Groups &#8211; I want to speak more often.  I hope to do 2 SQLSaturdays (we&#8217;ll see how that pans out), 2 UG presentations, and then quarterly brown bags.</li>
<li><strong><span style="text-decoration: underline;">Writing</span></strong> &#8211; I have two more articles in queue that I need to write and I want to write two beyond that for a total of four this year.  I also need to write more technical blog entries.  This has been extremely beneficial to me.  Writing in an effort to share knowledge has helped me learn the subject better.</li>
</ol>
<p>Again, that is just a short list of goals, but it should keep me busy in addition to how busy I will be with my other goals, with life, and with family.</p>
<p>As I pondered these goals a bit more, I am somewhat stoked about them.  These goals will help with other goals.  These goals will help me to learn quite a bit &#8211; even though they may seem a bit generic.  I put a fair amount of thought into these and know I can achieve them, but also know that I have stepped them up a tad from last year.  I am looking forward to meeting some of you at SQL Saturdays as well as I am stoked about my Virtual Environment.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=977" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/">TSQL Tuesday 14: Committed</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2011/01/11/tsql-tuesday-14-committed/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>SSIS Multiple File Export</title>
		<link>https://jasonbrimhall.info/2010/12/28/ssis-multiple-file-export/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssis-multiple-file-export</link>
					<comments>https://jasonbrimhall.info/2010/12/28/ssis-multiple-file-export/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 28 Dec 2010 19:49:51 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=928</guid>

					<description><![CDATA[<p>Have you ever needed to export different data sets to different flat files?  Each of these data sets could be customer information for different clients &#8211; but they all require the same fields.  I have [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/28/ssis-multiple-file-export/">SSIS Multiple File Export</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Have you ever needed to export different data sets to different flat files?  Each of these data sets could be customer information for different clients &#8211; but they all require the same fields.  I have run into this requirement a few times and have found that it is not as hard as it may sound.  To evolve that requirement, I have also had the requirement to export multiple different files for each of the clients.  For the sake of this post though, I will just stick to how to do the first level.  (It is only a little more complex but not much different to add the extra requirement.)</p>
<h3>SSIS to Save the Day</h3>
<p>SSIS has a looping mechanism built in to help achieve this.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachloop_container.jpg"><img loading="lazy" class="alignnone size-full wp-image-929" title="foreachloop_container" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachloop_container.jpg" alt="" width="191" height="107" /></a></p>
<p>If you want to learn more about this particular data flow object, here is the <a href="http://msdn.microsoft.com/en-us/library/ms141724.aspx">MSDN resource</a> on it.</p>
<p>When trying to create an SSIS package solution that meets our requirements, the first step (in my opinion) is to make sure you have an Object variable created for use by the Foreach Loop Container.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/objvar.jpg"><img loading="lazy" class="alignnone size-full wp-image-931" title="objvar" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/objvar.jpg" alt="" width="365" height="19" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/12/objvar.jpg 365w, https://jasonbrimhall.info/wp-content/uploads/2010/12/objvar-300x15.jpg 300w" sizes="(max-width: 365px) 85vw, 365px" /></a></p>
<p>To use this variable in the foreach loop container, we first need to load data into it.  This is accomplished by using an Execute SQL Task.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/executesql.jpg"><img loading="lazy" class="alignnone size-full wp-image-932" title="executesql" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/executesql.jpg" alt="" width="201" height="102" /></a></p>
<p>Note:  There is a red-x in this image simply because I have not defined any properties for this object.</p>
<p>The Execute SQL Task needs to be given a data source and a SQL command to run.  The result set of this task should be set to full result-set on the general page.  On the result-set page, set the result-set to be stored in the object variable that we created already.  On the same page, you should set the result name to a value of &#8220;0&#8221; (zero without the quotes).</p>
<p>Now we can start looking more at the Foreach Loop Container.  When we open the properties of the Foreach Loop Container, we want to go to the Collection page and adjust two settings.  The first is to select the appropriate type from the dropdown.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado.jpg"><img loading="lazy" class="alignnone size-full wp-image-933" title="foreachado" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado.jpg" alt="" width="579" height="554" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado.jpg 579w, https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado-300x287.jpg 300w" sizes="(max-width: 579px) 85vw, 579px" /></a></p>
<p>In this case, we will select ForEach ADO Enumerator.  The next change to be made is the next drop down labeled &#8220;ADO Object source variable:&#8221;.  In this box we will select the object variable that we already created.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_object.jpg"><img loading="lazy" class="alignnone size-full wp-image-934" title="foreachado_object" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_object.jpg" alt="" width="582" height="556" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_object.jpg 582w, https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_object-300x286.jpg 300w" sizes="(max-width: 582px) 85vw, 582px" /></a></p>
<p>Now we need to configure the Variable Mappings page.  For this you can either create a new variable from this page, or use variables you have already defined.  Let&#8217;s Create some variables from here.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_addvar.jpg"><img loading="lazy" class="alignnone size-full wp-image-935" title="foreachado_addvar" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_addvar.jpg" alt="" width="383" height="341" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_addvar.jpg 383w, https://jasonbrimhall.info/wp-content/uploads/2010/12/foreachado_addvar-300x267.jpg 300w" sizes="(max-width: 383px) 85vw, 383px" /></a></p>
<p>Once that is established we can work on configuring the Data Flow task.  For the sake of the example, we can do something simple.  It is a good idea to make sure you have your connection managers created by this point.  If they aren&#8217;t there &#8211; then let&#8217;s create some.  First, let&#8217;s create an OLEDB connection.  Second, we need to create a Flat File Connection Manager.  I won&#8217;t cover how to create those connection objects.  I will cover how to make a configuration change to the Flat File Connection Manager though.  To make sure the files will be written differently &#8211; we should use an expression on this connection manager.</p>
<p>In your flat file connection manager, you will need to look at the properties tab in order to create an expression.  In the Property Expressions Builder, select the ConnectionString Property from the drop down.  In the expression side build something like this:</p>
<p>[codesyntax lang=&#8221;sql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">&quot;D:\SomeDirectory\&quot;+User::TestSub+&quot;.txt&quot;</pre><p>[/codesyntax]</p>
<p>Now back to that Data Flow task I mentioned already.  In your Data Flow Task, select the appropriate OLEDB Connection manager that you have created.  Then select SQL Command in the data access mode dropdown menu.  In the SQL Command text box, type an appropriate query to retrieve your data.</p>
<p>Example:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT
    InvDate
   ,CustFullName
   ,BillingAddress
   ,Amt
FROM [Orders]
 Where Company=?</pre><p>[/codesyntax]</p>
<p>Then click on the Parameters button.  From here, you will assign the appropriate variable to the Parameter that was created in the query.  In our example, we should use the variable [ User::TestSub ].</p>
<p>That pretty much covers it.  In a follow-up I will go through an actual setup that I have created.  More screenshots, and slightly different setup than this baseline.  Hope you enjoy.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=928" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/28/ssis-multiple-file-export/">SSIS Multiple File Export</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/28/ssis-multiple-file-export/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Powershell, Me and the MCM part II</title>
		<link>https://jasonbrimhall.info/2010/12/20/powershell-me-and-the-mcm-part-ii/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=powershell-me-and-the-mcm-part-ii</link>
					<comments>https://jasonbrimhall.info/2010/12/20/powershell-me-and-the-mcm-part-ii/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 20 Dec 2010 17:54:10 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[MCM]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=924</guid>

					<description><![CDATA[<p>Last week I posted the first part of this series.  I thought it would be a good idea to give a little follow-up on how my foray into Powershell as I attempted to download this [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/20/powershell-me-and-the-mcm-part-ii/">Powershell, Me and the MCM part II</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Last week I posted the <a href="http://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/">first part</a> of this series.  I thought it would be a good idea to give a little follow-up on how my foray into Powershell as I attempted to download this videos.</p>
<p>Attempt 1:  Failed miserably.  I did not have enough disk space and thus only downloaded about half of the videos.  I tried to remedy this by changing the path to a different volume but that threw out some error messages.  The script works best when continuing to use the $env variable in the path for the location to dump the files.</p>
<p>Attempt 2:  From a different machine this was working beautifully until I noticed that every once in a while a file would error out and the download would resume with the next video in the list.  When I attempted to look up those particular videos, they were all present.  So I restarted thinking it was a local environment problem.</p>
<p>Attempt 3:  I figured out that attempt 2 was failing because my laptop was going to standby &#8211; duh!!!  I disabled the standby and finally got the download to work from start to finish without fail.</p>
<p>Now, I can place these videos on my Android and watch/listen from anywhere I have my phone.  Since I have an auxiliary port in my car, I can just plug the phone in, let it charge, and listen to the videos while I commute &#8211; through the car speakers.  It is nice to have such a high-level of training material available for a quick refresher or for that first time through.  I recommend people get on board and take advantage of what Microsoft, Paul Randal, and others have given to the community through this training.  Since I pay out of pocket for my training &#8211; this is the right price for me.</p>
<p>Thanks for the Christmas Gift.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=924" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/20/powershell-me-and-the-mcm-part-ii/">Powershell, Me and the MCM part II</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/20/powershell-me-and-the-mcm-part-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Powershell, Me and the MCM</title>
		<link>https://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=powershell-me-and-the-mcm</link>
					<comments>https://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 16 Dec 2010 15:00:23 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[MCM]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=920</guid>

					<description><![CDATA[<p>If you haven&#8217;t heard yet, Microsoft has made some significant changes to the MCM program.  The changes make the certification more accessible to the masses. You can read more about that from sources such as [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/">Powershell, Me and the MCM</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>If you haven&#8217;t heard yet, Microsoft has made some significant changes to the MCM program.  The changes make the certification more accessible to the masses.</p>
<p>You can read more about that from sources such as the following:</p>
<ol>
<li><a href="http://www.sqlservercentral.com/blogs/the-new-path-to-mcm">Grant Fritchey</a></li>
<li><a href="http://www.sqlservercentral.com/blogs/the-sql-server-mcm-training-has-changed">Jason Strate</a></li>
<li><a href="http://www.sqlservercentral.com/blogs/new-path-to-mcm-in-sql-server-2008">Glenn Berry</a></li>
<li><a href="https://web.archive.org/web/20120814084317/http://www.microsoft.com:80/learning/en/us/certification/master-sql-path.aspx">Microsoft</a></li>
</ol>
<p>This post is not so much about the changes.  More it is about the information dissemination related to the MCM.  I saw on twitter that there were some videos available to watch concerning the MCM training.  I was curious where these videos were so I decided to go looking for the videos.  In my search for the videos, I came across the Blog post referenced above by Jason Strate.  In that post, he has a link to the videos.  I decided to check out the videos and I decided to start downloading them so I could use them as study aids as I work on the MCITP.</p>
<p>Downloading those videos one by one is somewhat tedious and time consuming.  Thus while some were in the process of downloading, I started working on a few other things and saw another twitter post come across about a Powershell script to download those MCM training videos.  This is great news &#8211; except I have never run a powershell script.</p>
<p>Well, no time like the present to learn.  First thing to do is to check out the blog article about the script &#8211; it has a few downloads.  The blog post is by Eric Humphrey, and can be found <a href="http://lotsahelp.blogspot.com/2010/12/download-mcm-readiness-videos-with.html">here</a>.  After having read what he had to say about the script and downloading the necessary files that he lists, it was time to find out how to run a powershell script.  A little looking and I came across this <a href="http://technet.microsoft.com/en-us/library/ee176949.aspx">article</a>.</p>
<p>Excellent I am well under way now to run this script.  After following some of the recommendations in that article (e.g. security settings), it was time to look at the script and see what I needed to know from there, such as paths required for add-in files or paths for destination files.  Some quick adjustments to the userprofile path and to the download directory, as well as copying the HTMLAgilityPack into the userprofile path &#8211; and we are all set.</p>
<p>Now I have the script running and downloading the files &#8211; but it looks like it is going to be running for a long time.  This is a very useful tool for me at this moment.  This demonstrates another use for Powershell as well.  I haven&#8217;t yet decided that I will pursue the MCM, however I will use these videos to improve my knowledge base on SQL server.  I would recommend that people go check out these videos.  It was somewhat surprising to me to see that many of the pages had not been viewed very frequently at all.  This is great training material.  I recommend getting it and adding it to the reference material you may already have.</p>
<p>If you are just looking to browse the videos individually, you can find the site <a href="http://technet.microsoft.com/en-us/sqlserver/ff977043">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=920" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/">Powershell, Me and the MCM</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/16/powershell-me-and-the-mcm/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #13 &#8211; Business Requirements</title>
		<link>https://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-13-business-requirements</link>
					<comments>https://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 14 Dec 2010 01:00:35 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=907</guid>

					<description><![CDATA[<p>I think a common area that is easily overlooked when it comes to requirements and interpretation of requirements is report creation.  A common problem is that there are no defined or written requirements for the creation of a report.</p>
The post <a href="https://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/">T-SQL Tuesday #13 – Business Requirements</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Business Requirements<img loading="lazy" class="size-full wp-image-912 alignleft" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></h2>
<p>We have made it yet another month and to yet another episode in the continuing saga known as TSQL Tuesday.  This month we are being hosted by Steve Jones ( <a href="http://www.sqlservercentral.com/blogs/steve_jones/default.aspx">Blog </a>| <a href="http://twitter.com/@Wayoutwest">@Wayoutwest</a> ) of SqlServerCentral fame.  Steve has asked us to speak a little bit about business requirements, interpreting those requirements, and some of the pitfalls that may or may not exist in the whole communication process of getting a project done.  Now, can somebody please explain the requirements for me?</p>
<h3>What issues have you had in interacting with the business to get your job done?</h3>
<p>I think a common area that is easily overlooked when it comes to requirements and interpretation of requirements is report creation.  A common problem is that there are no defined or written requirements for the creation of a report.  When there are inadequate requirements, it is easy to miss the intention of the report and thus frustrate the business group that requested the report.  Another problem that can arise is the perceived inaccuracy of a report &#8211; even when all business requirements are properly met and signed off by the requesting business group.  How can that be?  Let me explain.</p>
<h3>Perceptions</h3>
<p>A recent problem was brought to light that revolved around the creation of two similar reports.  The reports were to be used by different business groups and each was requested by a different group.  The values in the reports no longer match due to a change requested on ReportA by GroupA.  GroupB doesn&#8217;t think this is accurate and wants both reports to match.  Small problem is that both reports should not produce the exact same results based on requirements and usage.  The report for GroupA has some extra requirements and filters placed on it to prevent the users from seeing data about former employees.  The report for GroupB is different in that it should show an overall summary for all data, even data of former employees.</p>
<h3>Re-Alignment</h3>
<p>Managing business requirements is almost as much about managing the perceptions of the business users as it is understanding what the business truly wants.  It is important that you are able to help them understand what it is you will be doing, what you can accomplish, when you can do it, and what impact it may have on other business parts (if they are known).  When an issue arises, it is best to approach the business and try to understand what the disconnect is.  In the case of the example of two reports outlined, I had to research and test both reports to get a better understanding of what the problem was.  Once I did that, then it was a matter of explaining the findings to the business.  From there, a discussion between business analyst and the two departments for which the reports serve needs to take place and an agreement made.</p>
<h3>Conclusion</h3>
<p>This is a rather short and straight-forward entry for this month for TSQL Tuesday.  This is a delicate subject and I am sure many people will have many more tales to tell.  I think it is most important to approach the business and try to help them understand what you understand from the requirements and get it hammered out before too much development has been done.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=907" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/">T-SQL Tuesday #13 – Business Requirements</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/13/t-sql-tuesday-13-business-requirements/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Wait Stats resources</title>
		<link>https://jasonbrimhall.info/2010/12/13/wait-stats-resources/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wait-stats-resources</link>
					<comments>https://jasonbrimhall.info/2010/12/13/wait-stats-resources/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 13 Dec 2010 23:11:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[troubleshoot]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=909</guid>

					<description><![CDATA[<p>Today I was out and about looking for past roundups on TSQLTuesday.  While doing that, I came across a post from Paul Randal (Blog &#124; Twitter) about wait stats.  The thing that strikes me about this [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/13/wait-stats-resources/">Wait Stats resources</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today I was out and about looking for past roundups on TSQLTuesday.  While doing that, I came across a post from Paul Randal (<a href="http://www.sqlskills.com/BLOGS/PAUL/">Blog</a> | <a href="http://twitter.com/PaulRandal">Twitter</a>) about wait stats.  The thing that strikes me about this post is the great query and the excellent references to more resources.  I recommend that you check out the article he has written on the topic.  Also, make sure you read the reference material he has provided.</p>
<p>You can find it <a href="https://www.sqlskills.com/blogs/paul/wait-statistics-or-please-tell-me-where-it-hurts/">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=909" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/13/wait-stats-resources/">Wait Stats resources</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/13/wait-stats-resources/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SSIS Job Execution</title>
		<link>https://jasonbrimhall.info/2010/12/13/ssis-job-execution/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ssis-job-execution</link>
					<comments>https://jasonbrimhall.info/2010/12/13/ssis-job-execution/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 13 Dec 2010 22:08:27 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=903</guid>

					<description><![CDATA[<p>While working on a process to refresh the QA environment (data purge, reload data and reapply changes made over time as parts of release cycles), I ran into self-imposed requirement.  I was attempting to create [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/13/ssis-job-execution/">SSIS Job Execution</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>While working on a process to refresh the QA environment (data purge, reload data and reapply changes made over time as parts of release cycles), I ran into self-imposed requirement.  I was attempting to create a process that would perform the entire process consistently.  Amongst the items that I needed to include in this process to &#8220;refresh&#8221; the QA environment was the need to run a couple of SSIS packages.  SSIS was not installed on this particular server where I was creating this process.  I needed to have a way of executing two SSIS packages without installing SSIS on the local server.</p>
<p>With that need, I decided to test a remote execution of a job that had SSIS steps.  The method I decided to use was to employ OSQL.  Here is what I did for that.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">osql -S &quot;remoteserver\remoteinstance&quot; -E -Q&quot;exec msdb.dbo.sp_start_job 'Remote Job Name'&quot;</pre><p>[/codesyntax]</p>
<p>I added that line of code to a SQL Agent Job step.  The job step type is Operating System (CMDExec).</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/12/cmdexec.jpg"><img loading="lazy" class="alignnone size-full wp-image-904" title="cmdexec" src="http://jasonbrimhall.info/wp-content/uploads/2010/12/cmdexec.jpg" alt="" width="698" height="161" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/12/cmdexec.jpg 873w, https://jasonbrimhall.info/wp-content/uploads/2010/12/cmdexec-300x69.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>This method works well for me since I had already tested the package on the remote server and knew that it worked.  There are several other methods as well, this happened to be implemented more quickly for me at this time.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=903" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/13/ssis-job-execution/">SSIS Job Execution</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/13/ssis-job-execution/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL Confessions</title>
		<link>https://jasonbrimhall.info/2010/12/13/sql-confessions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-confessions</link>
					<comments>https://jasonbrimhall.info/2010/12/13/sql-confessions/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 13 Dec 2010 21:37:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Confessions]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=890</guid>

					<description><![CDATA[<p>I had a brainstorm of an idea for a group of articles on my blog a couple of weeks ago and am finally getting around to putting it together.  The idea came about while I [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/12/13/sql-confessions/">SQL Confessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I had a brainstorm of an idea for a group of articles on my blog a couple of weeks ago and am finally getting around to putting it together.  The idea came about while I was struggling with a problem at work and trying to meet the requirements in the code.  As the title states, this group is going to be about things done in SQL server that I would normally avoid.</p>
<p>The first article came about while trying to find a solution to some business requirements.  The requirements had an average to be calculated and then a revised average if certain criteria were met.  Then it was required to move things from one group to another group depending on a series of criteria.  When I first looked at these requirements, I thought I would need several cursors.  As it turns out, I had to implement just one cursor.  I could find no way of getting away from using a cursor for this one requirement.  The essence of it was that I had two variables.  One variable was the number of items to move and the second variable was the person to whom the items needed to be moved.  Not only did it require those two variables, but there was the additional requirement that it be randomized.</p>
<p>First, let&#8217;s take a look at how I did the randomizing.  I took care of this requirement by dumping all of my prep data into a temp table that had a default on a column explicitly to hold  a random value.  Here is the code for that table.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Create Table LeadRedist_PhaseThree2 (
	LeadRedistID			Int Identity(1,1) Primary Key Clustered,
	ActivityOwner			uniqueidentifier,
	OppOwner				uniqueidentifier,
	OpportunityID			uniqueidentifier,
	ownershipbegindate		Datetime,
	ScheduledDate			Datetime,
	Disposition				Varchar(30),
	Randomizer				Float DEFAULT RAND(CHECKSUM(NEWID())) * 10000,
	RowNum					Int,
	OwnerFullName			Varchar(50),
	OppAuditDetailID		uniqueidentifier DEFAULT NEWSEQUENTIALID(),
	ActAuditDetailID		uniqueidentifier DEFAULT NEWSEQUENTIALID(),
	OppAuditID				uniqueidentifier DEFAULT NEWSEQUENTIALID(),
	ActAuditID				uniqueidentifier DEFAULT NEWSEQUENTIALID(),
	NewOwner				uniqueidentifier
)</pre><p>[/codesyntax]</p>
<p>Using this table, I can just run a set-based insert to populate the table and thus end up with random values in the &#8220;Randomizer&#8221; column due to the default constraint.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DEFAULT RAND(CHECKSUM(NEWID())) * 10000</pre><p>[/codesyntax]</p>
<p>That piece of the puzzle was fixed rather easily.  Now for the next part &#8211; the confession part.  I had to write a cursor.  Next part of that confession &#8211; I had to look up how to write the cursor.  Without going into a lot of details, this is the code of how I used a cursor to solve this particular problem.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Declare @NewUserID	UniqueIdentifier
		,@OppstoRec	Int

Declare PhaseThree_Cursor Cursor
	For
		Select LV.SystemUserID, LV.OppstoReceive
			From LeadRedist_Avgs2 LV
			Where LV.OppstoReceive &amp;gt; 0
			Order By LV.OppstoReceive Desc

Open PhaseThree_Cursor;

	Fetch Next From PhaseThree_Cursor
		Into @NewUserID, @OppstoRec;

	WHILE @@FETCH_STATUS = 0
	Begin
		With reassign as (
			Select top (@OppstoRec) LP.LeadRedistID
				From LeadRedist_PhaseThree2 LP
				Where LP.NewOwner is null
				Order By LP.Randomizer Desc
		)

		Update LP
			Set LP.NewOwner = @NewUserID
			From LeadRedist_PhaseThree2 LP
				Inner Join reassign r
					On LP.LeadRedistID = r.LeadRedistID

	Fetch Next From PhaseThree_Cursor
		Into @NewUserID, @OppstoRec;
	End

Close PhaseThree_Cursor
DeAllocate PhaseThree_Cursor</pre><p>[/codesyntax]</p>
<p>Note that this cursor is a little hybrid.  I am using this cursor to perform some set based actions.  I am fine with that.  I am happy with the random distribution and the fact that this performs well.  This was done for a one off requirement that will not be used again (or at least not planned to be used again) and it met all of the requirements.  I was blocked on this particular requirement by the required variables and couldn&#8217;t get past how to do this in a 100% set-based fashion.  If you have any input, let me know.</p>
<p>Do you have any such stories to share?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=890" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/12/13/sql-confessions/">SQL Confessions</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/12/13/sql-confessions/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Drumroll Please&#8230;</title>
		<link>https://jasonbrimhall.info/2010/11/29/drumroll-please/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=drumroll-please</link>
					<comments>https://jasonbrimhall.info/2010/11/29/drumroll-please/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 29 Nov 2010 21:59:43 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=881</guid>

					<description><![CDATA[<p>Defensive Db Programming Chapter 10 After dragging this review on for months now, it is finally time to bring this bad boy home and wrap it up.  I have been working through a chapter by [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/29/drumroll-please/">Drumroll Please…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2>Defensive Db Programming Chapter 10</h2>
<p>After dragging this review on for months now, it is finally time to bring this bad boy home and wrap it up.  I have been working through a chapter by chapter review of the book by Alex Kuznetsov (<a href="http://sqlblog.com/blogs/alexander_kuznetsov/default.aspx" class="broken_link">Blog </a>| <a href="https://twitter.com/search?q=alexk_v&amp;src=typd">Twitter</a>).  Alex has been taking us through the process and various techniques to better program defensively.  This is the last installment in that series (yes shed a little tear).  This chapter is devoted to teaching us how to better deal with Modifications that Survive Concurrency.  Some of the problems associated with this are:</p>
<div id="_mcePaste">
<ul>
<li>lost modifications, a.k.a. lost updates – such problems occur when modifications performed by one connection are overwritten by another; these typically occur silently; no errors are raised</li>
<li>resource contention errors – such as deadlocks and lock timeouts</li>
<li>primary key and unique constraint violations – such problems occur when different modifications attempt to insert one and the same row. (p. 337)</li>
</ul>
</div>
<p>Another way of stating these types of problems is that there is a &#8220;Race Condition.&#8221;  You may have heard this term thrown around by the developers from time to time.  It isn&#8217;t made up and is a very real potential problem that must be dealt with accordingly.</p>
<p>I can&#8217;t give this chapter enough props nor enough due through a short blog post on it.  It is a lengthy chapter and covers a very important topic (my opinion).  Alex covers each of the race conditions and continues to show how to resolve that race condition.  He uses real world scenarios as you should have grown to see up to this point.  I will point out that I had not considered using RowVerssion to help resolve some race conditions.  That is at least one thing I have learned from reading this chapter.</p>
<p>Another thing that struck me and made me think is related to the TSQL patterns that Fail High concurrency.  Here two methods are scrutinized and a third method is proposed.  The third method is MERGE.  That is a subject about which I could learn a lot.</p>
<p>For the final time (since this series has come to a close), go get the book and read it.  You can find the rest of the articles by linking back through this <a href="http://jasonbrimhall.info/2010/11/22/defensive-db-programming-chapter-09/">link</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=881" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/29/drumroll-please/">Drumroll Please…</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/29/drumroll-please/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Defensive Db Programming Chapter 08</title>
		<link>https://jasonbrimhall.info/2010/11/11/defensive-db-programming-chapter-08/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defensive-db-programming-chapter-08</link>
					<comments>https://jasonbrimhall.info/2010/11/11/defensive-db-programming-chapter-08/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 11 Nov 2010 16:48:08 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=865</guid>

					<description><![CDATA[<p>We are slowly getting to the end of this book by Alex Kuznetsov (Blog).  You can find more on this series by looking here.  We are now discussing chapter 8 and it is a good chapter. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/11/defensive-db-programming-chapter-08/">Defensive Db Programming Chapter 08</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We are slowly getting to the end of this book by Alex Kuznetsov (<a href="http://sqlblog.com/blogs/alexander_kuznetsov/default.aspx" class="broken_link">Blog</a>).  You can find more on this series by looking <a href="http://jasonbrimhall.info/tag/professional-book-review/">here</a>.  We are now discussing chapter 8 and it is a good chapter.  This chapter delves into Error Handling.</p>
<blockquote><p>While the use of TRY…CATCH certainly is the best way to handle errors in T-SQL, it is not without difficulties. (p. 259)</p></blockquote>
<p>In this chapter, Alex discusses some of the problems associated with error handling and demonstrates how to resolve some of those problems.  We will also see how to use XACT_ABORT.</p>
<p>The first key to error handling is to prepare for unanticipated failure.  That is the crux of error handling.  We anticipate certain behaviors and code for that, anything else needs to be handled through error handling so we can see what has happened.  Code sometimes fails, and queries against the data can also fail on occasion &#8211; we need to plan for those failures.</p>
<p>When dealing with data modifications there are occasions when using explicit transactions is necessary due to the nature of the data modification &#8211; we would want to ensure that any and all changes to the data were rolled back.  There are other times when we would want to ensure that processing halts immediately when an error is encountered.  In such a scenario, XACT_ABORT comes in useful.  Note, however, that this setting is probably better set explicitly ON or OFF depending on the needs.</p>
<p>A recommendation in this chapter is to use client-side error handling for all but the simplest of error handling.  Error-handling is far more robust in other languages than it is in TSQL.  This is a recommendation that I support.  Error handling in TSQL has become better over time (i.e. with the addition of the TRY&#8230;CATCH) and is quite useful for some degrees of error handling.  One particular realm where error handling in TSQL is lacking is in the area of Code-Reuse.  The TRY&#8230;CATCH must be rewritten for each stored procedure for which you wish to enable error handling.</p>
<p>As always, this chapter covers some of the gotchas of error handling in TSQL and gives examples on how to implement as well as circumvent some of the problems.  Check it out!!</p>
<blockquote>
<blockquote></blockquote>
</blockquote>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=865" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/11/defensive-db-programming-chapter-08/">Defensive Db Programming Chapter 08</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/11/defensive-db-programming-chapter-08/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Blogger Awards</title>
		<link>https://jasonbrimhall.info/2010/11/09/blogger-awards/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=blogger-awards</link>
					<comments>https://jasonbrimhall.info/2010/11/09/blogger-awards/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 10 Nov 2010 01:24:30 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[Awards]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=863</guid>

					<description><![CDATA[<p>A few days ago I wrote about an election that was taking place (ok so it was a week ago at this point).  That election was the SQLServerpedia Awards.  My first post on that election [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/09/blogger-awards/">Blogger Awards</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>A few days ago I wrote about an election that was taking place (ok so it was a week ago at this point).  That election was the <a href="https://web.archive.org/web/20130409114529/http://pulse.sqlserverpedia.com:80/awards/">SQLServerpedia Awards</a>.  My first post on that election can be found <a href="http://jasonbrimhall.info/2010/11/02/voting-day-is-here/">here</a>.  I had wanted to write another post about the election and make a whole bunch of campaign promises &#8211; to help make it feel political.  One big difference is that I was going to run a positive campaign and just talk about what I would do if I were to win.</p>
<p>Well, I won in one of the categories and I never wrote that campaign promises post.  So, I will just tell you what I would have promised and then maybe do some of those things.</p>
<ol>
<li>I will display the trophy in my cubicle at work</li>
<li>I will support my fellow bloggers as much as I can just as I have done in the past.  There are some exceptional bloggers out there.</li>
<li>I will continue to work with SQL Server</li>
<li>I will continue to blog!!!!</li>
<li>I will also finish my series on the book review for which I won.  Then I will progress to the next book or two and write reviews for them as well.</li>
<li>I will continue to provide posts to SQLServerPedia</li>
</ol>
<p>Thanks to all who voted for me.  I appreciate the support.  I recommend checking out the other books in the Book Review category.  I also recommend that you read the Blogs of the other people that were nominated for the SQL Choice Awards/ SSP Awards.</p>
<p>In short, this award is great and I really appreciate it.  In the grand scheme of things I am happy to have received it and rest assured that it doesn&#8217;t change my blog or me &#8211; except that I will post a badge on my blog.  We also had many excellent DB professionals and bloggers who won in various other categories.</p>
<p>Thanks SQLServerpedia for the awards and putting on these awards for the community.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=863" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/09/blogger-awards/">Blogger Awards</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/09/blogger-awards/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Defensive Db Programming Chapter 07</title>
		<link>https://jasonbrimhall.info/2010/11/03/defensive-db-programming-chapter-07/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defensive-db-programming-chapter-07</link>
					<comments>https://jasonbrimhall.info/2010/11/03/defensive-db-programming-chapter-07/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 03 Nov 2010 18:01:15 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=853</guid>

					<description><![CDATA[<p>We are here again after another &#8230;um long lapse in time &#8230; and ready for another episode in this series.  Today we get to talk about chapter 7 in the book by Alex Kuznetsov (Blog). [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/03/defensive-db-programming-chapter-07/">Defensive Db Programming Chapter 07</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We are here again after another &#8230;um long lapse in time &#8230; and ready for another episode in this series.  Today we get to talk about chapter 7 in the book by Alex Kuznetsov (<a href="http://sqlblog.com/blogs/alexander_kuznetsov/default.aspx" class="broken_link">Blog</a>).  You can find more on this series by looking <a href="http://jasonbrimhall.info/tag/professional-book-review/">here</a>.</p>
<h2>Advanced Use of Constraints</h2>
<p>This chapter ties in well with chapters 4 and 6.  You may want to review those chapters as you read this chapter.  There were problems raised in those prior chapters and now they are being discussed at length in this chapter.  First order of business is to revisit the ticket tracking system that was discussed in chapter 4.</p>
<h3>Ticket Tracking</h3>
<p>The system was left with business rules implemented via triggers in chapter 4.  We are now going to explore using constraints in lieu of the triggers to enforce the business rules.  For sake of testing, the environment should be reset and a new environment built.  Alex provides all of the scripts to do so.  As Alex progresses through this example he lays out the assumptions and some of the problems with those assumptions.  Through a combination of Indexes and constraints.  Another item that was implemented was the use of ON UPDATE CASCADE to help ensure the business requirements could be met.  Alex talks about the implications on performance and the reasons for implementing the cascade update.  Make sure you read this chapter to find out more.</p>
<h3><strong>Inventory System</strong></h3>
<p><strong>There is a substantial amount of discussion about a new example in this chapter.  That discussion revolves around the Inventory System and several use cases.  I recommend reading the chapter.  I am not going to discuss it beyond that here in this post.  There are a great collection of scripts to run through the example.</strong></p>
<h3><strong>Conclusion</strong></h3>
<p><strong>In this chapter Alex shows us how a combination of constraints can enforce complex business rules.  The use of constraints should be included as a viable option when trying to enforce business rules.</strong></p>
<p>Once again, go get this book and read it.  It is well worth the read.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=853" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/03/defensive-db-programming-chapter-07/">Defensive Db Programming Chapter 07</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/03/defensive-db-programming-chapter-07/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #012 &#8211; Skills</title>
		<link>https://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-012-skills</link>
					<comments>https://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 02 Nov 2010 18:49:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=835</guid>

					<description><![CDATA[<p>November is upon us and in some areas this also means that the leaves have changed color.  With the change in leaves we also have a change in TSQL Ones&#8230;err Tuesday this month.  The change [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/">T-SQL Tuesday #012 – Skills</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="https://www.sqlskills.com/blogs/paul/invitation-to-participate-in-t-sql-tuesday-12-why-are-dba-skills-necessary/"><img loading="lazy" class="alignright size-full wp-image-836" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/11/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>November is upon us and in some areas this also means that the leaves have changed color.  With the change in leaves we also have a change in TSQL Ones&#8230;err Tuesday this month.  The change is with good reason as well.  November is a busy month in the DBA world.  PASS is holding the <a href="http://www.sqlpass.org/summit/na2010/">Summit</a> Nov 8 &#8211; 11 in Seattle (that involves the second Tuesday).  We have <a href="http://www.devconnections.com/shows/FALL2010SQL/default.asp?s=153">Connections</a> this week in Las Vegas (despite being in Vegas, I won&#8217;t be there due to budgetary constraints).  And we have Paul Randal (<a href="http://www.sqlskills.com/BLOGS/PAUL/">Blog</a> | <a href="http://twitter.com/PaulRandal">Twitter</a>) hosting <a href="https://www.sqlskills.com/blogs/paul/invitation-to-participate-in-t-sql-tuesday-12-why-are-dba-skills-necessary/">TSQLTuesday </a>this month.</p>
<p>Paul has chosen the topic of &#8220;why are DBA skills necessary?&#8221;</p>
<h2><a href="http://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon-dynamite-cagefighter.jpg"><img loading="lazy" class="alignleft size-full wp-image-839" title="napoleon-dynamite-cagefighter" src="http://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon-dynamite-cagefighter.jpg" alt="" width="300" height="466" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon-dynamite-cagefighter.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon-dynamite-cagefighter-193x300.jpg 193w" sizes="(max-width: 300px) 85vw, 300px" /></a>You know, like nunchuku skills, bow hunting skills, computer hacking skills&#8230;</h2>
<p>Oh wait, maybe I do have some of those computer skills.  I don&#8217;t have nunchuku skills though, and that could be useful from time to time.</p>
<p>As a DBA, we occasionally have the opportunity of attracting a new client or a new job or a new database.  It seems that more often than not, some of the skills requisite (at least they should be) of owning a database are missing.</p>
<p>Some of these include:</p>
<p>Backup and recovery of a database<br />
Indexing<br />
Disaster Recovery<br />
Normalization and De-normalization<br />
Performance Tuning<br />
Server Patching<br />
Proper Storage recommendations<br />
De-fragmentation<br />
File and Filegroup Creation<br />
Performance Troubleshooting<br />
User and Database Security<br />
And more&#8230;</p>
<h2>And more&#8230;</h2>
<p>I want to touch on some of the other skills of a DBA.  These are the skills that a DBA must use in order to be successful (besides knowing the craft).  For me, these skills help make the job just a bit easier and they seem to be present in many of the top tier Database Professionals.  For me, these skills include:  Communication, Participation, Sense of Community, and Drive.  These may also appear as attributes &#8211; but I think they are things that a professional can work on and improve on to improve in the work place.</p>
<h3>Communication</h3>
<p>This is a skill employed in many different ways in the profession.  Many have chosen to communicate via blogs and via speaking at events, while others have written books.  This skill is a must have in the day to day business and helps to mend fences between DBA and business as well as DBA and Development.  Learning how to interact with both the positive as well as the harsh feedback is critical to career growth.</p>
<h3>Participation</h3>
<p>As a database professional, it is essential to be involved in meetings and the decision making process.  Just being present does not always mean that you are participating.  Are you engaged in thought of getting out of the meeting or about the next level on Angry Birds?  Or are you listening, taking notes (if necessary), and interjecting comment that is constructive to the meeting?  When a task comes across your desk, what is your reaction?  Do you just do it or do you interface with the requester to ensure that the request meets the needs?  Occasionally it will happen that the requirements do not reflect the true need from the person making the request.  Without talking to that person, a level of frustration is accomplished when you return to them having completed the request but not having fulfilled the underlying needs.</p>
<h3>Sense of Community</h3>
<p>One of the best networks available to use is the social network for the Database Professional.  There is a good amount of people always willing to help via twitter (#sqlhelp) and online forums (<a href="http://www.sqlservercentral.com">sqlservercentral.com</a>).  A good DBA knows his/her limits and knows that they don&#8217;t know everything.  Admit it early and be willing to rely on the community when you don&#8217;t know something.  Part of being a good database professional is knowing where to find help and where to find the answer.  This also ties in with the communication skill.  There is no need to memorize every nook and cranny of SQL Server.  Learn how to take notes, create documentation, and how to talk to the community.  This will help you learn more about SQL as well as help you build friendships.</p>
<h3>Drive</h3>
<p>This one is a lot more difficult.  A skill that is helpful in being a better Database Professional is an internal motivation to be better and to create a better database environment no matter the employer or project.  If this means longer hours or making significant changes &#8211; then do it.  Sometimes it also means that we need to make a list and present the good with the bad of the environment and then make suggestions on how to improve.  If you are really good and don&#8217;t put in any extra effort &#8211; imagine how good you could be should you dedicate a few extra hours here and there to becoming a better Database Professional.</p>
<h2>Oh and the other stuff</h2>
<p>I don&#8217;t want to completely ignore those important skills.  There are many accidental DBA&#8217;s out in the world due to a database having come into existence.  Many times a database can exist without a DBA due to various variables such as vendor support, little to no activity, or low criticality of the data.  Many times one of these databases eventually explodes into being much more than initially planned (high transaction or high criticality or even reduced vendor support).  At this point a DBA is needed.  DBA&#8217;s help protect the data and are an investment for the company.  A DBA can help provide timely information as well as protect the data and ensure business continuity.  For me, it is a worthwhile investment &#8211; and not just because I do the work.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon_dynamite_tshirt.jpg"><img loading="lazy" class="size-full wp-image-843 alignright" title="napoleon_dynamite_tshirt" src="http://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon_dynamite_tshirt.jpg" alt="" width="319" height="316" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon_dynamite_tshirt.jpg 319w, https://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon_dynamite_tshirt-150x150.jpg 150w, https://jasonbrimhall.info/wp-content/uploads/2010/11/napoleon_dynamite_tshirt-300x297.jpg 300w" sizes="(max-width: 319px) 85vw, 319px" /></a></p>
<h2>In Conclusion</h2>
<p>Today is Election Day throughout the United States.  Get out and Vote!</p>
<p>There are elections at <a href="https://web.archive.org/web/20130409114529/http://pulse.sqlserverpedia.com:80/awards/">SQLServerPedia</a>, <a href="http://www.zoomerang.com/Survey/WEB22BD59JCQBT">SQLRally </a>and then there are also the political elections.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=835" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/">T-SQL Tuesday #012 – Skills</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/02/t-sql-tuesday-012-skills/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>November Snuck Up on Me</title>
		<link>https://jasonbrimhall.info/2010/11/01/november-snuck-up-on-me/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=november-snuck-up-on-me</link>
					<comments>https://jasonbrimhall.info/2010/11/01/november-snuck-up-on-me/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 01 Nov 2010 14:45:40 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSSOLV]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=832</guid>

					<description><![CDATA[<p>I should have gotten this post out last week with another follow-up this week.  Well, looks like I will have to get a couple out this week to try to remind people.  This month SSSOLV [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/11/01/november-snuck-up-on-me/">November Snuck Up on Me</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I should have gotten this post out last week with another follow-up this week.  Well, looks like I will have to get a couple out this week to try to remind people.  This month SSSOLV has moved up 1 week due to Connections being in town this month and PASS being next week.  With Connections being in town this week, I was able to convince Steve Jones (<a href="http://www.sqlservercentral.com/blogs/steve_jones/default.aspx">Blog </a>| <a href="http://www.twitter.com/way0utwest">Twitter</a>) to come and speak to us.  It works well if we move our regularly scheduled meeting from the second Thursday to the first Thursday of the month.</p>
<p>Steve is going to talk to us this month about the modern resume.  And for those that don&#8217;t know who Steve is, Steve is a co-founder of <a href="http://www.sqlservercentral.com/">SQLServerCentral </a>and is currently the Editor of SQLServerCentral.</p>
<p>We will be hosting this presentation via LiveMeeting as well.  Here are the details for joining the meeting virtually.</p>
<p>Attendee URL: https://www.livemeeting.com/cc/usergroups/join?id=PPBZ4S&amp;role=attend</p>
<p>Meeting ID: PPBZ4S</p>
<p>The meeting will be from 6:30 &#8211; 9 PDT at the Learning Center ( 777 N. Rainbow Ste. 250 Las Vegas 89107).  I am still working on the evite at this time (the contacts list is unavailable currently).</p>
<p>We hope to see you there.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=832" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/11/01/november-snuck-up-on-me/">November Snuck Up on Me</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/11/01/november-snuck-up-on-me/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>My SQLSat54 Experience</title>
		<link>https://jasonbrimhall.info/2010/10/25/my-sqlsat54-experience/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=my-sqlsat54-experience</link>
					<comments>https://jasonbrimhall.info/2010/10/25/my-sqlsat54-experience/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 25 Oct 2010 14:33:14 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=823</guid>

					<description><![CDATA[<p>In case you hadn&#8217;t heard SQLSaturday #54 was Oct 23 in Salt Lake City.  It was a dreary opening to the Deer hunt, and a good morning to be inside to learn about SQL Server. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/10/25/my-sqlsat54-experience/">My SQLSat54 Experience</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In case you hadn&#8217;t heard SQLSaturday #54 was Oct 23 in Salt Lake City.  It was a dreary opening to the Deer hunt, and a good morning to be inside to learn about SQL Server.  I was there to make my first presentation at a larger scale event (than a UG setting).</p>
<p>I got to meet some cool people and to learn a few things while I was there.  I enjoyed the time I had to chat with Denny Cherry (<a href="http://www.twitter.com/mrdenny">Twitter </a>| <a href="http://itknowledgeexchange.techtarget.com/sql-server/" class="broken_link">Blog</a>), Nic Cain (<a href="https://twitter.com/search?q=anonythemouse&amp;src=typd">Twitter</a> | <a href="https://twitter.com/SirSQL">new twitter</a> | <a href="http://englishtosql.com">Blog</a>), Bill Pearson (<a href="http://www.twitter.com/Bill_Pearson">Twitter</a>), TJay Belt (<a href="http://www.twitter.com/tjaybelt">Twitter </a>| <a href="http://tjaybelt.blogspot.com">Blog</a>), Pat Wright (<a href="http://www.twitter.com/SqlAsylum">Twitter </a>| <a href="http://sqlasylum.wordpress.com/about/">Blog</a>), Meredith Ryan-Smith (<a href="http://www.twitter.com/coffegrl">Twitter</a>), and Randy Knight (<a href="http://www.twitter.com/randy_knight">Twitter</a>) as well as some others.</p>
<p>I picked up a few pointers for when we do a SQLSat in Las Vegas (like order overkill on the pizza).  It is also encouraging after having participated in a SQLSat to just get out and do it.  Nevermind the concerns about this or that, just do it.  So we will be formally working toward a SQLSat in LV very shortly.  I will be presenting that to the UG in LV first though.  We had tinkered with the idea &#8211; but now it is time to do something about it.</p>
<p>If you have never participated in a SQLSat, I highly recommend that you do.  I got some good networking in, some knowledge transfer, and I got to give my presentation (which needs a little more tuning).  That brings me to another thing that I learned.  It seems to be a trend that it is difficult to get audience participation no matter where you go (first hand experience as well as from what I have heard).  As presenters, many thrive on participation.  For my presentations &#8211; <strong>participation is crucial</strong>.</p>
<p>I hope to see you at future SQL Saturdays.</p>
<p>Oh,  and many thanks to Tjay Belt and Pat Wright for organizing this event.  Great Job.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=823" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/10/25/my-sqlsat54-experience/">My SQLSat54 Experience</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/10/25/my-sqlsat54-experience/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>A Haunting TSQL Tuesday Tale</title>
		<link>https://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-haunting-tsql-tuesday-tale</link>
					<comments>https://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 12 Oct 2010 05:02:01 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLBP]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SSC]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[back to basics]]></category>
		<category><![CDATA[SQL Myth]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=813</guid>

					<description><![CDATA[<p>If you truncate a table, you cannot undo the action like you can with a delete.  What is the difference between the two methods to remove data from a table?</p>
The post <a href="https://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/">A Haunting TSQL Tuesday Tale</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/?s=back+to+basics"><img loading="lazy" class="alignright wp-image-814" title="halloween" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/halloween.jpg" alt="" width="389" height="291" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/10/halloween.jpg 450w, https://jasonbrimhall.info/wp-content/uploads/2010/10/halloween-300x224.jpg 300w" sizes="(max-width: 389px) 85vw, 389px" /></a>Time for the ghouls and goblins to come out of the woodwork once again for another tale of deception and tyranny.  OK maybe not tyranny but definitely a haunting tale is to be told this month while trick-or-treaters plan their routes and mend their costumes.  We have SQueeLing experts suiting up for the adult party known as TSQL Tuesday.</p>
<p>This month the vampires, ghosts, and zombies are all breaking it down at Sankar Reddy&#8217;s place (<a href="http://sankarreddy.com">Blog</a> | <a href="http://twitter.com/SankarReddy13">Twitter</a>).  The ghoulish stories to be shared are to be myths from the underSQLworld.</p>
<h3><a href="http://sankarreddy.com/2010/10/invitation-to-participate-in-t-sql-tuesday-11-misconceptions-in-sql-server/"><img loading="lazy" class="alignleft size-full wp-image-815" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>Truncating a Table is Unrecoverable</h3>
<p>Have you heard this one in the past?  If you truncate a table, you cannot undo the action like you can with a delete.  What is the difference between the two methods to remove data from a table?</p>
<p>When you truncate a table, the pages are deallocated with minimal locking of the resources.  When you use the delete statement, the data is deleted row-by-row with more locks.  Everybody knows that a delete can be rolled back.  Many people believe that a Truncate cannot be rolled back.</p>
<p>Well, at this point we really need a table to test.  So let&#8217;s create a table and perform a few simple tests.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT TOP 1000000
		RollID       = IDENTITY(INT,1,1)
	INTO dbo.TruncTabRollback
	FROM Master.dbo.SysColumns t1,
		Master.dbo.SysColumns t2 

ALTER TABLE dbo.TruncTabRollback
	ADD PRIMARY KEY CLUSTERED (RollID)</pre><p>With the test table ready to go, we will begin with the baseline demonstration on the Delete command.  Here is the script to demonstrate that a Delete can be rolled back (but we already knew that).</p><pre class="urvanov-syntax-highlighter-plain-tag">Begin Tran delrollback

Delete TruncTabRollback

Select COUNT(*) as PreRollBack
	From TruncTabRollback

RollBack Tran delrollback

Select COUNT(*) as PostRollBack
	From TruncTabRollback</pre><p>Pretty simple and straight forward &#8211; baseline is proven with that script.  The premise that a Delete can be rolled back has been established.  Now, how about that truncate statement?  For the truncate statement, I will use the same simple script, substituting the appropriate commands in this script.</p><pre class="urvanov-syntax-highlighter-plain-tag">Begin Tran delrollback

Truncate Table TruncTabRollback

Select COUNT(*) as PreRollBack
	From TruncTabRollback

RollBack Tran delrollback

Select COUNT(*) as PostRollBack
	From TruncTabRollback</pre><p>When this script is executed, we see that indeed the data is recoverable.  Here are the results I get from the truncate and associated rollback script.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/10/TruncResults.jpg"><img loading="lazy" class="alignnone size-full wp-image-819" title="TruncResults" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/TruncResults.jpg" alt="" width="219" height="161" /></a></p>
<h3>Conclusion</h3>
<p>I think this is one of those myths that is frequently floated throughout the SQL world due to another myth that is related to the Truncate statement.  It is often explained that you can&#8217;t recover a truncate because the truncate is not logged.  That is also obviously wrong (if it weren&#8217;t logged, how could you recover the table without a restore?).  The myth about Truncate being non-logged has already been debunked (as has this one &#8211; in a different series) by Paul Randal in his <a href="http://www.sqlskills.com/BLOGS/PAUL/A-SQL-Server-DBA-myth-a-day-(1930)-TRUNCATE-TABLE-is-non-logged/" class="broken_link">Myth-A-Day</a> series.  The key to this is that the Truncate is logged and that you wrap the command in a transaction &#8211; and only commit when you are ready.</p>
<p>This happens to be a good post for the back to basics series. Other topics in the series include (but are not limited to): <a href="http://bit.ly/2heI2eG">Backups</a>, <a href="http://bit.ly/2h7Dpmr">backup history</a> and <a href="http://jasonbrimhall.info/2016/12/23/user-contains-invalid-characters-back-to-basics/">user logins</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=813" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/">A Haunting TSQL Tuesday Tale</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/10/11/a-haunting-tsql-tuesday-tale/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>It&#8217;s Implied</title>
		<link>https://jasonbrimhall.info/2010/10/05/its-implied/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=its-implied</link>
					<comments>https://jasonbrimhall.info/2010/10/05/its-implied/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 05 Oct 2010 15:00:18 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[permissions]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=803</guid>

					<description><![CDATA[<p>This has been on my radar now for a little over a week.  I ran across a  request in the forums to assist with permissions and decided to test some things.  The gist of the [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/10/05/its-implied/">It’s Implied</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This has been on my radar now for a little over a week.  I ran across a  request in the forums to assist with permissions and decided to test some things.  The gist of the request was to disallow a user from inserting into a table and still have execute permissions on a stored procedure that may need to insert data into the same table.</p>
<h3>The Setup</h3>
<p>To work through this, I decided to create a user, grant that user specific permissions, and create a stored procedure to which I would grant that user I created execute permissions.  All of this is pretty straight forward stuff just to demonstrate the principle.  I will also be using a database previously setup just for testing purposes.</p>
<p>So let&#8217;s just start by creating this user that we will be using to test our permissions.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">USE [master]
GO
CREATE LOGIN [TestRW] WITH PASSWORD=N'testrw' , DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE [TestA]
GO
CREATE USER [TestRW] FOR LOGIN [TestRW]
GO
USE [TestA]
GO
EXEC sp_addrolemember N'db_denydatawriter', N'TestRW'
GO</pre><p>[/codesyntax]</p>
<p>We can see that the user creation is pretty straight forward and we are immediately adding the user to the denydatawriter role for the database.  Now for the next couple of items that we will be using in this little experiment, a table and a stored procedure.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">create table testinsert	(testid int identity(1,1) primary key clustered, teststring varchar(50))</pre><p>[/codesyntax]</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Create Procedure sp_inserttestinsert

as

Insert into testinsert (teststring)
	Select 'Successfully inserted a string'</pre><p>[/codesyntax]</p>
<p>And the last little bit of the setup is to grant our TestRW user execute permissions on this stored procedure.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Grant execute on sp_inserttestinsert to TestRW</pre><p>[/codesyntax]</p>
<p>That is it for the initial setup.  I think this is a pretty straight forward setup to demonstrate these permissions.  The next item of business is to actually create these objects and to test.</p>
<h3>Testing &#8211; 1,2,3</h3>
<p>The testing I have setup for this is also pretty straight forward.  I will execute the proc and then select all records from that table that was created.  If successful, then there will be no records.  If (per the requirements), we see records then the setup has failed and we need to explore other options or find a reasonable conclusion that is preventing us from achieving success.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">exec sp_inserttestinsert

select * from testinsert</pre><p>[/codesyntax]</p>
<p>Upon executing that, you should see the following results at this point.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/10/round_01.jpg"><img loading="lazy" class="alignleft size-full wp-image-805" title="round_01" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/round_01.jpg" alt="" width="240" height="74" /></a></p>
<p>Well, would you look at that.  Having denydatawriter on the table, and granting execute permissions on the proc has allowed us to insert data into the table.  Let&#8217;s take it one step further now &#8211; what if we explicitly deny update, delete, and insert permissions on the table to this user?  We can do that with the next script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Deny insert,update, delete on testinsert to 
TestRW</pre><p>[/codesyntax]</p>
<p>With the new permissions added (or subtracted depending on how you look at it), we can test once again &#8211; using the same script as in the first round.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/10/round_02.jpg"><img loading="lazy" class="alignleft size-full wp-image-806" title="round_02" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/round_02.jpg" alt="" width="228" height="82" /></a></p>
<p>Well, now we can see that explicitly denying update, insert and delete on the table is no more effective than adding the user to the denydatawriter role.  Are the deny permissions even working at this point?  Well, this verify that.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Insert into testinsert (teststring)
	Select 'Successfully inserted a string'</pre><p>[/codesyntax]</p>
<p>Now, I had forgotten to mention this but it is very critical to the proper testing of this routine.  The objects created were created by a different user than the TestRW account we created.  Once the objects are created, then we MUST login to the Database Server with the new login and we must run the queries from that user account.  To recap &#8211; grant permissions and object creation are done from an account other than TestRW.  Running the test queries is done through the TestRW account.  (For ease of testing, you may also want to grant access to the db_datareader role on the TestRW user.</p>
<p>The results of running that simple Insert statement should yield the following result.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/10/error.jpg"><img loading="lazy" class="alignnone size-full wp-image-807" title="error" src="http://jasonbrimhall.info/wp-content/uploads/2010/10/error.jpg" alt="" width="671" height="88" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/10/error.jpg 671w, https://jasonbrimhall.info/wp-content/uploads/2010/10/error-300x39.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>So we know that the permissions are working but that the stored procedure is circumventing those explicit permissions.</p>
<h3>Conclusion</h3>
<p>Well, this is not actually a failure.  This is by design.  This is called implicit permissions.  If I am going through the trouble of granting execute permissions on a stored procedure to a specific user, then the system interprets that as the stored proc permissions override any explicitly set permissions.  Is there a way around this?  You could setup triggers on a table to prevent this from happening or you could remove the execute permissions for that user on each proc.  I also think this helps to underscore the importance of not just granting execute to all stored procedures in a database to a user.  This simply over-permissions that user and they may be able to do more than you wish for them to do.  Another option is to add code to each stored procedure that would check for group memberships and error out if the user is a member of the denydatawriter role (for instance).  This would be very similar to the way that MS prevents users from executing certain system stored procs from being executed by users who do not have adequate permissions.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=803" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/10/05/its-implied/">It’s Implied</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/10/05/its-implied/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQLSat 54</title>
		<link>https://jasonbrimhall.info/2010/10/01/sqlsat-54/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlsat-54</link>
					<comments>https://jasonbrimhall.info/2010/10/01/sqlsat-54/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 01 Oct 2010 20:33:41 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[SQLSat]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=794</guid>

					<description><![CDATA[<p>Wow, I have really been kinda slow in the blog department for a couple of weeks now.  I have a few things in queue that i will be letting out within the next week. I [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/10/01/sqlsat-54/">SQLSat 54</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Wow, I have really been kinda slow in the blog department for a couple of weeks now.  I have a few things in queue that i will be letting out within the next week.</p>
<p>I got notice today that I have a presentation on the slate for SQL Saturday #54 &#8211; woohoo.  I was honestly unsure of whether I would be able to present.  I was hopeful but this is a new venture for me.  I hope to get to meet some of you at SQL Saturday 54.</p>
<p>You can find more info on it <a href="http://www.sqlsaturday.com/54/eventhome.aspx">here</a>.  You should be able to read my little blurb for the presentation as well as find a bit of a bio about me there.</p>
<p>BTW, I am a bit stoked to be able to do this in the community.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=794" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/10/01/sqlsat-54/">SQLSat 54</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/10/01/sqlsat-54/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Tuesday Indexes and Blobs</title>
		<link>https://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-tuesday-indexes-and-blobs</link>
					<comments>https://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 15 Sep 2010 01:27:43 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=785</guid>

					<description><![CDATA[<p>How does one find what columns were LOB columns in the database.  I knew I had some past blog posts about various aspects of LOBs, but I had never broken it down to find the columns in the LOB.  Even better was that I wanted to know what columns were in what index that were also a BLOB.</p>
The post <a href="https://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/">TSQL Tuesday Indexes and Blobs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Woohoo &#8211; chugga chugga chugga chugga &#8211; woo woo.  <a href="http://michaeljswart.com/?p=844"><img loading="lazy" class="alignright size-full wp-image-786" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/09/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>The train is pulling into town once again for another installment in the TSQLTuesday Blog party.  Michael Swart is hosting and has asked us to post something ado about indexes.</p>
<h3>What to do What to do</h3>
<p>I thought long and hard about the topic this month.  I really wanted to discuss something that would be of use.  I also wanted to talk about something that may not have been covered by somebody else.  The topic of indexes and combination of blog entries this month should be comprehensive and covering in many aspects of Indexes.  We all know that there are Clustered Indexes and Non-clustered indexes, and then the other subtypes of indexes that I am sure have been covered by others in this party.</p>
<p>Then it hit me.  One day while helping in the forums I ran across a post requesting information about how to find what columns were LOB columns in the database.  I knew I had some past blog posts about various aspects of LOBs, but I had never broken it down to find the columns in the LOB.  Even better was that I wanted to know what columns were in what index that were also a BLOB.  Oooohh, spine tingling idea &#8211; I could cover Blob Index Columns.</p>
<h3>Restore from Backup</h3>
<p>Not really, but every once in a while we have to dig back in the backups to recover data from the past.  I had to pull up an article from the past in order to get to the script that would benefit me in this venture.</p>
<p>Before I go to lengths to post that script, let&#8217;s start with the script that was provided as a response to that initial question.  This is a straight-forward script that provides the answer to the question posed.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT OBJECT_NAME(c.object_id), c.name, t.name 
  FROM sys.columns c 
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
  WHERE t.name IN ('text','ntext','image','xml') 
    OR (t.name IN ('varchar','nvarchar','varbinary') AND c.max_length = -1)
    And OBJECTPROPERTY(c.object_id,'ismsshipped') = 0</pre><p>And here is the script that I thought could prove useful for this situation:</p><pre class="urvanov-syntax-highlighter-plain-tag">drop table #indstats

CREATE TABLE #indstats (
	indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,database_id BIGINT
	,Object_id BIGINT
	,index_id BIGINT
	,IndexSizeMB DECIMAL(16,1)
)

INSERT INTO #indstats (database_id,object_id,index_id,IndexSizeMB)
	SELECT database_id,object_id,index_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,object_id,index_id
;

Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,p.object_id
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL) 
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And a.data_pages &amp;gt; 0
		--And filegroup_name(a.data_space_id) = 'Primary'
Union
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,p.object_id
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL) 
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0</pre><p>That script can be found in my post <a href="http://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/">here</a>.</p>
<p>With that script in hand I figured a few short customizations could prove useful to help find the additional column info.  Now, I must admit, this is still a work in progress for which I want to tune it and tidy up the script substantially &#8211; where possible.  My point for now is the concept of using it to retrieve the indexed columns that are blobs and to see that extra detail about it.</p>
<p>I am going to make a few modifications that include adding a CTE, as well as adding the following snippet to both sides of the union, as well as a few additional columns.</p><pre class="urvanov-syntax-highlighter-plain-tag">Left Outer Join sys.index_columns ic
			On i.index_id = ic.index_id
			And i.object_id = ic.object_id
		Left Outer Join sys.columns c
			On ic.object_id = c.object_id
			And ic.column_id = c.column_id</pre><p>This is what I came up with:</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #indstats (
	indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,database_id BIGINT
	,Object_id BIGINT
	,index_id BIGINT
	,IndexSizeMB DECIMAL(16,1)
)

INSERT INTO #indstats (database_id,object_id,index_id,IndexSizeMB)
	SELECT database_id,object_id,index_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,object_id,index_id
;

With LOBCols as (
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,p.object_id
	,IndexName = i.name
	,ColumnName = c.name
	,c.column_id
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL) 
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
		Left Outer Join sys.index_columns ic
			On i.index_id = ic.index_id
			And i.object_id = ic.object_id
		Left Outer Join sys.columns c
			On ic.object_id = c.object_id
			And ic.column_id = c.column_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And a.data_pages &amp;gt; 0
		--And filegroup_name(a.data_space_id) = 'Primary'
Union
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,p.object_id
	,IndexName = i.name
	,ColumnName = c.name
	,c.column_id
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL) 
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
		Left Outer Join sys.index_columns ic
			On i.index_id = ic.index_id
			And i.object_id = ic.object_id
		Left Outer Join sys.columns c
			On ic.object_id = c.object_id
			And ic.column_id = c.column_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0

)

Select L.column_id,L.FileGroupName,L.TableName,L.IndexName,L.ColumnName,L.LOBUsedPages,L.LOBTotalPages,L.LOBDataSizeMB,L.IndexSizeMB
		,L.UserRequests,L.LastUpdate,L.RatioRequestsToUpdates,L.AllocUnitType,t.name
	From LOBCols L
		Inner Join sys.columns c
			On c.object_id = L.object_id
			And c.column_id = L.column_id
		Inner Join sys.types t
			On t.user_type_id = c.user_type_id
	Order By L.TableName asc,L.AllocUnitType</pre><p>This script will not return as many rows as the first script shared.  That should be an indicator that not all LOB columns are in an index.  Here we are looking for those that may be causing an extra performance impact due to the inclusion in an index.  It is always good to know what is going on in a database.  Something like this is very helpful for the newly hired DBA when trying to get to understand the databases which need to be supported.  This is also helpful when the need is to document a database.  This script may also spit out multiple rows for the same column in the same index.  This is due to that column being split into two different allocation unit types.  I feel this is good to know as well.</p>
<p>Here we can see just a small sample of the output from this script.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/09/queryresults.jpg"><img loading="lazy" class="alignleft size-full wp-image-787" title="queryresults" src="http://jasonbrimhall.info/wp-content/uploads/2010/09/queryresults.jpg" alt="" width="857" height="54" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/09/queryresults.jpg 857w, https://jasonbrimhall.info/wp-content/uploads/2010/09/queryresults-300x18.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px" /></a></p>
<p>This little snippet is from a CRM database, and you can see that the clustered index in this image has three columns in it that are BLOBS and they are all three being stored as an LOB_Data allocation unit.</p>
<p><strong>Conclusion</strong></p>
<p>Even though this was a quick and dirty entry on the topic, there is much to be gained from the little insight this script can provide.  I would recommend that people find out what indexes are holding that LOB data.  It&#8217;s better to know than to not know.</p>
<p>And I go by Indexes &#8211; not indices.  Indices for me represent more of a financial term than a logical lookup term.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=785" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/">TSQL Tuesday Indexes and Blobs</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/09/14/tsql-tuesday-indexes-and-blobs/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQLSaturday SLC 2010</title>
		<link>https://jasonbrimhall.info/2010/09/01/sqlsaturday-slc-2010/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sqlsaturday-slc-2010</link>
					<comments>https://jasonbrimhall.info/2010/09/01/sqlsaturday-slc-2010/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 01 Sep 2010 14:00:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Speaking]]></category>
		<category><![CDATA[SQLSat]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=772</guid>

					<description><![CDATA[<p>Well, I have taken another plunge.  I finally got around to submitting a session for SQL Saturday Salt Lake City 2010 (Web &#124; #sqlsat54 ).  I had been planning on doing this since it was [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/09/01/sqlsaturday-slc-2010/">SQLSaturday SLC 2010</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Well, I have taken another plunge.  I finally got around to submitting a session for SQL Saturday Salt Lake City 2010 (<a href="http://sqlsaturday.com/54/eventhome.aspx">Web </a>| #sqlsat54 ).  I had been planning on doing this since it was announced through the grapevine.  The delay for submitting the first session really came down to a bit of confidence in writing an abstract on the topic.  Writing abstracts is new territory for me.  I plan on improving in this domain, thus will need to submit a few more abstracts to various different events.  That said &#8211; SQL Sat SLC will be the first but not the last.  If you check out the website for SQL Saturday 54, you will see that my topic is one of those that brings agony to many DBA&#8217;s &#8211; Documentation.  As I said in the abstract, I hope to share some scripts to help simplify some of the documentation tasks.</p>
<p>I am looking forward to this event and hope to see some of you there.  Here&#8217;s to hoping my presentation will be selected.  In the meantime, I will be working on another abstract for a second topic to present at SQLSat54.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=772" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/09/01/sqlsaturday-slc-2010/">SQLSaturday SLC 2010</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/09/01/sqlsaturday-slc-2010/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Memory</title>
		<link>https://jasonbrimhall.info/2010/08/25/memory/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=memory</link>
					<comments>https://jasonbrimhall.info/2010/08/25/memory/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 25 Aug 2010 15:30:12 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[server settings]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=756</guid>

					<description><![CDATA[<p>Not a sound from the pavement Have you ever come across a SQL query that used to run faster?  Has that query just recently begun to run considerably slower? I just ran into one of [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/25/memory/">Memory</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>Not a sound from the pavement</h3>
<h3><span style="font-weight: normal; font-size: 13px;">Have you ever come across a SQL query that used to run faster?  Has that query just recently begun to run considerably slower?</span></h3>
<p><span style="font-weight: normal; font-size: 13px;">I just ran into one of those situations.  I had a query that should have been running in seven minutes or less (string parsing nearly 4 million records).  When it started running much slower, I decided to pull out some monitoring scripts and start checking a few things on the server.  I wanted to check for the usual suspects first and then find what was causing the alleged problems.</span></p>
<h3><span style="font-weight: normal; font-size: 13px;"> </span>If you touch me you&#8217;ll understand what happiness is</h3>
<p>When problems arise in a database, it is good to have a toolbelt of scripts available to help in quickly &#8220;touching&#8221; / assessing the problem.  In this case, I first turned to the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select percent_complete, estimated_completion_time, cpu_time, total_elapsed_time, reads,writes,logical_reads
	,session_id,scheduler_id,start_time,status 
	from sys.dm_exec_requests
go</pre><p>[/codesyntax]</p>
<p>My goal from this query is to quickly assess if the query is still progressing.  For the query in question, I should see that the query is steadily writing to the database.  I can also see really quick the status of the query.  Running this in conjunction with sp_who2 is helpful in identifying, at a high level, issues that may be occurring.  Another possible query to run in this kind of situation would be <a href="http://sqlblog.com/blogs/adam_machanic/archive/tags/who+is+active/default.aspx" class="broken_link">sp_whoisactive</a> by Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" class="broken_link">Blog </a>| <a href="http://twitter.com/AdamMachanic">Twitter</a>), or the who2 script I wrote about <a href="http://www.sqlservercentral.com/articles/sp_who2/70222/">here</a>.  The idea, is to get a quick glimpse at this point to see if there is a potential issue.</p>
<p>In this case, I found nothing alarming or noteworthy from the initial queries.  Other queries could be run at this point to try and determine if there is a pressure point somewhere on your resources (memory, cpu).  I decided to take a quick glance at task manager just to get a quick visual of the server.  Looking at it, I saw that I had no memory available &#8211; all 96 GB were in use.  I proceeded to check the max memory setting on SQL server.  As expected, it was still set at the default setting.  A little further prodding showed that the SQL server process was consuming most of the memory available to the server.</p>
<p><img loading="lazy" class="alignleft size-full wp-image-757" title="SettingsEffect" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/SettingsEffect.jpg" alt="" width="356" height="90" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/08/SettingsEffect.jpg 356w, https://jasonbrimhall.info/wp-content/uploads/2010/08/SettingsEffect-300x75.jpg 300w" sizes="(max-width: 356px) 85vw, 356px" /></p>
<p>I changed the max memory to 64GB and immediately saw improvements.  In task manager the effect could also be seen, as shown to in the pic to the left.  NO server restart or service restart was required.  This change took effect immediately.  The poorly performing query was soon performing back to normal.</p>
<h3>I can smile at the old days</h3>
<p>This should serve as a reminder to check your server settings from time to time and ensure that they are appropriately set.  This little change (and that was the only change), allowed my query to return to normal processing which was &gt; 5 times faster than the problem range.  Happy troubleshooting.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=756" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/25/memory/">Memory</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/25/memory/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Sp_whoAmI</title>
		<link>https://jasonbrimhall.info/2010/08/24/sp_whoami/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sp_whoami</link>
					<comments>https://jasonbrimhall.info/2010/08/24/sp_whoami/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 24 Aug 2010 22:06:54 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Blogging]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=759</guid>

					<description><![CDATA[<p>I was doing a little catching up on some blog reading today and came across a new post from Adam Machanic (Blog &#124; Twitter).  The post is titled Who Are You and is asking for [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/24/sp_whoami/">Sp_whoAmI</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I was doing a little catching up on some blog reading today and came across a new post from Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" class="broken_link">Blog </a>| <a href="http://twitter.com/AdamMachanic">Twitter</a>).  The post is titled <a href="http://sqlblog.com/blogs/adam_machanic/archive/2010/08/17/who-are-you.aspx" class="broken_link">Who Are You</a> and is asking for input from the readers.  Quite frankly, I think it is a great idea.  Adam is asking for people to do a little stand up and tell everybody a thing or two about themselves.  He wanted that info left in the comments, but I thought it would be better to write a post on the topic and link back to it.</p>
<p>First things first.  Why is this a good idea?  Well, it helps to know the readers as Adam said.  There truly is a nice bit of satisfaction when somebody leaves a comment on your blog.  It is even better when you feel like you know that person.  Better yet is to know that there are people you know that are reading your blog &#8211; whether or not they comment.  There are plenty of people (judging from the comments) that Adam knows and that read his blog but may not leave a lot of comments.  It is also really helpful to know the interests of the readers and try to put out some stuff that may be of interest to them.  I see this being of particular help when there is a little writers block.</p>
<p>What about me?</p>
<p>My name is Jason Brimhall and I have been doing database stuff for a little over 10 years.  My current title at my employer is Database Architect.  I am more than a database architect &#8211; I get to wear many hats.  I get to do the Architect stuff, administrator stuff, warehouse stuff, and occasionally I get to write a stored proc or two.  I have been blogging now for just about 9 months.  I have administered 4500+ servers as well as 1TB+ databases.  I have worked on SQL 6.5 &#8211; SQL 2008 as well as a spattering of Oracle and MySQL (don&#8217;t quiz me on those).  I live in Las Vegas and am the Vice President of the local Users Group (<a href="http://www.sssolv.com" class="broken_link">Web </a>| <a href="https://twitter.com/search?q=S3OLV">Twitter </a>) (which reminds me that I need to get that UG twitter account notice out).  Outside of work, I like to spend time with my children as well as play basketball and run.</p>
<p>Edit:  I forgot to tell you what my twitter handle is&#8230;<a href="http://twitter.com/sqlrnnr">@sqlrnnr</a></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=759" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/24/sp_whoami/">Sp_whoAmI</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/24/sp_whoami/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Star Struck</title>
		<link>https://jasonbrimhall.info/2010/08/17/star-struck/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=star-struck</link>
					<comments>https://jasonbrimhall.info/2010/08/17/star-struck/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 17 Aug 2010 21:32:00 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=735</guid>

					<description><![CDATA[<p>Have you ever run into an error and been puzzled as to why that error occurred? Recently I have been working on a project to backfill a development and QA environment.  These environments are essential [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/17/star-struck/">Star Struck</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3><a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/gold-star3.jpg"><img loading="lazy" class="alignright size-full wp-image-737" title="gold-star3" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/gold-star3.jpg" alt="" width="336" height="336" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/08/gold-star3.jpg 800w, https://jasonbrimhall.info/wp-content/uploads/2010/08/gold-star3-150x150.jpg 150w, https://jasonbrimhall.info/wp-content/uploads/2010/08/gold-star3-300x300.jpg 300w" sizes="(max-width: 336px) 85vw, 336px" /></a><span style="font-weight: normal; font-size: 13px;">Have you ever run into an error and been puzzled as to why that error occurred?</span></h3>
<p>Recently I have been working on a project to backfill a development and QA environment.  These environments are essential in any database environment to help ensure the production database will continue to work after changes have been made.  These environments existed once upon a time but had been sorely neglected and process was not followed.</p>
<p>For this process, I am using some software to help generate diff scripts between the environments.  Once the script has been generated I will execute that script in the appropriate environment (DEV or QA).  I am doing this process for all tables, procs, views, and functions.  This is also done iteratively database by database.</p>
<h3>All-Stars</h3>
<p>While performing this routine, occasionally an error might be encountered due to an order of processing that may need to be performed.  In cases such as that, I would typically alter my process to account for this error.  Usually that is not an issue if the tables are first created, then the views, and then the procs and functions.  Other times, the create/alter script must be evaluated to determine what is causing the failure.</p>
<p>One of these failures that caused me a lot of angst was producing the following error in  a few stored procedures.</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;span style=&quot;color: #ff0000;&quot;&gt;Msg 205, Level 16, State 1, Line 4
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.&lt;/span&gt;</pre><p>That error message is fair enough to evaluate.  Based on the error one should expect that the stored procedure contains one of those keywords.  I picked a stored procedure out of the mix that was generating this error and checked the code for it.  Looking through the entire proc, there was no such instance of those keywords.  This was temporarily puzzling.  I continued to investigate and found that there was a view being used in that stored procedure.  I decided to double-check the view and see if it might be the cause.  Inside the view I see something like the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select *
from dbo.Table1 with (nolock)
where AccrueThruDate between '2010/01/31' and '2010/12/31'
UNION ALL
select *
from dbo.Table2 with (nolock)
where AccrueThruDate between '2010/01/31' and '2010/12/31'
UNION ALL
select *
from Db2.dbo.Table1 with (nolock)</pre><p>[/codesyntax]</p>
<p>At first sight, I see a few things I don&#8217;t like but didn&#8217;t immediately pick up on the table in the third select.  I saw the table name and moved on thinking it must be ok.  Then I decided to sanity check more precisely what was there and saw that it was pointing to the same table name in a different database.  Low and behold in the other database the table did not have the same number of columns.  These tables are all pretty wide at 100+ columns each.  The designer thought that every single column from each of these tables was needed and decided to take a shortcut.  Had the columns been explicitly named, I would have gotten a more useful error message, in this case, such as the following:</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;span style=&quot;color: #ff0000;&quot;&gt;Msg 207, Level 16, State 1, Line 3
Invalid column name 'Column102'.&lt;/span&gt;</pre><p>That little change in message could save time when troubleshooting a problem such as what I have described.  Granted, it does not tell me which database or table but at least I know which column is missing.  This is one little reason why I like to explicitly name the columns in my Select statements.</p>
<p>Another reason why I like to use the column names instead of a &#8221; * &#8221; is that I have seen queries improve dramatically in performance speed when compared.  In this little case, even though there are 100+ columns from each table to list out and all of the data would be returned from each of these, I see a 700 ms improvement in return time on just the &#8220;top 1000&#8221; records.  When I bump that up to the full result set required by the view, I tire of waiting for the results from either query.  Both are terrificly slow (takes longer than 15 minutes to return the full result set).</p>
<p><strong>But But But&#8230;</strong><br />
<a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/goldstar.jpg"><img loading="lazy" class="alignleft size-full wp-image-744" title="goldstar" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/goldstar.jpg" alt="" width="259" height="194" /></a>So why do people use Select * in their code?  It is a lot easier to type than having to type all of the column names.  Because it is fewer keystrokes it would also save time when writing code.  Many times, we may also use it when trying to get a glimpse of the system really quick.  It is also oftentimes used when doing a demo.</p>
<p>Should it be used?  There are cases for using that kind of code such as in an &#8220;if exists&#8221; block.  There are cases where the performance impact is minimal or just as good as listing the columns so it is fine.  I use it when I am trying to do a quick and dirty statement while troubleshooting.  I don&#8217;t like to put that into code to be consumed by applications or reused.  I like to know exactly what columns are being returned by my queries and I don&#8217;t feel it necessary to return more data than necessary (and consequently consume more resources).</p>
<p>What are some cases you have found a select * to be better than explicitly naming the columns?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=735" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/17/star-struck/">Star Struck</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/17/star-struck/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TSQL Tuesday 009 Roundup</title>
		<link>https://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tsql-tuesday-009-roundup</link>
					<comments>https://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 13 Aug 2010 00:31:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=720</guid>

					<description><![CDATA[<p>T-SQL Tuesday #009: Beach Time I hope you enjoyed your time in the sun with your toes in the sand.  We are wrapping up this vacation with a little recap on what we learned.  There [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/">TSQL Tuesday 009 Roundup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h1>T-SQL Tuesday #009: Beach Time</h1>
<p><a href="http://jasonbrimhall.info/2010/08/03/t-sql-tuesday-009-beach-time/"><img loading="lazy" class="size-full wp-image-587 alignleft" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/06/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>I hope you enjoyed your time in the sun with your toes in the sand.  We are wrapping up this vacation with a little recap on what we learned.  There were some similarities and some differences amongst our vacationers.</p>
<p>I enjoyed reading the comments made this month and the methods employed by each person that came along for the party.</p>
<p>Without further ado, in order of submission, here is what people had to say.</p>
<h4>Pinal Dave (<a href="http://blog.sqlauthority.com/">Blog</a> | <a href="http://twitter.com/pinaldave">Twitter</a> | <a href="http://blog.sqlauthority.com/2010/08/10/sql-server-best-practices-for-dba-before-taking-vacation/">TSQLTuesday9</a>)</h4>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/superhero.jpg"><img loading="lazy" class="alignright size-medium wp-image-725" title="superhero" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/superhero-212x300.jpg" alt="" width="191" height="270" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/08/superhero-212x300.jpg 212w, https://jasonbrimhall.info/wp-content/uploads/2010/08/superhero.jpg 400w" sizes="(max-width: 191px) 85vw, 191px" /></a>Pinal teaches us that we need to stop thinking about the job when on vacation and that we don&#8217;t need to be a superhero.  He also tells us that we should keep the phone on, but use restraint.</p>
<h4>Rob Farley (<a href="http://sqlblog.com/blogs/rob_farley/default.aspx" class="broken_link">Blog </a>| <a href="http://twitter.com/rob_farley">Twitter</a> | <a href="http://sqlblog.com/blogs/rob_farley/archive/2010/08/10/managing-to-get-time-away.aspx" class="broken_link">TSQLTuesday9</a>)</h4>
<p>Rob states that “Just because you’re necessary doesn’t mean you’re important.”  He has a very good point with that.  Nobody should horde all of the information about his/her job, project or process.  Learn to share your knowledge and you will learn more in the process!!</p>
<h4>Robert Davis (<a href="http://www.sqlsoldier.com/wp/" class="broken_link">Blog </a>| <a href="http://twitter.com/SQLSoldier">Twitter </a>| <a href="http://www.sqlsoldier.com/wp/sqlserver/tsqltuesday9beachtime" class="broken_link">TSQLTuesday9</a>)</h4>
<p>SQLSoldier has let it slip that he is working on some top secret project at work away from work.  What I like about this is that he is getting beach time by doing this other project.  It is not necessarily vacation but it is a change and there is a change in project focus for the week long stints that he will be doing this.</p>
<h4>Benjamin Nevarez (<a href="http://www.benjaminnevarez.com/">Blog </a>| <a href="http://twitter.com/BenNevarez">Twitter </a>| <a href="http://www.benjaminnevarez.com/2010/08/back-from-vacation/">TSQLTuesday9</a>)</h4>
<p>Ben just returned from vacation in time to participate this month.  Ben takes us on vacation with him by sharing some of his pictures.  I think a good way to get ready for vacation is to busy one&#8217;s self looking at vacation spots. <img src="https://s.w.org/images/core/emoji/13.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h4>Jeremy Carter (<a href="http://jeremycarterblog.com/" class="broken_link">Blog </a>| Twitter | <a href="https://web.archive.org/web/20160428225025/http://jeremycarterblog.com/2010/08/tsql-tuesday-beach-time/">TSQLTuesday9</a>)</h4>
<p>Jeremy brings up some solid points.  One of the best points is the change management piece.  Jeremy also touches on the hero mentality a bit.  I really like his closing sentence: &#8220;The real hero of the day will be missed because they are a true asset, not because the world stopped in their absence.&#8221;</p>
<h4>Bob Pusateri (<a href="http://www.bobpusateri.com/">Blog </a>| <a href="http://twitter.com/SQLBob">Twitter </a>| <a href="http://www.bobpusateri.com/archive/2010/08/t-sql-tuesday-009-beach-time/">TSQLTuesday9</a>)</h4>
<p>Bob teaches us in his entry this month that he spends a lot of time in a science museum.  When he is out at the museum he will Delegate a team member to fill in for certain projects or aspects of work.  Bob keeps it pretty simple &#8211; Documentation and Delegation are his keys to a successful vacation.</p>
<h4>Steve Jones (<a href="http://stevejonesssc.blogspot.com/">Blog </a>| <a href="http://twitter.com/way0utwest">Twitter </a>| <a href="http://stevejonesssc.blogspot.com/2010/08/t-sql-tuesday-beach-time.html">TSQLTuesday9</a>)</h4>
<p>Steve, with his heavy packing and all, makes sure he communicates a lot before he leaves the office.  It is fair to be available for a true emergency.  The person to whom you delegated your responsibilities should be the one to escalate to you.  Trust them to understand what a true emergency is (and hopefully you won&#8217;t have to train them further on the topic when you return).</p>
<h4>Andy Lohn (<a href="https://web.archive.org/web/20181102022841/http://sqlfeatherandquill.com/">Blog </a>| <a href="http://twitter.com/sqlquill">Twitter </a>| <a href="https://web.archive.org/web/20150909234255/http://www.sqlfeatherandquill.com/2010/08/10/t-sql-tuesday-009-an-ounce-of-prevention/">TSQLTuesday9</a>)</h4>
<p>There are a few things that are new in this blog from SQLQuill.  One, I like his avatar &#8211; pretty cool.  His blog theme looks good &#8211; the theme works well for his site.  Anyway, back to the topic.  When Andy leaves for vacation he sends a meeting request to the team.  No reminder is set, just a meeting request that shows the time as available.  Then he blocks it out on his calendar as out of the office with an out of office rule set.  Then he goes through his lists and checks off everything that needs to be done (knowledge transfer, tasks, etc).</p>
<h4>Stef Bauer (<a href="http://stef-bauer.com/">Blog </a>| <a href="http://twitter.com/stefbauer">Twitter </a>| <a href="http://stef-bauer.com/2010/08/10/t-sql-tuesday-009-%e2%80%93-beach-time/">TSQLTuesday9</a>)</h4>
<p>Stef was also on vacation as the announcement went out for this months meme.    Stef works in a small shop and is available to the manager should an emergency arise.  Stef recommends a technology silence in order to enjoy vacation &#8211; thus twitter goes bye-bye.  Stef also double-checks processes prior to leaving to make sure everything is in tip-top shape.</p>
<h4>Josh Feierman (<a href="http://awanderingmind.com/">Blog </a>| <a href="http://twitter.com/awanderingmind">Twitter </a>| <a href="https://web.archive.org/web/20150711002128/http://awanderingmind.com:80/2010/08/10/its-vacation-prep-time-t-sql-tuesday-009/">TSQLTuesday9</a>)</h4>
<p>This is the first ever TSQLTuesday post by Josh.  Welcome to the party Josh!  Josh believes in project visibility (that&#8217;s a good thing).  With everything up to date in sharepoint, he feels a lot more comfortable taking off for vacation.  He also makes certain that he is unreachable via email.  He will turn off email synchronization to the Blackberry when on vacation.  I am strongly considering doing the same.</p>
<h4>John Racer (<a href="http://speeddba.com/">Blog </a>| <a href="http://twitter.com/speedracer">Twitter </a>| <a href="http://speeddba.com/t-sql-tuesday-009-time-off.html" class="broken_link">TSQLTuesday9</a>)</h4>
<p>John believes that a system that requires constant hand-holding by the dba are incorrectly designed.  There are tools available for making your life easier &#8211; use them.  Systems should be built with ease of maintenance in mind.  This is a valuable asset.  Just because it took you 5000 lines of TSQL to accomplish what somebody could do in 10 lines, does not make your code any better or valuable to the company.</p>
<h4>My Entry (<a href="http://twitter.com/sqlrnnr">Twitter</a> | <a href="http://jasonbrimhall.info/2010/08/10/r-r/">TSQLTuesday9</a>)</h4>
<p>I talk about some recent experiences around trying to get away from work for an extended weekend.  I had a funeral to attend that interfered with deadlines for work that I needed to meet.  I also talk about Beach Time as a state of mind rather than a destination or even being vacation.</p>
<h3>That&#8217;s a Wrap</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/lettuce-wrap4.jpg"><img loading="lazy" class="size-medium wp-image-723 alignleft" title="lettuce-wrap4" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/lettuce-wrap4-300x200.jpg" alt="" width="300" height="200" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/08/lettuce-wrap4-300x200.jpg 300w, https://jasonbrimhall.info/wp-content/uploads/2010/08/lettuce-wrap4-1024x682.jpg 1024w, https://jasonbrimhall.info/wp-content/uploads/2010/08/lettuce-wrap4.jpg 1536w" sizes="(max-width: 300px) 85vw, 300px" /></a>I hope you enjoyed this vacation filled week.  Let us all wrap things up with a feast in honor of a good vacation and a toast to many great accomplishments.</p>
<p>I hope to see you all next month for another round of TSQL Tuesday!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=720" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/">TSQL Tuesday 009 Roundup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/12/tsql-tuesday-009-roundup/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>R &#038; R</title>
		<link>https://jasonbrimhall.info/2010/08/10/r-r/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=r-r</link>
					<comments>https://jasonbrimhall.info/2010/08/10/r-r/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 10 Aug 2010 23:12:02 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=698</guid>

					<description><![CDATA[<p>It is once again time for the blog party known as TSQL Tuesday.  I am hosting this month and wanted to also participate.  The theme is &#8220;Beach Time&#8221; and this is TSQL Tuesday #9.  Why [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/10/r-r/">R & R</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/2010/08/03/t-sql-tuesday-009-beach-time/"><img loading="lazy" class="size-full wp-image-587 alignleft" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/06/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>It is once again time for the blog party known as TSQL Tuesday.  I am hosting this month and wanted to also participate.  The theme is &#8220;Beach Time&#8221; and this is TSQL Tuesday #9.  Why did I choose this theme?  There are a few reasons for it.  1.)  There are numerous people in the community getting ready, or who have recently, to change jobs.  2.)  I was on the tail end of a mini-vacation / long weekend when I got the invite to host.  3.)  To be able to take a day off for that long weekend, I wanted to make sure the loose ends were wrapped up so I would not need to work over the weekend.  4.)  The song lyrics I mentioned in the <a href="http://jasonbrimhall.info/2010/08/03/t-sql-tuesday-009-beach-time/">Theme announcement</a>, were stuck in my head and reminded me of vacation.  For this post, I want to cover what Beach Time means for me and some of the things I did recently in order to get a little R &amp; R.</p>
<h3>Beach Time</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/beach_01.jpg"><img loading="lazy" class="alignright size-full wp-image-699" title="beach_01" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/beach_01.jpg" alt="" width="259" height="194" /></a>Beach Time means having peace of mind, for me.  I can&#8217;t go on vacation if there is doubt or concern about any of my projects (work, home, financial).  So, in order for me to truly have a vacation &#8211; Beach Time comes first.</p>
<p>I find it completely useless to go on vacation if I am going to be checking email or project statuses every 10 minutes.  There is no rest or relaxation in doing those things while I am supposed to be doing something else.  Vacation should be fun and enjoyable.  Thus, if I am to enjoy vacation, I need to do a few extra things in the office prior to leaving.</p>
<h3>Going the Distance</h3>
<p>When Adam (<a href="http://sqlblog.com/blogs/adam_machanic/archive/2009/11/30/invitation-to-participate-in-t-sql-tuesday-001-date-time-tricks.aspx" class="broken_link">Blog</a> | <a href="http://twitter.com/AdamMachanic">Twitter</a>) asked me to host, I was on my little mini-vacation.  In order to get to that vacation, I had to prep myself and work for the one day absence.  I had to make sure I had built up a few things.<br />
<a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/Sand-Castle.jpg"><img loading="lazy" class="alignleft size-full wp-image-703" title="Sand-Castle" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/Sand-Castle.jpg" alt="" width="450" height="298" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/08/Sand-Castle.jpg 500w, https://jasonbrimhall.info/wp-content/uploads/2010/08/Sand-Castle-300x198.jpg 300w" sizes="(max-width: 450px) 85vw, 450px" /></a><br />
<strong> 1.  Confidence</strong></p>
<p><strong>2.  Skills</strong></p>
<p><strong>3.  Processes</strong></p>
<p><strong>4.  Automation</strong></p>
<p>Let me explain what I mean by each of these items.  I am sure it seems a bit odd to hear that Confidence and skills must be built right before one takes a vacation.</p>
<p>I needed to build <strong>confidence</strong> in processes and systems that were recently deployed.  This required more testing and monitoring of the processes to ensure all would be well.  I worked on transferring some knowledge of specific items to team-members.  I wanted to make sure they knew what they were doing.  I also wanted them to know that they knew what they were doing and that they could do it.  This goes hand in hand in number one, all while building <strong>skills</strong>.  With the massive changes that we were wrapping up (complete network migration), some new <strong>processes</strong> needed to be developed and implemented.  We are using new technology and software and the old methods just didn&#8217;t work anymore or were unreliable in the first place.</p>
<p>In addition to these items, there was the work tasks that needed to be completed.  Since we were trying to finish the project by the weekend that I needed to be out of the office, I needed to have my tasks done that much sooner.  This meant a willingness to work longer days (ok, continue working longer days)  and try to work a little faster without making any mistakes.  This also required some increased communication and visibility with regards to the tasks and effort.</p>
<p>I also had a feeling that something might come up on the day I was scheduled to be out of the office.  I suspected that there may be a user request for a data dump.  In preparation for this, I also built an SSIS package that would handle the most common requests from this particular user.  The package would be able to handle various different types from this user based on common requirements I had seen in the past.  A user would only need to change a few input variables and run the package.  The result as a simplified version of a process I had been using for that particular user and was something that I could hand off to a team-mate.  This <strong>automation</strong> made it so less time could be spent on teaching the team-mate what may be needed, and permits one to just execute the package.  This was something that I wanted to get done at some point in the future anyway, but this was a very good time to introduce it into the mix.  Overall time savings of this implementation could be a couple of hours a week.  Overall savings in thought process, memory tracing, note tracing, and stress was substantial.  It was well worth the day or so that I put into creating it.</p>
<h3>&#8220;Toes in the Water&#8230;&#8221;</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/08/chairs-on-beach.jpg"><img loading="lazy" class="alignright size-full wp-image-710" title="chairs-on-beach" src="http://jasonbrimhall.info/wp-content/uploads/2010/08/chairs-on-beach.jpg" alt="" width="251" height="200" /></a>Now that I have been able to accomplish some very good stuff by putting in the extra effort, I can relax a bit.  By planning ahead, communicating, working extra, and training &#8211; I can have that Beach Time that I wanted.  I was able to have the peace of mind needed to really take a vacation.  Taking a break from work sometimes requires going the extra mile just before the break happens, but it is well worth it if you don&#8217;t have to think about work at all while on vacation.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=698" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/10/r-r/">R & R</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/10/r-r/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>August SSSOLV Reminder</title>
		<link>https://jasonbrimhall.info/2010/08/10/august-sssolv-reminder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=august-sssolv-reminder</link>
					<comments>https://jasonbrimhall.info/2010/08/10/august-sssolv-reminder/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 10 Aug 2010 15:30:34 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=696</guid>

					<description><![CDATA[<p>Just another reminder about the Las Vegas User Group meeting coming up on August 12th. Here is the info: The S3OLV UG will be meeting Thursday August 12 at 6:00.  Come and enjoy the fun [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/08/10/august-sssolv-reminder/">August SSSOLV Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Just another reminder about the Las Vegas User Group meeting coming up on August 12th.</p>
<h3>Here is the info:</h3>
<p>The S3OLV UG will be meeting Thursday August 12 at 6:00.  Come and enjoy the fun and socialize with local SQL Server enthusiasts.</p>
<div>
<p>This month we will be hosting another LiveMeeting presentation.  We have the pleasure of listening to Grant Fritchey (<a href="http://twitter.com/GFritchey">Twitter</a> | <a href="http://scarydba.wordpress.com/">Blog</a>).  Grant is a SQL Server MVP and has written a couple of <a href="http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&amp;field-keywords=grant+fritchey&amp;x=0&amp;y=0&amp;ih=5_0_1_0_0_0_0_0_0_1.84_219&amp;fsc=5">books</a> on SQL Server Execution Plans.</p>
<p>The livemeeting can be joined at the following location:</p>
<p>LiveMeeting Attendees (https://www.livemeeting.com/cc/UserGroups/join?id=BSSZD6&amp;role=attend)</p>
<p>For those that plan on attending in person, we will be meeting at the same place &#8211; The Learning Center at 777 Raindbow.</p>
<p>We hope to see you there!!</p>
</div>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=696" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/08/10/august-sssolv-reminder/">August SSSOLV Reminder</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/08/10/august-sssolv-reminder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Defensive Db Programming Chapter 03</title>
		<link>https://jasonbrimhall.info/2010/07/26/defensive-db-programming-chapter-03/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defensive-db-programming-chapter-03</link>
					<comments>https://jasonbrimhall.info/2010/07/26/defensive-db-programming-chapter-03/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 26 Jul 2010 12:30:39 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=673</guid>

					<description><![CDATA[<p>Chapter 3 of the Defensive Database Programming Book by Alex Kuznetsov teaches us about how to &#8220;survive&#8221; changes to database objects.  Alex brings to light how simple changes to the underlying schema could be damaging [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/26/defensive-db-programming-chapter-03/">Defensive Db Programming Chapter 03</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Chapter 3 of the Defensive Database Programming Book by Alex Kuznetsov teaches us about how to &#8220;survive&#8221; changes to database objects.  Alex brings to light how simple changes to the underlying schema could be damaging to performance and accuracy of the code that touches the objects to be changed.</p>
<p>Three main focal points are discussed in this chapter.</p>
<ul>
<li>Changes to the Primary or Unique Keys</li>
<li>Changes to Stored Procedure signatures</li>
<li>Changes to Columns</li>
</ul>
<p>A key lesson is outlined in subtle terms at the beginning of the chapter.  If you have assumptions based on any of the above focal points, then those assumptions <strong><span style="text-decoration: underline;">must be documented</span></strong>!  If this information or the assumptions are not documented, how can the changes made be properly tested?  All assumptions must be tested and validated.  If changes are made to the schema, any prior assumptions for the code touching the affected column, key, or signature must be reassessed, documented and validated.</p>
<p>Alex also brings up a a good point about Unit testing and how that can help speed things along when validating these assumptions.  This also provides a gateway to a level of documentation for those assumptions.</p>
<p>In addition to Unit testing, Alex suggests a counter measure of using @@ROWCOUNT to ensure that only 1 row is updated in update procedures.  If the rowcount is different than the expected 1 row, then the transaction is rolled back.  In his samples for this, Alex uses IF blocks.  I would have liked to see a TRY&#8230;Catch implementation as well.  This method is less preferable to the Unit test.  The reasons for that are explained in the chapter &#8211; have a read and find out why.</p>
<p>Further along in this chapter we learn another important lesson and a good practice to be using.  When calling a stored procedure that has parameters, use the parameter names when calling the stored procedure.</p>
<p>From here, there are several other recommendations in this chapter worth reading.  We see more best practices and further discussion elaborating particular methods over other methods.  There are several good lessons to be learned from this chapter and to find the rest of them &#8211; you will have to read it.  Enjoy reading!</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=673" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/26/defensive-db-programming-chapter-03/">Defensive Db Programming Chapter 03</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/26/defensive-db-programming-chapter-03/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A little Dance with SSIS and Informix</title>
		<link>https://jasonbrimhall.info/2010/07/23/a-little-dance-with-ssis-and-informix/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-little-dance-with-ssis-and-informix</link>
					<comments>https://jasonbrimhall.info/2010/07/23/a-little-dance-with-ssis-and-informix/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 23 Jul 2010 22:05:37 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[DTS]]></category>
		<category><![CDATA[Informix]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=662</guid>

					<description><![CDATA[<p>Not too many moons ago I embarked on porting some servers over from SQL 2000 to SQL 2008.  On some of these SQL 2000 servers, we had numerous DTS packages performing various ETL functions.  One [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/23/a-little-dance-with-ssis-and-informix/">A little Dance with SSIS and Informix</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Not too many moons ago I embarked on porting some servers over from SQL 2000 to SQL 2008.  On some of these SQL 2000 servers, we had numerous DTS packages performing various ETL functions.  One of these jobs interacted with an Informix database.  On the old server, an ODBC driver had been installed permitting a connection be created between the two servers.</p>
<h3>Thunderstruck</h3>
<p>Something that we did not flesh out prior to the migration was this particular setup.  One would think that would not be that big of a deal considering the ODBC connection information was still present on the old server.  Sure we could find most of the pertinent information to recreate this connection.  One vital piece of information was missing &#8211; the password for the user account in the Informix system.  FANTASTIC!  This raises a dilemma.  We could easily change the password so we could recreate this connection.  If we change the password, then we run the chance of breaking something else.  We could also create a new account for this one process and ensure we document the userid, process, and password.  However, that does not resolve the problem of not knowing the password for this other account used by some processes.</p>
<p>Decisions, decisions, decisions.  We chose to potentially break some unknown process.  We reset the password.  Woohoo!!  We were finally able to successfully recreate the ODBC connection on the new server.  We were also able to confirm that it worked on both the new and old server.  Prior to changing the password, we could not confirm that the connection was properly created on the old server since the password must be re-entered in the System DSN in order to test.  By changing the password (and putting it safely into the vault) we were able to improve our documentation as well as confirm that the process could work.</p>
<h3>Verify</h3>
<p>Along the lines of my entry for TSQL Tuesday this month where I talked about the necessity to <a href="http://jasonbrimhall.info/2010/07/13/gettin-skewled/">Observe and Report</a>, I had to go back and learn how the old DTS package worked to ensure I could make it work in the new environment.  I quickly ran into a new series of problems in my efforts to study this package.</p>
<h4>64 v. 32</h4>
<p>The server was 64 bit, the ODBC client was 64 bit, and dts packages were 32 bit.  I knew this from previous experience but had become engrossed with trying to do too much that I overlooked it.  Not too big of a problem, I will convert it to SSIS.  I plan on converting all of the packages to SSIS over time, the schedule just got moved up for this package.  That was really a no-brainer.</p>
<h3>Opening BIDS</h3>
<p style="text-align: left;">Creating an ODBC connection to Informix that can be consumed by the SSIS package is a little different.  Again, this was not too difficult of a problem to overcome.  You can create an ODBC connection in BIDS by creating a New Connection from the Connection Managers region.  From the Add SSIS Connection Manager window, there is an option for &#8220;ODBC.&#8221;   Select this option.</p>
<p><img loading="lazy" title="NewODBCConnection" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/NewODBCConnection.jpg" alt="" width="414" height="454" /></p>
<p>Another option to create this connection is to Create a new Ado.Net connection.  From the new Ado.Net connection Manager, you need to select Odbc Data Provider from the &#8220;Provider&#8221; drop down menu at the top.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/adonetODBC.png"><img loading="lazy" class="alignnone size-full wp-image-667" title="adonetODBC" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/adonetODBC.png" alt="" width="513" height="534" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/07/adonetODBC.png 513w, https://jasonbrimhall.info/wp-content/uploads/2010/07/adonetODBC-288x300.png 288w" sizes="(max-width: 513px) 85vw, 513px" /></a></p>
<p>Once you have decided which method to use to create an ODBC connection you would need to specify the appropriate settings such as the user name, password, and dsn.  This worked well for a bit.  This method quickly ran me into an Informix problem.</p>
<h4>Doesn&#8217;t play well with others</h4>
<p>I was able to test my connection successfully initially.  On the first attempt to pull data from the connection though, I started getting an error message in SSIS.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/multipleconnshare.png"><img loading="lazy" title="multipleconnshare" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/multipleconnshare.png" alt="" width="611" height="137" /></a></p>
<p>I started wondering if this was an SSIS problem.  I wanted to confirm what the overall impact of this error was so I tried to test it from the DTS package as well.  Guess what &#8211; same thing.  What about testing from the ODBC DSN?  I got the same thing there too.  From there I proceeded to the Internet to see what else I could learn about this problem.  Well, as it turns out &#8211; this seems to be a common occurrence where Informix is involved.  The resolution for this is to modify the SQLHOSTS file on the Informix database server.  One needs to change the nettype from Shared Memory to a Network connection (TCP/IP).  This was a solution that would have required involving our vendor.  Thus while waiting for a time when they could assist, I decided to try other things.</p>
<h4>Missing Link</h4>
<p>Since I didn&#8217;t like the need to pass a password to a connection manager in SSIS or for multiple people to need to know this account and password being used to connect to the Informix DB, and since I also needed to find a way around this shared memory problem, I decided to try an alternative method.  I would create a linked server that would use the ODBC settings I had created for the DSN just created.</p>
<p>For this linked server, I provided the setting for the user and password of the remote server.  The user has read only on the remote Informix server.  By employing this, I can ensure that the password will not need to be known by anybody outside of the DBA group.  The password will also not need to be stored in any files for connecting to this Informix server &#8211; I see it as being more secure and protected than the previous setup.</p>
<p>With connecting to Informix via a linked server, I am using the OPENQUERY method.  I saw this as a method used / recommended by several people who have come across a similar need.  To use the OPENQUERY, one needs to use a query similar to the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select * from OPENQUERY 
		(LinkedServerName, 
			'SELECT * FROM sometable')</pre><p>[/codesyntax]</p>
<p>I recommend changing the &#8216;Select *&#8217; on the interior select statement to be specific columns.  As a sidebar, I ran into problems with this query initially due to using a top in the interior select statement.  OPENQUERY does not like the top, and thus I removed it and it works flawlessly.</p>
<h4>One more for the road&#8230;</h4>
<p>Once I got the OPENQUERY statement working to satisfaction in SSMS, I tried to use the OPENQUERY directly from an execute SQL task.  This attempt failed miserably.  The task was unable to connect through the linked server and thus bombed.  With that, I tried a different avenue once again.</p>
<p>I decided that the query needed to be put into a stored procedure.  I would test from there since I knew that the query worked from within SSMS.  I had three tables and three tasks in the DTS package that required the same process.  So for all three, I combined them into a single stored procedure.  The basic functionality was to simply extract the data through OPENQUERY and then dump the data into a staging table.  In the new world, that means I will be replacing six steps from the DTS package with one step in the SSIS package.</p>
<p>With all of the code in the proc necessary for these tasks, I proceeded with testing.  Testing was very encouraging and worked rather well.  That was testing from within SSMS.  How would it fare from BIDS?  That was the next step.  I created an Execute SQL task with an ado.net connection to my database and set the IsQueryStoredProcedure property to True.  I then ran this step individually and it worked just as expected.  Now I can finally finish translating the rest of this DTS package into SSIS and get this ETL process back up and running.</p>
<h3>In the End</h3>
<p>When all was said and done, I took a DTS package and converted it to SSIS 2008.  The package works better now than it did in the old world.  I simplified the package from 18 steps down to 6.  This package in the end probably does not need to be run from SSIS.  All of the steps are Execute SQL tasks and no use of the SSIS transformations are employed.  That is something that can be looked into changing at a later date.  For now, I will leave it as is since it also serves as an example for some of the team on how to upgrade a DTS package to SSIS.  They needed something to help familiarize themselves to the product &#8211;  and this serves that purpose.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=662" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/23/a-little-dance-with-ssis-and-informix/">A little Dance with SSIS and Informix</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/23/a-little-dance-with-ssis-and-informix/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Defensive Db Programming Chapter 02</title>
		<link>https://jasonbrimhall.info/2010/07/14/defensive-db-programming-chapter-02/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defensive-db-programming-chapter-02</link>
					<comments>https://jasonbrimhall.info/2010/07/14/defensive-db-programming-chapter-02/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 15 Jul 2010 01:15:05 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Books]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=657</guid>

					<description><![CDATA[<p>This is the review of the second chapter of the book Defensive Database Programming.  The title of this chapter is &#8220;Code Vulnerabilities Due to SQL Server MisConceptions.&#8221; This chapter examines three common misconceptions: WHERE clause [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/14/defensive-db-programming-chapter-02/">Defensive Db Programming Chapter 02</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is the review of the second chapter of the book Defensive Database Programming.  The title of this chapter is &#8220;Code Vulnerabilities Due to SQL Server MisConceptions.&#8221;</p>
<p>This chapter examines three common misconceptions:</p>
<div id="_mcePaste">
<ol>
<li>WHERE clause conditions will always be evaluated in the same order</li>
<li>SET and SELECT always change the values of variables</li>
<li>Data will be returned in some &#8220;natural order&#8221;</li>
</ol>
</div>
<p>Another misconception is that DBAs and Developers know these misconceptions.  As frequently as we are reminded of these things, it is not enough and we need to continue to remind ourselves about these misconceptions as well as teach others the same thing.</p>
<p>As was shown in the first chapter, we have been given some samples of how these statements are proved invalid.  Due to the proof of the misconception, we are also given some alternatives to code against them.</p>
<p>This is the kind of information that should be required reading for anybody who needs to write a stored procedure or a script that touches a database.  Even for seasoned professionals, the samples laid out in this chapter need to be examined.  I think most of us could find an application in our current environments where we could apply these principles right away.</p>
<p>In this chapter we also see another use for the &#8220;Numbers&#8221; table.  This chapter is also rather easy to read and written well.  I hope you enjoy reading it as well.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=657" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/14/defensive-db-programming-chapter-02/">Defensive Db Programming Chapter 02</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/14/defensive-db-programming-chapter-02/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Gettin&#8217; Skewled</title>
		<link>https://jasonbrimhall.info/2010/07/13/gettin-skewled/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gettin-skewled</link>
					<comments>https://jasonbrimhall.info/2010/07/13/gettin-skewled/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 13 Jul 2010 16:24:06 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=635</guid>

					<description><![CDATA[<p>Observe and Report This month we get to frolic in our memories of school days.  Thanks to HeadMaster Robert Davis (Blog &#124; @SQLSoldier), we are entreated to a little detention while we figure out how [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/13/gettin-skewled/">Gettin’ Skewled</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h2><a href="http://www.sqlservercentral.com/blogs/robert_davis/archive/2010/07/04/T_2D00_SQL-Tuesday-008-Gettin-Schooled.aspx"><img loading="lazy" class="size-full wp-image-587 alignleft" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/06/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>Observe and Report</h2>
<p>This month we get to frolic in our memories of school days.  Thanks to HeadMaster Robert Davis (<a href="http://www.sqlservercentral.com/blogs/robert_davis/default.aspx">Blog</a> |<a href="http://twitter.com/SQLSoldier"> @SQLSoldier</a>), we are entreated to a little detention while we figure out how we best learn.  I don&#8217;t have any idea how to learn in detention so I skipped out and headed to a more convenient place to think about learning.  I won&#8217;t share that location since I don&#8217;t want the truant officers showing up to haul me back to detention hall.</p>
<p>We were given a whole lot of restriction on this topic.  I am going to take a much broader approach with the topic since the topic applies to so many facets of being a SQL professional.  I will try to entreat each of the options that were listed out in the <a href="http://www.sqlservercentral.com/blogs/robert_davis/archive/2010/07/04/T_2D00_SQL-Tuesday-008-Gettin-Schooled.aspx">TSQL2SDAY</a> invite by Robert Davis.</p>
<ol>
<li>How do you learn?</li>
<li>How do you teach?</li>
<li>What are you learning or teaching?</li>
<li>Coup de gras post &#8211; Learn something new and Tell us about it.</li>
</ol>
<p>I will try to answer each of these topics through one common theme with two principles &#8220;Observe and Report.&#8221;</p>
<h3>How do you learn?</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/back_to_school.gif"><img loading="lazy" class="alignright size-full wp-image-643" title="back_to_school" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/back_to_school.gif" alt="" width="358" height="312" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/07/back_to_school.gif 358w, https://jasonbrimhall.info/wp-content/uploads/2010/07/back_to_school-300x261.gif 300w" sizes="(max-width: 358px) 85vw, 358px" /></a>For me, learning actually comes in a lot of ways.  I think the most prevalent is through observing others.  Frankly, the term observing could be taken rather broadly or more acutely.  I think of observe more literally in the sense that I witness something and pay close attention to it.  At least I try to pay close attention.</p>
<p>Some times I may see something that appears like it is a good thing to know, but only witnessed it from a cursory perspective.  When that happens, I try to re-encounter the event so I can observe it more specifically.</p>
<p>When there is close attention to detail for such an event, it sticks just a little better.  To make the learning more permanent, one needs to practice that observation.  (It is starting to sound a little like the scientific process here.)  After I have observed such an event that requires my attention, I will try to implement it in some fashion.  Reproduce whatever it was supposed to be learned.  This will breed a higher level of consistency as well as knowledge permanence.  To bring us to the next level and internalize the learning even further, one must teach the principle or at least share it so somebody else can learn.</p>
<h3>How do you teach?</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/teach.jpg"><img loading="lazy" class="alignleft size-full wp-image-644" title="teach" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/teach.jpg" alt="" width="295" height="295" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/07/teach.jpg 295w, https://jasonbrimhall.info/wp-content/uploads/2010/07/teach-150x150.jpg 150w" sizes="(max-width: 295px) 85vw, 295px" /></a>The answer to this question is simple &#8211; <em>It Depends</em>.  The situation should help to determine the method.  Sometimes it may just require that a demonstration be performed.  Others may require explaining the lesson to be learned in various forms.  While yet others may require that some hands-on time be done.</p>
<p>I was taught that you don&#8217;t truly know the topic until you have taught it.  It is when you teach or share with somebody else that you internalize the lesson the most.  That isn&#8217;t to say that you know the topic perfectly and can answer any and all questions on the topic.</p>
<blockquote><p><em>Who dares to teach must never cease to learn.  ~John Cotton Dana</em></p></blockquote>
<p>As an IT professional / DBA, it is imperative that one learn all the time.  When one gives back by teaching others what s/he has learned &#8211; one learns considerable more and also becomes more respected.  The skills that pertain to being a DBA become more apparent and one is able to perform the duties associated with the job more easily.</p>
<h3>What am I learning or teaching?</h3>
<p>Now the questions start to get a bit harder.  It is a bit harder, in that most of what I learn professionally these days I try to share what I learn on my blog &#8211; at least what I learn professionally.  A lot of what I am learning lately is merely along the lines of troubleshooting Windows 7 to make things work as they should.  There have been quite a few nuances learned.  Now if only I could learn how to fix the USB keyboard bug in Win 7.</p>
<p>One of the best things I learned recently involved playtime with my children.  This is one of those things that can be learned over and over again.  It involves the little things that can help bond a relationship between parent and child.  A little game of hide and seek with one child soon turned into a rambunctious festival with my three youngest children and wife.  We played hide-n-seek for hours inside the house.  The kids were the  seekers all day and the adults hid.  It was a lot of fun and we got to teach the kids what family is about.  They enjoyed it and I hope they will do the same with their children some day.</p>
<p>I would also like to add that I am learning how much more important it is to Observe and Report.  These particular principles apply in so many facets of life.  Whether it be family, religion, politics or business &#8211; there is always a requirement that Observations be made and that you Report back to somebody about something.  Reporting is such a key component of everyday life and is often-times over-looked.  The method for reporting is not as important as the fact that it be done.  Reporting could be as simple as recounting a story to a friend or family member.  Reporting can often times be used as the method to teach or vice-versa.  Take the play time example I shared.  I will write that in my journal and then read some day in the future.  That will spark a memory and then I will talk with my children about it and spark a memory for them.  This story will serve as a form of report (as will the journal and blog entry now) that can be used many times over to teach this lesson.</p>
<h3>Coup de Gras</h3>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/holy_grail.jpg"><img loading="lazy" class="alignright size-full wp-image-649" title="holy_grail" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/holy_grail.jpg" alt="" width="370" height="204" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/07/holy_grail.jpg 660w, https://jasonbrimhall.info/wp-content/uploads/2010/07/holy_grail-300x165.jpg 300w" sizes="(max-width: 370px) 85vw, 370px" /></a>There are learning opportunities everywhere.  A very recent reminder of this was a business lesson I just learned from the NBA.  Many may of heard of the <a href="http://www.nba.com/cavaliers/news/gilbert_letter_100708.html">recent backlash by the owner</a> of the Cleveland Cavaliers concerning recent free-agent signings.  The lesson is that emotions can get the better of people in certain circumstances but we must learn to reign them in and behave professionally when in public.  Despite the belittlement and lack of integrity by one side, the other was able to maintain a good amount of integrity.</p>
<p>I am learning that learning is not just formalized education in a classroom or in specific settings.  There are things to be learned from all aspects of life.  This can be learned if only a little observation is used.  When you learn something, return and report what you have learned to a friend, family member, co-worker or somebody that could use it.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=635" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/13/gettin-skewled/">Gettin’ Skewled</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/13/gettin-skewled/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>July SSSOLV UG Meeting</title>
		<link>https://jasonbrimhall.info/2010/07/07/july-sssolv-ug-meeting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=july-sssolv-ug-meeting</link>
					<comments>https://jasonbrimhall.info/2010/07/07/july-sssolv-ug-meeting/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 07 Jul 2010 21:58:28 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=626</guid>

					<description><![CDATA[<p>This is really late notice &#8211; apologies in advance. We will be holding the LV UG meeting July 8th at the same time and same place as usual. 777 N Rainbow, Ste 250. 6:30 PM [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/07/july-sssolv-ug-meeting/">July SSSOLV UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This is really late notice &#8211; apologies in advance.</p>
<p>We will be holding the LV UG meeting July 8th at the same time and same place as usual.</p>
<p><strong>777 N Rainbow, Ste 250.</strong></p>
<p><strong>6:30 PM (officially when we start the presentation)</strong></p>
<p><strong>6:00 PM for meet and greet</strong></p>
<p><strong><span style="font-weight: normal;">This month we will have Jack Corbett present to us.  Jack is the Co-Pres of OPASS.  He will be presenting on an &#8220;Introduction to Profiler.&#8221;  We are making this meeting available via livemeeting.  This will be the first time for our little UG to use LiveMeeting for the presentation, so bear with us if any kinks arise.</span></strong></p>
<p><strong><span style="font-weight: normal;">You can join online with us at <span style="color: #00ff00;"><strong><span style="color: #339966;">https://www.livemeeting.com/cc/usergroups/join?id=47Z8F6&amp;role=attend</span></strong></span></span></strong></p>
<p><span style="color: #00ff00;"><span style="color: #000000;">The meeting will still be conducted in the traditional manner as well.  All who wish to attend in person, are plenty welcome.  Hope to see you there.</span></span></p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=626" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/07/july-sssolv-ug-meeting/">July SSSOLV UG Meeting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/07/july-sssolv-ug-meeting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL 2008 DTS</title>
		<link>https://jasonbrimhall.info/2010/07/07/sql-2008-dts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-2008-dts</link>
					<comments>https://jasonbrimhall.info/2010/07/07/sql-2008-dts/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 07 Jul 2010 20:15:08 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[DTS]]></category>
		<category><![CDATA[SSIS]]></category>
		<category><![CDATA[Win7]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=608</guid>

					<description><![CDATA[<p>It&#8217;s a Bird&#8230; No, not really.   It&#8217;s just Windows 7.   I have recently upgraded to Windows 7.  I took the roundabout trip to do that going from Server 2003 to Windows XP and [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/07/sql-2008-dts/">SQL 2008 DTS</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<h3>It&#8217;s a Bird&#8230;</h3>
<p>No, not really.   It&#8217;s just Windows 7.   I have recently upgraded to Windows 7.  I took the roundabout trip to do that going from Server 2003 to Windows XP and then finally up to Windows 7.  Having never used Windows Vista, there were several nuances to learn.  Most of those nuances had to deal with security and how to disable this or that setting or run programs with elevated privileges.  Pretty straight forward for much of it, once you figure out that it needs to be done.</p>
<p>One area that caused me a lot of grief trying to get it to work correctly was in the realm of dealing with DTS packages.  I browsed several webpages trying to find the fix for this particular issue.  Most of the fixes were explicitly designed to fix the issue in a 64 bit environment.   I am running a 32 bit environment.  I must admit that the packages run just fine from the 64 bit servers that are running SQL 2008 on Windows 2008 R2.  However, running the package or editing the package from my laptop only resulted in the following error message.</p>
<blockquote><p>SQL Server 2000 DTS Designer components are required to edit DTS packages.  Install the special Web download, &#8220;SQL Server 2000 DTS Designer Components&#8221; to use this feature. (Microsoft.SqlServer.DtsObjectExplorerUI)</p></blockquote>
<h3>Nitty Gritty</h3>
<p>Let&#8217;s quickly delve into everything that I did in an effort to fix this.  Let&#8217;s start with the most comprehensive resource I found on the issue.  You can find that resource <a href="http://blogs.msdn.com/b/sqlserverfaq/archive/2009/07/09/error-sql-server-2000-dts-designer-components-are-required-to-edit-dts-packages-install-the-special-web-download-sql-server-2000-dts-designer-components-to-use-this-feature-microsoft-sqlserver-dtsobjectexplorerui-ssms.aspx">here</a>.  The information presented in that blog post is more informative than the information listed in <a href="http://msdn.microsoft.com/en-us/library/ms143755.aspx">MSDN</a> on the same topic.  I will outline the steps from the first article noted.</p>
<ol>
<li>Install Sql Server 2000 DTS Designer Components
<ol>
<li>Download from <a href="https://web.archive.org/web/20100731013620/http://www.microsoft.com:80/downloads/details.aspx?FamilyID=536fd7d5-013f-49bc-9fc7-77dede4bb075&amp;displaylang=en">here</a>.  This is the most current version as of the writing of this article.</li>
</ol>
</li>
<li>Install Sql Server 2005 backward compatibility components
<ol>
<li>Download from <a href="https://web.archive.org/web/20100828121522/http://www.microsoft.com:80/downloads/details.aspx?FamilyID=c6c3e9ef-ba29-4a43-8d69-a2bed18fe73c&amp;DisplayLang=en">here</a>.  This is the most current version as of the writing of this article.</li>
<li>This is available with the installation media for SQL Server 2008.</li>
</ol>
</li>
<li>Verify your path environment variable.  The SQL 2000 path should be placed in the string prior to the SQL 2008 variable.  As a sample, this is what mine looks like.
<ol>
<li>%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\80\Tools\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\binn\;C:\Program Files\Microsoft SQL Server\90\DTS\Binn\;C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\</li>
<li>You can access the environment variables in Windows 7 by: Right Click My Computer  -&gt; Properties -&gt; Click Advanced System Settings -&gt; Click Environment Variables -&gt; Scroll to &#8220;Path&#8221; -&gt; Click &#8220;Path&#8221; and then click Edit&#8230;</li>
</ol>
</li>
<li>SSMS &#8211; Manually Copy Files
<ol>
<li>DLL Files to copy
<ol>
<li>semsfc.dll, sqlgui.dll, sqlsvc.dll</li>
</ol>
</li>
<li>Source
<ol>
<li>%Program Files%\Microsoft SQL Server\80\Tools\Binn\</li>
</ol>
</li>
<li>Destination
<ol>
<li>%Program Files%\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\</li>
<li>%Program Files%\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\%lang_id%\</li>
</ol>
</li>
<li>RLL Files to copy
<ol>
<li>semsfc.rll, sqlgui.rll, sqlsvc.rll</li>
</ol>
</li>
<li>Source
<ol>
<li>%Program Files%\Microsoft SQL Server\80\Tools\Binn\Resources\%lang_id%\</li>
</ol>
</li>
<li>Destination
<ol>
<li>%Program Files%\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Resources<strong>\</strong>%lang_id%<strong>\</strong></li>
</ol>
</li>
</ol>
</li>
<li>BIDS Manually Copy Files
<ol>
<li>DLL Files to copy
<ol>
<li>semsfc.dll, sqlgui.dll, sqlsvc.dll</li>
</ol>
</li>
<li>Source
<ol>
<li>%Program Files%\Microsoft SQL Server\80\Tools\Binn\</li>
</ol>
</li>
<li>Destination
<ol>
<li>%Program Files%\Microsoft Visual Studio 9.0\Common7\IDE\</li>
</ol>
</li>
<li>RLL Files to copy
<ol>
<li>semsfc.rll, sqlgui.rll, sqlsvc.rll</li>
</ol>
</li>
<li>Source
<ol>
<li>%Program Files%\Microsoft SQL Server\80\Tools\Binn\Resources\%lang_id%\</li>
</ol>
</li>
<li>Destination
<ol>
<li>%Program Files%\Microsoft Visual Studio 9.0\Common7\IDE\Resources<strong>\%lang_id%</strong>\
<ol>
<li>I had to create the Resources Subdirectory</li>
</ol>
</li>
<li>%Program Files%\Microsoft Visual Studio 9.0\Common7\IDE\<strong>%lang_id%</strong>\</li>
</ol>
</li>
</ol>
</li>
<li>The last step was not applicable in my case since the file version already matched
<ol>
<li>stardds.dll File version: 2000.80.2151.0</li>
</ol>
</li>
</ol>
<p>That is the basic gist of what needs to be done in most cases to resolve this issue.  In my Step 5 (BIDS manual copy), I would note that this should be a required step.  I skipped that step numerous times due to it appearing to be &#8220;optional.&#8221;  I was not attempting to edit these packages in BIDS, but directly from SSMS.  It was only after trying to edit the package in BIDS that I found the next key to the issue I was experiencing.  Up to that point, I had installed, uninstalled, rebooted and repaired the install numerous times after several different minor tweaks.  Only after the next step did it finally start working.</p>
<p>I must also share that I attempted starting SSMS as administrator and also tried to launch it in compatibility mode.  I had to verify that neither of those options was the root of my problem.</p>
<h3>Auction Block</h3>
<p>I think it is necessary to describe how to edit a DTS package from BIDS prior to explaining what the fix was that got this working for me.  You don&#8217;t just open a DTS package directly in BIDS.  In my case, the DTS packages are not structured storage files either &#8211; I have them stored in SQL Server.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/ExecDTSTask.jpg"><img loading="lazy" class="alignleft size-full wp-image-612" title="ExecDTSTask" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/ExecDTSTask.jpg" alt="" width="206" height="281" /></a>In BIDS, there is a Control Flow item called &#8220;Execute DTS 2000 Package Task.&#8221;  Drag this item into the work area in BIDS.   This Control flow task is illustrated in the image to the left as the last option in the image.  This task will give you the ability to edit a SQL 2000 dts package from within SSIS.  With the task showing in your workspace, open the properties for the task so you can configure it appropriately for the dts package you wish to edit.</p>
<p>After setting the properties for the package that you desire to edit or even simply view, click the Edit Package&#8230; button.  It is at this point that I was able to get a further clue into what was causing the inability to open packages from within SSMS.  At this point I got the following error message.</p>
<blockquote>
<p style="padding-left: 30px;">Error: Attempted to read or write protected memory. This is often an indication that other memory is corrupt (Microsoft Visual Studio).</p>
</blockquote>
<p>Could this be my big break in the case?</p>
<h3>Hard Hat and Hammer</h3>
<p>With this piece of information, I have a tool and I can get to work fixing the problem.  Admittedly, at this point, I did not know that this was the root of the problem for me.  Quickly I race to my search engine du jour in an effort of finding any relevant information on this new error message.  I soon discover that this issue is one that existed with Windows Vista and appears occasionally in Windows 7.  The cause of this problem has its roots in Data Execution Prevention.  It would seem to only be an issue if your CPU supports DEP.   To determine if you have DEP enabled, you will need to check the Advanced Settings of your computer properties.  You can get there as explained earlier when checking the path.  Only this time you will need to click the Settings&#8230; button rather than the Environment Variables button.  Once inside of the settings, you will notice that there is a tab called &#8220;Data Execution Prevention&#8221; &#8211; click on this tab.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/07/disabledDEP.jpg"><img loading="lazy" class="alignleft size-medium wp-image-619" title="disabledDEP" src="http://jasonbrimhall.info/wp-content/uploads/2010/07/disabledDEP-208x300.jpg" alt="" width="208" height="300" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/07/disabledDEP-208x300.jpg 208w, https://jasonbrimhall.info/wp-content/uploads/2010/07/disabledDEP.jpg 367w" sizes="(max-width: 208px) 85vw, 208px" /></a>Once you have reached the DEP tab, you will be able to tell if DEP is enabled or not by the display on the screen and not by the settings selected.  To the left, I have a screenshot of how mine looks at present.  All settings are greyed out and I see a message at the bottom explaining that I must enable it via a command prompt utility called bcdedit.exe.</p>
<p>If DEP is enabled, the options will not be greyed out.  You may also see a note at the bottom that says &#8220;Your computer&#8217;s processor supports hardware-based DEP.&#8221;  You will also have a choice at the top between two settings, both of which are &#8220;ON.&#8221;</p>
<p>Just as you must enable this setting through the command prompt, you must also disable it through the command prompt.  Once disabled or enabled, you must reboot the computer for the settings to take effect.  So how does one disable this setting?  Here is the command to disable that setting.</p>
<p><strong><em>bcdedit.exe /set {current} nx AlwaysOff</em></strong></p>
<p>Should you decide you need to re-enable the DEP setting, you can use the following command.</p>
<p><strong><em><strong><em>bcdedit.exe /set {current} nx AlwaysOn</em></strong></em></strong></p>
<p><em>Disclaimer: I recommend you have a good backup of your system first.  It is also advisable to have a system restore point and understand how to boot into safe mode.  Adjusting settings like this may have an effect that is undesirable (such as unable to boot into windows).  You can read more about DEP from <a href="http://support.microsoft.com/kb/875352">Microsoft</a></em><em>.</em></p>
<h3>I got my Toes in the Water&#8230;</h3>
<p>As you can already see, I have disabled DEP on my laptop.  After disabling DEP and having rebooted, I am now able to edit a DTS package from within BIDS.  Great! Can I open a package from within SSMS though?  I open SSMS and attempt to open a package and it does indeed work.  This is just one more tool in the troubleshooting arsenal.  Happily I can now open and edit packages from both tools.  This will permit me to take the time I need to upgrade those packages to SSIS and do it correctly.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=608" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/07/sql-2008-dts/">SQL 2008 DTS</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/07/sql-2008-dts/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Q2 Goal Review</title>
		<link>https://jasonbrimhall.info/2010/07/06/q2-goal-review/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=q2-goal-review</link>
					<comments>https://jasonbrimhall.info/2010/07/06/q2-goal-review/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 06 Jul 2010 17:07:27 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Goals]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=605</guid>

					<description><![CDATA[<p>As we close out the Second Quarter of 2010 it is time to review progress made on the Goals I set at the beginning of the year.  Just like the end of Q1, I think [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/07/06/q2-goal-review/">Q2 Goal Review</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>As we close out the Second Quarter of 2010 it is time to review progress made on the Goals I set at the beginning of the year.  Just like the end of Q1, I think I continue to make good progress.  Thus I will break down each of the goals that was established in that <a href="http://jasonbrimhall.info/?p=84">blog post</a> back in January.</p>
<p><strong>Start a Blog</strong></p>
<p>This has been covered pretty well.</p>
<p><strong>Implement a BI Solution</strong></p>
<p>I have made no further progress on this.  Despite that, I have been converting several dts packages into SSIS packages.  I also have numerous reports for SSRS that I need to implement.  Also, let&#8217;s throw out there that I have spent considerable time working on the COGNOS 7 platform over this past quarter.  I have had to troubleshoot various components from cube build to security to execution and report accuracy.  That doesn&#8217;t count as a BI solution, however, it should be noted that there is more BI experience being gained.  The purpose of this goal was to increase experience and knowledge with BI.  Albeit, the goal was designed to gain that experience in the Microsoft products.</p>
<p><strong>1 Technical Blog Post per Week</strong></p>
<p>This one is getting harder for me currently.  I am in the middle of some very big and high profile projects that have consumed a lot of my time.  I will be working harder at this goal over the upcoming quarter.  Despite that difficulty, I am still ahead of the goal by means of averages though I missed a technical post this last week.</p>
<p><strong>Attend 2010 Pass Summit</strong></p>
<p>I have not yet attended the summit, and can’t do that until November.  However, I have registered for the Summit and have every intention of attending this year.</p>
<p><strong>Present Once a Quarter (or 4 times)</strong></p>
<p>I continued to make measurable progress.  I only presented once this quarter.  On the flip-side, I have taken the lead in two of the three UG meetings.</p>
<p><strong>Write 2 Articles</strong></p>
<p>I can mark this goal as achieved at this point.  My second article was published recently and I have a few more that I am working on in queue currently.  I wrote a short blog on the publication of this article.</p>
<p><strong>Run Two Marathons</strong></p>
<p>I have not run a marathon yet this year, but that is fine.  I have laid out my schedule for running and have several planned for my typical race season coming up in the fall.</p>
<p>As for the less measurable goals, I think I am doing fine there as well.  I was assigned as VP to our PASS Users Group, I am on a subcommittee for Summit 2010, and I am actively involved with the community at SQLServerCentral.com.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=605" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/07/06/q2-goal-review/">Q2 Goal Review</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/07/06/q2-goal-review/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Declare Scalar Variable</title>
		<link>https://jasonbrimhall.info/2010/06/22/declare-scalar-variable/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=declare-scalar-variable</link>
					<comments>https://jasonbrimhall.info/2010/06/22/declare-scalar-variable/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 22 Jun 2010 19:03:21 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=601</guid>

					<description><![CDATA[<p>Lately I have been going through a bunch of maintenance style scripts and fixing them.  Along with fixing them, I have also been updating them to work more efficiently and to work in SQL 2008. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/06/22/declare-scalar-variable/">Declare Scalar Variable</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Lately I have been going through a bunch of maintenance style scripts and fixing them.  Along with fixing them, I have also been updating them to work more efficiently and to work in SQL 2008.  Most have been corrected / updated.  The most recent script I have been looking at is supposed to backup databases and delete old database backups from the fileshare based on parameters passed to the stored procedures from a table.  The backups are working as expected, the deletion of files is not working so well.</p>
<p>This will be just a short entry on some of the frustration involved with getting this script to work properly.  That frustration revolves around the title of the post.</p>
<h3>In the Beginning&#8230;</h3>
<p>The procedure that runs the backups is a modularized script.  The basic workings depend on bit operations / math.  Thus I can store multiple options for the backup job within a single field.  Some of these options are for compression, verify, and to delete the backup files.  Performing the bit math on the values stored in this particular field, I knew that my settings were correct and that various operations were supposed to be happening.  The logic inside the parent procedure was also correct to call the delete module.  Thus I figured the problem had to be inside that module.  So it is in the delete module that we will pick up.</p>
<p>Inside this delete module we have various operations to determine OS version, then loops to get file details, and to move this information from one temp table to another, and then ultimately a delete statement.  The delete statement is run iteratively for each file that matches certain criteria (most notably that the file is older than the retention specified).  Each action is then logged to a Log table.  Here is a snapshot of what the script does to find the file information.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">SET @SourceDirFOR = 'FOR %I IN (&quot;' + @SourceDir + @SourceFile + '&quot;) DO @ECHO %~nxtI'</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag">-- Start temp table population(s).
CREATE TABLE #_File_Details_01
	( Ident int IDENTITY(1,1)
	, Output varchar(512) )

	SELECT @Error = @@ERROR
	IF @Error != 0
		BEGIN
			INSERT INTO dbo.Process_Log
				VALUES (getdate(), @ProcessName, 'ERROR', CONVERT(varchar(15),@Error), 'Create table #_File_Details_01 failed.')
		END

INSERT INTO #_File_Details_01
	EXEC master..xp_cmdshell @SourceDirFOR --, no_output</pre><p>[/codesyntax]</p>
<p>I didn&#8217;t much like this as it was originally written but copied it to a new query window so that I could debug it outside of the proc.  When I copied it, I ended up with something like the following:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">&lt;div id=&quot;_mcePaste&quot;&gt;DECLARE @SourceDirFOR varchar(255)&lt;/div&gt;</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag">SET @SourceDirFOR = 'FOR %I IN (&quot;' + @SourceDir + @SourceFile + '&quot;) DO @ECHO %~nxtI'</pre><p></p><pre class="urvanov-syntax-highlighter-plain-tag">-- Start temp table population(s).
CREATE TABLE #_File_Details_01
	( Ident int IDENTITY(1,1)
	, Output varchar(512) )
go

INSERT INTO #_File_Details_01
	EXEC master..xp_cmdshell @SourceDirFOR --, no_output</pre><p>[/codesyntax]</p>
<h3>What the Heck¿</h3>
<p>I tried running that snippet of code and failed miserably.  Why?  I started receiving an error message and was stumped.  The error was that I must declare scalar variable @SourceDirFOR.  But I have that variable declared.  The size is an appropriate size, I can add a print statement and see that the variable is getting a value assigned to it.  So the problem must be inside the variable and the usage of the FOR Loop there.  In that case, I will just change it up and simplify this process a bit.  So let&#8217;s try the following in lieu of the SourceDirFor stuff.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">DECLARE @BackupServer varchar(128)
		,@BackupShare varchar(128)
		,@DBName		varchar(128)
		,@SourceDir	varchar(512)
		,@SourceFile	varchar(128)
		,@SQL		varchar(1024)
		,@SourceDir2	varchar(512)

Select @SourceDir = '\\' + @BackupServer + '\' + @BackupShare + '\' + @@SERVERNAME + '\Databases\' + @DBName + '\'
Select @SourceFile = @DBName + '_*.*'

CREATE TABLE #DirTree
	( Ident int IDENTITY(1,1)
	,DirFileName varchar(256)
	,Depth Bit
	, IsFile Bit)
go

 SELECT @SourceDir = @SourceDir+'\'
  WHERE RIGHT(@SourceDir,1)&amp;lt;&amp;gt;'\'

exec master.dbo.xp_DirTree @SourceDir2,1,1</pre><p>[/codesyntax]</p>
<p>Alright, I am still getting this error message.  Some research and frustration later, I will have checked the collation settings and checked to see what others have done.  None of it seemed to be matching.  What is going on?  (Mind you this was being done while tired and needing a break.)  Finally I came across <a href="http://www.sqlservercentral.com/Forums/Topic540627-338-1.aspx">something in a forum</a> (By Jeff Moden) that was similar to what I was doing so I checked the code provided there (up to the point of running the xp_dirtree) and ensuring case similarity (though collation was checked and case insensitive collation is being used).  Running that code yielded the exact results that I wanted.  What was the difference?  I compared the xp_dirtree command to mine, the table creation to mine, and the variable declaration to mine.  It was all the same &#8211; still getting different results.  This, btw, was being done on the same server in different connections.  The SQL Server version is 2008 sp1, and the OS is 2008 R2.  Finally, I yielded to verifying line by line the differences.  Here is the difference:</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #DirTree
	( Ident int IDENTITY(1,1)
	,DirFileName varchar(256)
	,Depth Bit
	, IsFile Bit)
go

-- versus

 CREATE TABLE #DirTree
(
        RowNum INT IDENTITY(1,1),
        Name   VARCHAR(256) PRIMARY KEY CLUSTERED, 
        Depth  BIT, 
        IsFile BIT
)</pre><p>[/codesyntax]</p>
<h3>Conclusion</h3>
<p>Do you see it?  One little &#8220;go&#8221; statement was the cause of all of my scalar variable problems.  I don&#8217;t know how I ended up with a go statement in my script in that spot, but I overlooked it several times.  That is a really simple fix.  I&#8217;m fine with the result though &#8211; the script works better now and I prefer the shorter xp_dirtree method.  The moral is that you should batch your statements, but you need to be careful where you place the &#8220;;&#8221; or &#8220;go&#8221; statements.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=601" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/06/22/declare-scalar-variable/">Declare Scalar Variable</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/06/22/declare-scalar-variable/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Data Compression</title>
		<link>https://jasonbrimhall.info/2010/06/08/data-compression/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=data-compression</link>
					<comments>https://jasonbrimhall.info/2010/06/08/data-compression/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 08 Jun 2010 16:33:07 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Compression]]></category>
		<category><![CDATA[SQL 2008]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=586</guid>

					<description><![CDATA[<p>I see database compression, as offered with SQL 2008, to be more like these file compression utilities than DriveSpace.  Data compression in SQL 2008 is not an all or none implementation.  You get to pick and choose what gets compressed.  That is a big time bonus for me.</p>
The post <a href="https://jasonbrimhall.info/2010/06/08/data-compression/">Data Compression</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>We have come to that time of month again &#8211; <strong>blog party</strong>.  This time, the party is hosted by Jorge Segarra (aka SQLChicken) (<a href="http://sqlchicken.com/">Blog</a> | <a href="http://twitter.com/sqlchicken">Twitter</a>).  <a href="http://jasonbrimhall.info/wp-content/uploads/2010/06/TSQL2sDay150x150.jpg"><img loading="lazy" class="size-full wp-image-587 alignleft" title="TSQL2sDay150x150" src="http://jasonbrimhall.info/wp-content/uploads/2010/06/TSQL2sDay150x150.jpg" alt="" width="150" height="150" /></a>The rules have also changed this month, though ever so slightly.  Now, we must insert a pic into our blog post rather than include the TSQL Tuesday in our blog title.  BTW, this month we are discussing features in <a href="http://sqlchicken.com/2010/06/t-sql-tuesday-007-summertime-in-the-sql/">SQL 2008</a> (supposed to be R2, but I am only discussing something that came out with 2008).</p>
<h4>Pick your Poison&#8230;err Feature.</h4>
<p>The feature that I have chosen is compression.  In SQL 2008 we have the option to compress backups as well as compress the data.  The data can be compressed in two methods as well.  I will just be discussing my experience with Page level compression.  I will touch lightly on the differences between row level and page level compression.</p>
<h3>History</h3>
<p>Do you recall a nifty utility that Microsoft gave us back in the glory days called <a href="http://en.wikipedia.org/wiki/DriveSpace">Doublespace</a> that was later renamed to Drivespace?  I do!!  Oh the memories are painful still.  That little compression agent was renamed due to the inaccuracy of the name.  You didn&#8217;t truly get double the space on your hard drive by using it.  I remember numerous support calls related to compression and all of them turned out ugly.  Something about compressing your drive and then losing everything because you used a Drive Overlay to access a larger disk drive than the BIOS supported and then used Doublespace to compress it.  Or another good one was to lose the doublespace bin files from a compressed drive.  You could also see heavy fragmentation issues.  All of these have created a heavy bias for me against mass compression utilities.</p>
<h3>Ch Ch Ch Changes</h3>
<p>Despite my heavy bias against compression, I have always liked the ability to compress selectively certain files or folders.  The reasons for compressing in this method, for me, have largely been for archival purposes.  There are several file compression utilities out there on the market for use in performing this.</p>
<p>How does that relate to database compression?  I see database compression, as offered with SQL 2008, to be more like these file compression utilities than DriveSpace.  Data compression in SQL 2008 is not an all or none implementation.  You get to pick and choose what gets compressed.  That is a big time bonus for me.</p>
<h3>The Setup</h3>
<p>After some research and having learned a bit about compression, I decided to test it out.  I have yet to test performance as I have only tested the disk savings that compressing could generate.  There is a good demonstration on performance by Jason Shadonix <a href="http://www.sqlservercentral.com/articles/SQL+Server+2008/69740/">here</a>, for those that are interested.  I will be baselining and testing performance at a later time &#8211; that is just a bit beyond the scope for this article.</p>
<p>I decided to use a database from our warehouse that resides on SQL 2000, on Windows 2003 32 Bit, currently.  I created a backup of that database and restored it to a test box that is running SQL 2008 on Windows 2008 R2 64 Bit.  The starting database size was 164GB.  The database was also left in SQL 2000 compatibility mode.  The selection criteria for tables to compress was to select any table larger than 1GB in size.  I used a script I showed in the <a href="http://jasonbrimhall.info/2010/05/25/space-used/">table space</a> series to determine which tables to target.  The script can be found as follows.</p><pre class="urvanov-syntax-highlighter-plain-tag">declare @dbsize decimal(19,2)
		,@logsize decimal(19,2)

set nocount on

/*
**  Summary data.
*/
begin
	select @dbsize = sum(convert(decimal(19,2),case when type = 0 then size else 0 end)) * 8/1024
		, @logsize = sum(convert(decimal(19,2),case when type = 1 then size else 0 end)) * 8/1024
		from sys.database_files

end
/*
**  We want all objects.
*/
Begin
	With FirstPass as (
		SELECT OBJECT_ID,
			ReservedPage = convert(decimal(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = convert(decimal(19,2),SUM(used_page_count)) *8/1024,
			PageCnt = SUM(
			convert(decimal(19,2),CASE
				WHEN (index_id &amp;lt; 2) 
					THEN (used_page_count)
				ELSE lob_used_page_count + row_overflow_used_page_count
				END
			)) * 8/1024,
			RowCnt = SUM(
			CASE
				WHEN (index_id &amp;lt; 2) 
					THEN row_count
				ELSE 0
			END
			)
		FROM sys.dm_db_partition_stats 
		--Where OBJECTPROPERTY(OBJECT_ID,'IsMSShipped') = 0
		Group By OBJECT_ID
	)
	,InternalTables as (
		Select ps.OBJECT_ID,
			ReservedPage = convert(decimal(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = convert(decimal(19,2),SUM(used_page_count)) *8/1024
		From sys.dm_db_partition_stats  ps
			Inner Join sys.internal_tables it
				On it.OBJECT_ID = ps.OBJECT_ID
				And it.internal_type IN (202,204,211,212,213,214,215,216)
		Where it.parent_id = ps.OBJECT_ID
			--And OBJECTPROPERTY(ps.OBJECT_ID,'IsMSShipped') = 0
		Group By ps.OBJECT_ID
	)
	,Summary as (
		SELECT 
			ObjName = OBJECT_NAME (f.OBJECT_ID),
			NumRows = MAX(f.rowcnt),
			ReservedPageMB = SUM(IsNull(f.reservedpage,0) + IsNull(i.ReservedPage,0)),
			DataSizeMB = Sum(f.PageCnt),
			IndexSizeMB = Sum(CASE WHEN (f.UsedPage + IsNull(i.UsedPage,0)) &amp;gt; f.PageCnt 
							THEN ((f.UsedPage + IsNull(i.UsedPage,0)) - f.PageCnt) ELSE 0 END) ,-- Equivalent of max_record_size from sys.dm_db_index_physical_stats
			UnusedSpace = Sum(CASE WHEN (f.ReservedPage + IsNull(i.ReservedPage,0)) &amp;gt; (f.UsedPage + IsNull(i.UsedPage,0)) 
				THEN ((f.ReservedPage + IsNull(i.ReservedPage,0)) - (f.UsedPage + IsNull(i.UsedPage,0))) ELSE 0 END),
			DBSizeMB = @Dbsize,
			LogSizeMB = @logsize
		From FirstPass F
			Left Outer Join InternalTables i
			On i.OBJECT_ID = f.OBJECT_ID
		Group By f.OBJECT_ID
	)
	Select ObjName,NumRows, ReservedPageMB, DataSizeMB, IndexSizeMB, UnusedSpace, DBSizeMB, LogSizeMB,
			PercentofDB = ((IndexSizeMb + DataSizeMB) / @DBsize) * 100
	Into #LargeTables2Compress
	From Summary
	Order By PercentofDB desc
End</pre><p>In this script, you will note that I am dumping the results into a temp table.  I wanted to be able to run a few different cases against the data to check results quickly without running the entire query over again.  Though, running this particular query would not take that long in most cases.  Consider the temp table a fail-safe to prevent long execution times of the query.</p>
<p>To determine which tables from the previous query I would target, I employed a script similar to the following.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select 'Alter Table ' + objname +' rebuild with (Data_Compression = Page);'
	From #LargeTables2Compress
	Where DataSizeMB &amp;gt; 1000</pre><p>This is pretty straight-forward.  I am only selecting those tables from the temp table that are larger than 1 GB.  I am also concatenating a string to those tables for manual execution purposes.  I can now see which tables are &#8220;large&#8221; and compress them with Page level compression or not (note: the same sort of script would work for Row Level compression).  After, I was happy with the result set and which tables would be compressed, I proceeded with compressing the tables.  Recall that the database started at 164GB.  After compression of the handful of tables (30 versus the 460 tables in the database), the database used space was now down to 84GB.  That is a reduction of ~49% in space requirements for this database.  For me, that is a pleasing result.</p>
<h4>What if&#8230;</h4>
<p>Should you decided to run this process again, the tables that you have already compressed will be included in the result set.  Should you proceed with running the table alter scripts again, you will not get any better compression and the compression will remain in effect.  Or, you could eliminate those tables that are compressed by altering the script provided to also read from sys.partitions as in the following script.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select 'Alter Table ' + objname +' rebuild with (Data_Compression = Page);'
	From #LargeTables2Compress 
	Where DataSizeMB &amp;gt; 1000
		And objname in 
			(Select object_name(p.object_id) From sys.partitions p
				Where p.data_compression =0  
					And OBJECTPROPERTY(p.object_id,'ISMSShipped') = 0
					)</pre><p></p>
<h3>Conclusion</h3>
<p>Without hard and fast numbers concerning performance, a final conclusion could not be made concerning whether to compress or not.  Having run a few dry runs to test if processes still worked, I am pleased with the performance (it is faster &#8211; I don&#8217;t have the final data to back that now though).  The disk savings and even with a stalemate on performance, I like the compression that is offered in SQL 2008.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=586" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/06/08/data-compression/">Data Compression</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/06/08/data-compression/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Defensive Database Programming Chapter 01</title>
		<link>https://jasonbrimhall.info/2010/06/07/defensive-database-programming-chapter-01/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=defensive-database-programming-chapter-01</link>
					<comments>https://jasonbrimhall.info/2010/06/07/defensive-database-programming-chapter-01/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 07 Jun 2010 18:36:26 +0000</pubDate>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<category><![CDATA[Professional Book Review]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=581</guid>

					<description><![CDATA[<p>Today I am finally getting around to the review of the first chapter as promised.  I talked about the book a bit in the first post on the subject, which can be found here.  This [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/06/07/defensive-database-programming-chapter-01/">Defensive Database Programming Chapter 01</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today I am finally getting around to the review of the first chapter as promised.  I talked about the book a bit in the first post on the subject, which can be found <a href="http://jasonbrimhall.info/2010/05/21/sql-book-review/">here</a>.  This book was written by Alex Kuznetsov (<a href="http://sqlblog.com/blogs/alexander_kuznetsov/default.aspx" class="broken_link">blog</a>).</p>
<p>In this chapter, Alex discusses some basic defensive programming techniques.  That, in fact, is essentially the name of the chapter.  This is a pretty lengthy chapter &#8211; and with good reason.  Alex is laying the groundwork in this chapter with some basic samples and pretty much giving an introduction to the book.  The code samples are straight forward and designed to illustrate his point quite well.</p>
<p>During my current reading, a good takeaway from this chapter is the discussion on Rowcount.  For me, it serves as a prime reminder of the deprecation status as of SQL Server 2008.  If you are using SET ROWCOUNT, stop and change your practices.  Alex suggests using TOP in lieu of SET ROWCOUNT.</p>
<p>With each case that Alex presents as a potential problem when building your SQL code, he offers up a solution on how to avoid that problem.  The composition of using problems and providing solutions is quite handy.</p>
<p>And in Alex&#8217;s own words (Chapter 1 Summary, Page 59)</p>
<p style="padding-left: 30px;">
<div id="_mcePaste" style="padding-left: 30px;"><em>&#8220;It is vital that you understand and document the assumptions that underpin your implementation, test</em></div>
<div id="_mcePaste" style="padding-left: 30px;"><em>them to ensure their validity, and eliminate them if they are not.&#8221;</em></div>
<div><em><br />
</em></div>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=581" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/06/07/defensive-database-programming-chapter-01/">Defensive Database Programming Chapter 01</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/06/07/defensive-database-programming-chapter-01/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>DTS and 2008</title>
		<link>https://jasonbrimhall.info/2010/06/04/dts-and-2008/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dts-and-2008</link>
					<comments>https://jasonbrimhall.info/2010/06/04/dts-and-2008/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 04 Jun 2010 18:21:00 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[The Corner dep]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=575</guid>

					<description><![CDATA[<p>Have you ever been required to update your SQL Server environment and needed to test it?  I know, rhetorical question.  I am in such a process currently.  We have the entire gambit of project killers [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/06/04/dts-and-2008/">DTS and 2008</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Have you ever been required to update your SQL Server environment and needed to test it?  I know, rhetorical question.  I am in such a process currently.  We have the entire gambit of project killers in play as well.  We have short deadlines, requirements to maintain current technologies (i.e. DTS) in the new environment, consolidate rack space (ok not really a project killer), and wrong parts/equipment being shipped.  Through all of this we must test two different versions of operating system to determine which environment to build the new servers.  To accomplish this we had two test servers setup with SQL 2008, and each is on a different platform.  One is on SQL 2008 (32 Bit) and the other is SQL 2008 R2 (64 Bit).  The testing of these two environments is explicitly to determine that both will work appropriately and produce desirable results, particularly in the realm of our DTS packages.</p>
<p>I am not going to go into details on how to test all of that.  Rather, I want to discuss a quick way to get such environments ready to go without the need to manipulate each of the packages to have them redirect to entirely new servers.  Remember, the idea is to test these production packages in a test environment and ensure they will function properly.  The only way to do that is to mimic the environment.  When you create new test servers, you could be required to change log locations, connection strings and possibly some queries inside the packages in order to make these packages work in the test environment.  If the production boxes were no longer in play and all we had were these new servers, the easiest solution by far is to create a CNAME entry in DNS with the old server name and point that to the IP address of the new servers.  This does not work when you must test while the production server still exists.  There are also other options &#8211; such as a new Test network to perform this.  If that sort of environment exists &#8211; by all means use it.  We don&#8217;t have the time nor the equipment to create such a setup (maybe someday later &#8211; our dev environment is not a distinct network separate from the production network either).</p>
<h3>What to Do?</h3>
<p>The first thing that came to mind to try and cover all aspects of this type of situation was to alter the Hosts file on the servers.  In Server 2008 R2 that is a bit different to do due to the need to launch notepad first in administrator mode.  Once I had the Hosts file on each of the servers altered to redirect to the local box should the prod server name be encountered, I set off to begin testing.  It did not take long to discover that this would not work.  When trying to create a connection in SSMS an error was thrown.  The error was in relation to the user being from an untrusted domain.  Well that wasn&#8217;t possible since the user was a legitimate domain and there is only one domain in play.  Fileshares were redirected as desired, just SSMS did not want to play.</p>
<p>Since that was a failure, the next idea I had was to create an alias on each of the servers and see if that worked any better.</p>
<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/06/R2Alias.jpg"><img loading="lazy" class="alignnone size-full wp-image-576" title="R2Alias" src="http://jasonbrimhall.info/wp-content/uploads/2010/06/R2Alias.jpg" alt="" width="771" height="257" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/06/R2Alias.jpg 771w, https://jasonbrimhall.info/wp-content/uploads/2010/06/R2Alias-300x100.jpg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px" /></a></p>
<p>Notice in this screen from the Server 2008 R2 environment (not SQL 2008 R2) that there are two client configuration sections.  In order to create an alias for use by SSMS, the 32bit version must be configured.  Once this alias is in place, one is able to reference in SSMS the Alias Name and be redirected right back to the local databases.  This is progress!  When SQL Agent attempts to connect to a Servername encountered in a connection (database) string in a dts package, it will use the alias.  This is real progress!</p>
<p>This does not cure all things though for testing.  The alias and the Hosts reconfig don&#8217;t work in conjunction one with another.  Thus, if one has any logs being written out to the file system then the logs will be written out to the actual server and not the aliased server.  This is true of logs attached to job steps and logs from within the DTS package.  Thus, if you are doing either of those things &#8211; some job and package editing may have to take place.  For the logs being written from job steps &#8211; I recommend not writing out to the file system and rather write it out to a table.  Writing out to a table will also reduce significantly the changes required in packages and their Agent jobs.  This will help you get to quicker testing.</p>
<p>A final note about the aliases.  If you try to change the Alias in the SQL Native Client 10.0 configuration section, you will not get the desired results.  Be careful on where you make these sorts of changes.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=575" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/06/04/dts-and-2008/">DTS and 2008</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/06/04/dts-and-2008/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Space Used</title>
		<link>https://jasonbrimhall.info/2010/05/25/space-used/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=space-used</link>
					<comments>https://jasonbrimhall.info/2010/05/25/space-used/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 25 May 2010 12:00:07 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Table Info]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=569</guid>

					<description><![CDATA[<p>At long last I am bringing the next installment in this mini-series.  You can find the rest of the articles by perusing the last article I wrote on the topic.  That article was a correction [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/25/space-used/">Space Used</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>At long last I am bringing the next installment in this mini-series.  You can find the rest of the articles by perusing the <a href="http://jasonbrimhall.info/2010/05/19/tablespace-update/">last article</a> I wrote on the topic.  That article was a correction to the TableSpace script about which I had already blogged.</p>
<p>As you will recall, this series was designed to compare and contrast two MS provided stored procedures.  Those procedures are sp_spaceused and sp_MStablespace.  They both calculate table sizes and information but they do not always arrive at the same result.  It was the difference in results that prompted this little series of blogs.  In this article I will be examining sp_spaceused, or at least the re-write I did for this proc.  There will likely be one more article in the series.  That article will be to compare performance and wrap up the series.</p>
<h3>Problem</h3>
<p>As was stated in the <a href="http://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/">Tablespace</a> article, there are two main problems with this procedure.  The first is that some measure of looping must be used, if one is to use the stored procedure as is, to gather all of the information for all of the tables in a database.  This problem can be rectified by understanding the inner workings of the stored procedure.  The second issue is that it does not return data that is consistent with that of sp_MStablespace.  I would like for the data to be consistent between the two scripts that may be used.  If the data is the same, then it will only be a matter of preference as to which script one decides to use.  This should help eliminate doubt.</p>
<h4>Looping</h4>
<p>Much the same as needs to be done with the sp_MStablespace procedure, a loop can be used to return the data for all tables.  Based on my experience, the looping query does not take long to execute.  It really is somewhat unnecessary though.  Here is a sample of how such a loop might be done.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">/*
Looping mechanism for sp_spaceused
*/

-- Create the temp table for further querying
CREATE TABLE #spaceused(
	rec_id			INT IDENTITY (1, 1),
	TableName		VARCHAR(128),
	NumRows			VARCHAR(11),
	reserved		VARCHAR(18),
	DataSpaceMB		VARCHAR(18),
	IndexSpaceMB	VARCHAR(18),
	unused			VARCHAR(18),
	TotalSizeMB		DECIMAL(15,2),
	percent_of_db	DECIMAL(15,12),
	DBSizeMB		DECIMAL(15,2)
	)

-- Get all tables, names, and sizes
EXEC sp_msforeachtable @command1=&quot;insert into #spaceused(TableName,NumRows,reserved, DataSpaceMB, IndexSpaceMB,unused) exec sp_spaceused '?'&quot;

update #spaceused
	Set DataSpaceMB = replace(DataSpaceMB,' KB','')
		,IndexSpaceMB = replace(IndexSpaceMB,' KB','')

-- Set the TotalSizeMB and total database size fields
UPDATE #spaceused
SET TotalSizeMB = (convert(decimal(15,2),DataSpaceMB) + convert(decimal(15,2),IndexSpaceMB))/1024
	,DBSizeMB = (SELECT SUM(convert(decimal(15,2),DataSpaceMB) + convert(decimal(15,2),IndexSpaceMB))/1024 FROM #spaceused)

-- Set the percent of the total database size
UPDATE #spaceused
	SET percent_of_db = (TotalSizeMB/DBSizeMB) * 100

-- Get the data
--sp_spaceused
SELECT TableName,NumRows, convert(decimal(15,2),DataSpaceMB)/1024 as DataSpaceMB
	,convert(decimal(15,2),IndexSpaceMB)/1024 as IndexSpaceMB, TotalSizeMB, percent_of_db, DBSizeMB
	FROM #spaceused
	ORDER BY TotalSizeMB DESC

/* Drop Temp Table
DROP TABLE #spaceused
*/</pre><p>[/codesyntax]</p>
<p>In this version of the loop, it must be noted that an additional step must be taken due to the nature of the data that is returned by sp_spaceused.  This procedure returns &#8216; KB&#8217; in the output.  This additional data must be treated so proper calculations can be performed.</p>
<h4>Inconsistencies</h4>
<p>As stated in the aforementioned article on sp_MStablespace, the data returned between the two does not always match (in regards to table size).  The reason for this is due to a difference in calculation and it seems intent.  Thus both procs can be deemed accurate and correct.  However, that does not breed any higher level of confidence in the return data from both procedures.  I hope to elaborate somewhat on these subtle differences.</p>
<h3>Discovery</h3>
<p>I am using the stored procedure from SQL 2008 as the basis for my analysis.  One of the first things I have noted is that the procedure has been mostly updated in support of the new SQL 2008 objects.  The one exception is that it still uses dbo.<span style="color: #008000;">sysfiles </span>to try and determine the database size and logsize.  Beyond that, the proc makes use of the system views <span style="color: #008000;">sys.partitions</span>, <span style="color: #008000;">sys.allocation_units</span>, <span style="color: #008000;">sys.internal_tables</span>, <span style="color: #008000;">sys.objects</span> and <span style="color: #008000;">sys.dm_db_partition_stats</span>.</p>
<h4><span style="color: #008000;">sys.objects</span></h4>
<p>The use of this view is primarily to get the object_id of the table that was passed in to the stored procedure.  For this particular version, this can be eliminated since we are trying to get a solution that does not require looping.  For a later version, I will look into reincorporating that view into the script to allow either a single table or all tables to be returned.</p>
<h4><span style="color: #008000;">sysfiles</span></h4>
<p>As mentioned already, <span style="color: #008000;">sysfiles</span> is present in order to retrieve the database size and the logfile size.  This can be replaced by sys.database_files.  In testing, I have found that using <span style="color: #008000;">sys.database_files</span> is more consistent and it is also more accurate than using <span style="color: #008000;">sysfiles</span>.</p>
<h3>Revision</h3>
<p>Since this procedure was already mostly up to date with the new objects for 2005 / 2008, most of it is reusable and the changes are less dramatic than they were for the counterpart sp_MStablespace.  Much the same as the script for MStablespace, I did employ the use of CTEs to get the data that I wanted.  I use three CTEs to retrieve all of the necessary information.  I am also using the same calculations that were used in the original procedure that determined table size.  The exception being in the database size and the log size.  For ease of consumption, I will once again break the script up into smaller chunks.</p>
<h4><span style="color: #0000ff;">Part I</span></h4>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">/*similar to sp_spaceused */

declare @dbsize decimal(19,2)
		,@logsize decimal(19,2)

set nocount on

/*
**  Summary data.
*/
begin
	select @dbsize = sum(convert(decimal(19,2),case when type = 0 then size else 0 end)) * 8/1024
		, @logsize = sum(convert(decimal(19,2),case when type = 1 then size else 0 end)) * 8/1024
		from sys.database_files

end</pre><p>[/codesyntax]</p>
<p>This is pretty straightforward here.  I am retrieving and summing the values needed for the database size and the log size.</p>
<h4><span style="color: #0000ff;">Part II</span></h4>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Begin
	With FirstPass as (
		SELECT OBJECT_ID,
			ReservedPage = convert(decimal(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = convert(decimal(19,2),SUM(used_page_count)) *8/1024,
			PageCnt = SUM(
			convert(decimal(19,2),CASE
				WHEN (index_id &amp;lt; 2) 
					THEN (used_page_count)
				ELSE lob_used_page_count + row_overflow_used_page_count
				END
			)) * 8/1024,
			RowCnt = SUM(
			CASE
				WHEN (index_id &amp;lt; 2) 
					THEN row_count
				ELSE 0
			END
			)
		FROM sys.dm_db_partition_stats 
		--Where OBJECTPROPERTY(OBJECT_ID,'IsMSShipped') = 0
		Group By OBJECT_ID
	)
	,InternalTables as (
		Select ps.OBJECT_ID,
			ReservedPage = convert(decimal(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = convert(decimal(19,2),SUM(used_page_count)) *8/1024
		From sys.dm_db_partition_stats  ps
			Inner Join sys.internal_tables it
				On it.OBJECT_ID = ps.OBJECT_ID
				And it.internal_type IN (202,204,211,212,213,214,215,216)
		Where it.parent_id = ps.OBJECT_ID
			--And OBJECTPROPERTY(ps.OBJECT_ID,'IsMSShipped') = 0
		Group By ps.OBJECT_ID
	)
	,Summary as (
		SELECT 
			ObjName = OBJECT_NAME (f.OBJECT_ID),
			NumRows = MAX(f.rowcnt),
			ReservedPageMB = SUM(IsNull(f.reservedpage,0) + IsNull(i.ReservedPage,0)),
			DataSizeMB = Sum(f.PageCnt),
			IndexSizeMB = Sum(CASE WHEN (f.UsedPage + IsNull(i.UsedPage,0)) &amp;gt; f.PageCnt 
							THEN ((f.UsedPage + IsNull(i.UsedPage,0)) - f.PageCnt) ELSE 0 END) ,-- Equivalent of max_record_size from sys.dm_db_index_physical_stats
			UnusedSpace = Sum(CASE WHEN (f.ReservedPage + IsNull(i.ReservedPage,0)) &amp;gt; (f.UsedPage + IsNull(i.UsedPage,0)) 
				THEN ((f.ReservedPage + IsNull(i.ReservedPage,0)) - (f.UsedPage + IsNull(i.UsedPage,0))) ELSE 0 END),
			DBSizeMB = @Dbsize,
			LogSizeMB = @logsize
		From FirstPass F
			Left Outer Join InternalTables i
			On i.OBJECT_ID = f.OBJECT_ID
		Group By f.OBJECT_ID
	)
	Select ObjName,NumRows, ReservedPageMB, DataSizeMB, IndexSizeMB, UnusedSpace, DBSizeMB, LogSizeMB,
			PercentofDB = ((IndexSizeMb + DataSizeMB) / @DBsize) * 100

	From Summary
	Order By PercentofDB desc
End</pre><p>[/codesyntax]</p>
<p>Note here that I have left code to remove MSShipped objects from the total.  This is a placeholder simply for if somebody would like to test that result.  The only thing other than that to explain is the internal_types.  I am checking for a range of internal table types just as is done in the original stored procedure.  A quick rundown of what those types is as follows (and can be found on MSDN):  202 = xml index nodes, 204 = fulltext_catalog_map, 211 = FULLTEXT_AVDL, 213 = FULLTEXT_DOCID_STATUS, 214 = FULLTEXT_INDEXED_DOCID, 215 = FULLTEXT_DOCID_FILTER, 216 = FULLTEXT_DOCID_MAP, and I was unable to locate what type 212 is.  I presume it is another FullText type.  For those types, the data is not counted as part of the data but is aggregated into the index size.</p>
<p>The final point with this script to note is in regards to an additional comment I left in the script.  The comment is in regards to how the size is calculated and I wanted to be certain that it was explained how that relates.  In the MStablespace script, I use sys.dm_db_index_physical_stats to help determine the index and table size.  My comment here relates to that DMF in that the spaceused version is equivalent to the max_record_size field in that DMF.  This procedure and script determine the size of a table based on the maximum size and of a page and then multiplies that across all pages.  The MStablespace script is more equivalent to calculating based on average fill of those pages.  The MStablespace script can easily be modified to support the max size and thus bring both scripts into harmony.  Beyond those points, I think the rest of the script is pretty self-explanatory.</p>
<h3>Results</h3>
<p>This script now permits us to get the full size of all tables in a database without the need for looping through a single stored procedure.  We also see that at this point we have outlined why the two Microsoft stored procedures returned different results.  With both scripts now returning the same data, and doing so consistently we can now begin to evaluate performance measures.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=569" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/25/space-used/">Space Used</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/25/space-used/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Content Copy Followup</title>
		<link>https://jasonbrimhall.info/2010/05/24/content-copy-followup/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=content-copy-followup</link>
					<comments>https://jasonbrimhall.info/2010/05/24/content-copy-followup/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 24 May 2010 17:12:17 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[copy]]></category>
		<category><![CDATA[plagiarism]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=567</guid>

					<description><![CDATA[<p>Last week I posted an article about plagiarism.  This is a follow-up to that.  After posting that blog article, Steiner quickly removed the copied content.  The tone may have been a bit harsh in that [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/24/content-copy-followup/">Content Copy Followup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Last week I posted an article about plagiarism.  This is a follow-up to <a href="http://jasonbrimhall.info/2010/05/20/plagiarized/">that</a>.  After posting that blog article, Steiner quickly removed the copied content.  The tone may have been a bit harsh in that article.  My feeling on the subject has shifted only slightly.  Steinar was trying to do something good, only went about it the wrong way.  The issue for me is not the intention but the posting of entire articles for consumption by somebody else.  The articles did have a category on each one with the original authors name.  However, that was not evident when first reading the article.  Had I not known that the articles were mine, I may have missed the category at the end of the article.   Having known that the article was mine, I looked harder for some sort of attribution.</p>
<p>Here is where my opinion has shifted slightly.  Steinar was only plagiarizing inadvertently (prior to my initial post I was a little uncertain in this regard).  I don&#8217;t think he was blatantly intending to do harm.  Despite that, <a href="http://www.wadsworth.com/english_d/special_features/plagiarism/definition.html" class="broken_link">whether intentional or not</a> &#8211; it was plagiarism.  Has he corrected his actions &#8211; YES!  The speed with which he reacted to the emails he received tells me that it was unintentional.  Do I still take issue with it &#8211; NO!  He apologized, corrected the wrong and we are moving on.  I also must apologize for plastering his email on my blog.  I have removed the email address.  I should have done so sooner.</p>
<p>This morning I received an email from Steinar about working with him to post some content for his aggregation.  I responded with some questions about his plans for how he will be managing his aggregation.  I hope that we can work something out that would be beneficial for both.</p>
<p>The blog site that Steinar runs is <a href="https://web.archive.org/web/20100127162943/http://www.sqlblogs.net:80/">www.sqlblogs.net</a>.  Go check it out.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=567" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/24/content-copy-followup/">Content Copy Followup</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/24/content-copy-followup/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Plagiarized or Copied</title>
		<link>https://jasonbrimhall.info/2010/05/20/plagiarized/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=plagiarized</link>
					<comments>https://jasonbrimhall.info/2010/05/20/plagiarized/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 20 May 2010 23:04:19 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[plagiarism]]></category>
		<category><![CDATA[rant]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=559</guid>

					<description><![CDATA[<p>Today I ran into an interesting website.  While I was trying to locate information concerning a SQL Saturday event, I came across one of my blog entries on another site.  I syndicate to SQLServerCentral and [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/20/plagiarized/">Plagiarized or Copied</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Today I ran into an interesting website.  While I was trying to locate information concerning a SQL Saturday event, I came across one of my blog entries on another site.  I syndicate to <a href="https://www.sqlservercentral.com/blogs/source/sql-rnnr">SQLServerCentral </a>and <a href="https://blog.toadworld.com/">SQLServerpedia (replaced by toadworld and author page is gone now)</a> and am fully aware that my blogs would be verbatim on each of those sites.  That is expected, both parties and I agreed to terms and conditions of syndicating my blog on those sites.  This site was neither of them.  My blogs that appear on this site could be found <a href="https://web.archive.org/web/20100528052416/http://www.sqlblogs.net:80/?author=72">here</a> (as of the writing of this article).</p>
<p>I had to ponder it for a bit.  The intent of the site, as they state, is to pull the best of the blogs to a single site.  That may seem a little flattering for somebody new to the blogging world.  I decided to ask some peers what they thought of the site.  You can find that question <a href="http://www.sqlservercentral.com/Forums/Topic604325-61-308.aspx#bm925502">here </a>and follow the conversation about it.  Flattery or not it is stealing of content as Buck Woody brought up in his <a href="http://blogs.msdn.com/buckwoody/archive/2010/05/20/shame-on-you-for-stealing.aspx">blog</a> on the topic after word spread.  Thanks to Gail Shaw for forwarding it out on twitter.  A lot of people have their blogs copied to this site, and none via permission.  Emails are being generated and being sent to (removed email address) the admin of the site.  If your content has been stolen, I suggest you do the same.</p>
<p>Personally, if a request came to me asking my permission to have my material syndicated on that blog site &#8211; I would consider it.  But please don&#8217;t just post my content without proper attribution or having requested my permission.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=559" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/20/plagiarized/">Plagiarized or Copied</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/20/plagiarized/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>TableSpace Update</title>
		<link>https://jasonbrimhall.info/2010/05/19/tablespace-update/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tablespace-update</link>
					<comments>https://jasonbrimhall.info/2010/05/19/tablespace-update/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 19 May 2010 17:15:53 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Table Info]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=554</guid>

					<description><![CDATA[<p>The last post in the series on finding the sizes of your tables showed us how we could find that size via a set-based method similar to using sp_MStablespace.  In that post I showed you [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/19/tablespace-update/">TableSpace Update</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>The last post in the series on finding the sizes of your tables showed us how we could find that size via a set-based method similar to using sp_MStablespace.  In that post I showed you how to find the sizes using the SQL 2005 system objects rather than the scheduled to be deprecated objects.  You can read more about it <a href="http://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/">here</a>.</p>
<p>I needed to go back and revisit that post and perform a little spring cleaning on it.  I noticed after publication that the script had multiple columns by the same name that were unintended.  I discovered this as I was prepping and reviewing for my presentation at our SSSOLV (PASS UG) meeting last week.  During that review I came across another bug.  The script was not consistently returning the index size for the tables.  After reviewing the script more closely, against more databases, I found the problem and fixed it.  The change was rather simple &#8211; I changed the Join from the #indstats table to go directly to sys.partitions rather than through <span style="color: #008000;">sys.dm_db_index_usage_stats</span>.  I was able to spot this one due to running the query against one of my databases that is seldom used and thus the indexes were less likely to have statistics populated in that DMV.</p>
<p>So, here is the updated query.  Rather than breaking out into sections like I did in that last article, I am just pasting the script in its entirety.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Part I */
--Drop Table #indstats
If exists (select * from tempdb.sys.objects where name like '%#indstats%')
Begin
	Drop table tempdb.dbo.#indstats
End

Begin
CREATE TABLE #indstats (
         IndStatsID Int PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,OBJECT_ID	BIGINT
);
End

INSERT INTO #indstats (IndStatsID,database_id,index_id,OBJECT_ID,IndexSizeMB)
        SELECT Row_Number() over (order by Object_id) as IndStatsID
				,database_id,index_id,OBJECT_ID
				,CONVERT(DECIMAL(19,2),(SUM(ps.page_count))) * 8 /1024 AS IndexSizeMB
			FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
			GROUP BY database_id,OBJECT_ID,index_id;

/* Part II */
declare @dbsize decimal(19,2)

set nocount on

/*
**  Summary data.
*/
begin
	select @dbsize = sum(convert(decimal(19,2),case when type = 0 then size else 0 end)) * 8/1024
		from sys.database_files

end

/* Part III */
Begin
	With RegData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) 
					+ IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				On p.hobt_id = a.container_id
				And a.type = 1
			Left Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON p.index_id = ps.index_id
				And ps.database_id = DB_ID()
				And p.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	)
	, LOBData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) 
					+ IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				ON p.partition_id = a.container_id
				And a.type = 2
			Left Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON p.index_id = ps.index_id
				And ps.database_id = DB_ID()
				And p.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	)
	, OverFlowData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) 
					+ IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				On p.hobt_id = a.container_id
				And a.type = 3
			Left Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON p.index_id = ps.index_id
				And ps.database_id = DB_ID()
				And p.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	), IndexSum as (
		Select a.object_id
		,AllDataSizeMB = sum(case when a.index_id in (0,1) 
							Then IsNull(a.DataSizeMB,0) +  IsNull(p2.DataSizeMB,0) +  IsNull(p3.DataSizeMB,0)
							Else IsNull(p2.DataSizeMB,0) + IsNull(p3.DataSizeMB,0)
							End)
		From RegData a
			Left Outer Join LOBData p2
				ON p2.container_id = a.container_id
			Left Outer Join OverFlowData p3
				ON p3.container_id = a.container_id
		Group By a.object_id
	), SummaryInfo as (
		SELECT 
			TableName = Max(a.TableName)
			,InRowDataSizeMB = sum(IsNull(a.DataSizeMB,0))
			,LOBDataSizeMB = sum(IsNull(p2.DataSizeMB,0))
			,OFlowDataSizeMB = sum(IsNull(p3.DataSizeMB,0))
			,NumRows = Max(Coalesce(a.NumRows,p2.NumRows,p3.NumRows,0))
			,AllUsedPages = sum(IsNull(a.UsedPages,0) + IsNull(p2.UsedPages,0) + IsNull(p3.UsedPages,0))
			,AllPages = sum(IsNull(a.TotalPages,0) + IsNull(p2.TotalPages,0) + IsNull(p3.TotalPages,0))
			,FreeDataSpace = convert(decimal(19,2),
				sum(IsNull(a.TotalPages,0) + IsNull(p2.TotalPages,0) + IsNull(p3.TotalPages,0)) 
				- sum(IsNull(a.UsedPages,0) + IsNull(p2.UsedPages,0) + IsNull(p3.UsedPages,0)))* 8 / 1024
			,AllDataSizeMB = Max(ids.AllDataSizeMB)
			,IndexSizeMB = Sum(IsNull(a.IndexSizeMB,0)) 
				+ sum(IsNull(p2.IndexSizeMB,0)) + sum(IsNull(p3.IndexSizeMB,0))
			,UserRequests = Avg(IsNull(a.UserRequests,0) 
				+ IsNull(p2.UserRequests,0) + IsNull(p3.UserRequests,0))
			,UserUpdates = Avg(IsNull(a.UserUpdates,0) + IsNull(p2.UserUpdates,0) + IsNull(p3.UserUpdates,0))
			,LastUpdate = Max(Coalesce(a.LastUpdate,p2.LastUpdate,p3.LastUpdate,null))
			,DatabaseSize = @dbsize
		FROM RegData a
			Left Outer Join LOBData p2
				ON p2.container_id = a.container_id
			Left Outer Join OverFlowData p3
				ON p3.container_id = a.container_id
			Left Outer Join sys.indexes i
				ON i.OBJECT_ID = a.OBJECT_ID
				And i.index_id = a.index_id
			Left Outer Join IndexSum ids
				On i.object_id = ids.object_id
		--WHERE filegroup_name(a.data_space_id) = 'Primary'
		Group by a.object_id
	)
	Select TableName,NumRows,InRowDataSizeMB,LOBDataSizeMB,OFlowDataSizeMB
			,AllUsedPages,AllPages
			,FreeDataSpace,AllDataSizeMB,IndexSizeMB
			,TableSizeMB = AllDataSizeMB + IndexSizeMB + FreeDataSpace
			,UserRequests,UserUpdates,LastUpdate
			,PercentofDB = ((IndexSizeMB + AllDataSizeMB) / DatabaseSize) * 100
			,DatabaseSize
		From SummaryInfo
		Order By PercentofDB desc
End</pre><p>[/codesyntax]</p>
<p>At some point in the future, I intend on modifying this query to make it more flexible in output, as well as to make it into a stored procedure.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=554" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/19/tablespace-update/">TableSpace Update</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/19/tablespace-update/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>May 2010 S3OLV Meeting Recap</title>
		<link>https://jasonbrimhall.info/2010/05/14/may-2010-s3olv-meeting-recap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=may-2010-s3olv-meeting-recap</link>
					<comments>https://jasonbrimhall.info/2010/05/14/may-2010-s3olv-meeting-recap/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Fri, 14 May 2010 16:17:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[PASS]]></category>
		<category><![CDATA[S3OLV]]></category>
		<category><![CDATA[User Group]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=547</guid>

					<description><![CDATA[<p>On the evening of May 13th, S3OLV held its monthly meeting.  We had some really good discussion, and got to participate in a couple of good presentations. Charley (Chapter President) gave a presentation on his [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/14/may-2010-s3olv-meeting-recap/">May 2010 S3OLV Meeting Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>On the evening of May 13th, S3OLV held its monthly meeting.  We had some really good discussion, and got to participate in a couple of good presentations.</p>
<p>Charley (Chapter President) gave a presentation on his current SAN migration and some of the sticking points that he is experiencing.  To say they are experiencing mild frustration would be putting it lightly.  We joked about it a bit, but it raises some good discussion points.  The primary point is SAN configuration and doing it correctly.  The secondary point is to not make hasty decisions or decisions based on knee-jerk reactions.  The final discussion point to be made would be to test.  They are testing it currently &#8211; and that is good.  The principle problem is that the disk performance has decreased by a factor of two.</p>
<p>Charley also showed us some of his dabbling in burning his own circuit boards and programming the processors for the board.  Cool stuff.</p>
<p>The second presentation was by myself.  I showed a few different methods for quickly finding the table sizes for all of the tables in the database.  This presentation goes hand in hand with the series I am currently doing on the same subject.</p>
<p>It was a good meeting and fun was had.  The discussion was both light and serious at times.  We even had a carrion and a howling flying monkey visit us.</p>
<p>Tune in next month for more about S3OLV.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=547" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/14/may-2010-s3olv-meeting-recap/">May 2010 S3OLV Meeting Recap</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/14/may-2010-s3olv-meeting-recap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>T-SQL Tuesday #006: A Blobbing We Will Go</title>
		<link>https://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=t-sql-tuesday-006-a-blobbing-we-will-go</link>
					<comments>https://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 11 May 2010 19:49:00 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[BLOB]]></category>
		<category><![CDATA[Scripts]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=538</guid>

					<description><![CDATA[<p>In the DMVs for SQL 2005 and SQL 2008 there is more than one place you can find the information about the size of your LOB data?  And it goes without saying that there is more than one way to find information about LOBs in your database.</p>
The post <a href="https://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/">T-SQL Tuesday #006: A Blobbing We Will Go</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p><a href="http://jasonbrimhall.info/wp-content/uploads/2010/05/blobfish.jpg"><img loading="lazy" class="alignleft size-full wp-image-540" title="blobfish" src="http://jasonbrimhall.info/wp-content/uploads/2010/05/blobfish.jpg" alt="" width="288" height="576" srcset="https://jasonbrimhall.info/wp-content/uploads/2010/05/blobfish.jpg 288w, https://jasonbrimhall.info/wp-content/uploads/2010/05/blobfish-150x300.jpg 150w" sizes="(max-width: 288px) 85vw, 288px" /></a></p>
<p>Once again it looks like I was early for the <a href="http://tSQLtuesDay.com">T-SQL Tuesday</a> event.  Last month I submitted <a href="http://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/">my entry</a> on reporting as was the topic last month.  If you recall, last month I was a week early.  As it turns out, this month I am a full month early.  This month we have the distinct pleasure of writing about BLOBS.  Last month I wrote about Reporting on BLOBS.  This month, the event is hosted by <a href="http://sqlblog.com/blogs/michael_coles/archive/2010/05/03/t-sql-tuesday-006-what-about-blob.aspx" class="broken_link">Michael Coles</a>.</p>
<p>This month the topic is a little more difficult for me.  As luck would have it, I have written a fair share of articles about BLOB data, or at least involving BLOBs over the last month.  What should I write that is unique to what I have already written?  Or could I slide by with simply writing a recap of some of those posts?  Hmmmmm&#8230;</p>
<p>Well, lucky I know of something that I can add to the meme on the topic of LOB or BLOB data.  Oh, and it is more than just the fish you see to the left.</p>
<h3>Did You Know&#8230;</h3>
<p>In the DMVs for SQL 2005 and SQL 2008 there is more than one place you can find the information about the size of your LOB data?  And it goes without saying that there is more than one way to find information about LOBs in your database.  I have outlined a couple of methods already in previous posts (and in another post coming up that will conclude the table size procs series that I started).</p>
<p>One of the methods to find a little information about the LOBs is through a function that I have been using for various different purposes.  This function is the <span style="color: #008000;">sys.dm_db_index_physical_stats <span style="color: #000000;">function.  In this function there is a column returned called allocation_unit_type.  If you want to learn more about this function and the column, I recommend you read what Microsoft has to say about it from this <a href="http://msdn.microsoft.com/en-us/library/ms188917.aspx">page</a>.  In short, this column contains what type of data is being stored for the specified database and object within that database with its varying other stats.</span></span></p>
<h3>That&#8217;s all fine and dandy&#8230;</h3>
<p>Since we know (from reading that Microsoft document and from past experiences) that we can retrieve various pieces of information from this function such as page counts, allocation unit types, record count and avg record size; it stands to reason that we can also determine the size of our BLOB infrastructure through the use of this function.  The question is, how do we calculate the size and which option should we use to do it?</p>
<h3>Weapons of Choice</h3>
<p>Due to the length of time it may take to run the function, one may want to have a few options.  It is also desirable that one use the most efficient method to retrieve the data.  In order to find this, I decided to use test each of the function options to determine accuracy and speed.  These options are Limited (Default), Sampled, and Detailed.</p>
<p>The script setup for each is essentially the same script.  The only difference being that option has been changed for the data pertinent to that option.  After running each of the scripts, I find the results to be somewhat surprising.  I will be examining execution time, Io statistics and the execution plans and execution cost.  I will also note that I am also dumping the results of each of the function calls into a temp table so I can run multiple queries against that data without having to wait for the function to run again.</p>
<h4>Limited</h4>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">If exists (select * from tempdb.sys.objects where name like '%#LimitedLOB%')
Begin
	Drop table tempdb.dbo.#LimitedLOB
End

Begin
CREATE TABLE #LimitedLOB (
         LOBStatsID Int PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,OBJECT_ID	BIGINT
        ,AllocUnitType	varchar(24)
);
End
set statistics time on
set statistics io on

INSERT INTO #LimitedLOB (LOBStatsID,database_id,index_id,OBJECT_ID ,AllocUnitType,IndexSizeMB)
	SELECT Row_Number() over (order by Object_id) as IndStatsID
		,database_id,index_id,object_id,alloc_unit_type_desc
		,CONVERT(DECIMAL(19,2),(SUM(ps.page_count))) * 8 /1024 AS IndexSizeMB					--for accuracy
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'Limited') ps
	GROUP BY database_id,OBJECT_ID,index_id,alloc_unit_type_desc

set statistics time off
set statistics io off</pre><p>The query is pretty straightforward and self-explanatory.  I am querying the function for all tables in the database in a limited fashion.  I am grouping those results into usable groupings based on allocation unit type, object, index and database.  From this query, I see a CPU Time of 3062 ms and elapsed time of 8809ms.  I have also taken the sum of all objects returned from this query to get a value of 1163.5 MB for this database.  At this point I have not broken out the sum by allocation unit type.</p>
<h4>Sampled</h4>
<p>For the sampled run, I used the same query with minor changes.</p><pre class="urvanov-syntax-highlighter-plain-tag">If exists (select * from tempdb.sys.objects where name like '%#SampledLOB%')
Begin
	Drop table tempdb.dbo.#SampledLOB
End

Begin
CREATE TABLE #SampledLOB (
         LOBStatsID Int PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,OBJECT_ID	BIGINT
        ,AllocUnitType	varchar(24)
);
End
set statistics time on
set statistics io on

INSERT INTO #SampledLOB (LOBStatsID,database_id,index_id,OBJECT_ID ,AllocUnitType,IndexSizeMB)
	SELECT Row_Number() over (order by Object_id) as IndStatsID
		,database_id,index_id,object_id,alloc_unit_type_desc
		,CONVERT(DECIMAL(19,2),(SUM(ps.page_count))) * 8 /1024 AS IndexSizeMB					--for accuracy
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'Sampled') ps
	GROUP BY database_id,OBJECT_ID,index_id,alloc_unit_type_desc

set statistics time off
set statistics io off

;
set statistics time off
set statistics io off</pre><p>The only changes being the option and the name of the temp table.  For this query, I get a CPU time of 3203ms, elapsed time of 5768ms and a total for the objects of 11678.2 MB.  If I were to stop at this point I would conclude that the actual size would be larger than I just saw and I could expect that the cpu time and elapsed times should be longer.  The bit of surprise is that the sampled return is faster overall than using the limited option.</p>
<h4>Detailed</h4>
<p>Same script as the prior to tests.  Again, the only changes are in regards to the temp table name and the use of the Detailed option in the function.  When I run the detailed query, I see that the cpu time jumps to 12313ms, elapsed time jumps to 29191ms and the total size decreases to 11635 MB.  What?  The total size decreased.  It is more in line with what we see from the Limited option.  With that knowledge, one may conjecture that it would suffice for these queries to simply run the function in Limited fashion.  The speed of that option is comparable to the Sampled run and the data appears to be more accurate (since sample is just an estimate).</p>
<h3>Conclusion</h3>
<p>The execution plan and query cost for each run is identical in my testing.  The real differences were seen in execution time.  I can now take this data and modify the queries slightly further to just return the lines that tell me the size information for the allocation unit type of &#8220;LOB_DATA.&#8221;  This will help me to gain a better understanding of the sizes of that kind of data in my environment and a better understanding of the environment in general.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=538" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/">T-SQL Tuesday #006: A Blobbing We Will Go</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/11/t-sql-tuesday-006-a-blobbing-we-will-go/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>SQL 2005 TableSpace</title>
		<link>https://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-2005-tablespace</link>
					<comments>https://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Wed, 05 May 2010 07:56:24 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Table Info]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=518</guid>

					<description><![CDATA[<p>In the first post of this series I highlighted and described two stored procedures that are shipped from Microsoft.  These stored procedures use different methods to display information about a table in a SQL Server [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/">SQL 2005 TableSpace</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In the <a href="http://jasonbrimhall.info/2010/05/03/table-sizes/">first post</a> of this series I highlighted and described two stored procedures that are shipped from Microsoft.  These stored procedures use different methods to display information about a table in a SQL Server database.  In this post, I want to delve a little deeper into the sp_MStablespace stored procedure.  In doing this, I plan to discover what causes the reporting difference between it and sp_spaceused.  I will also unveil a script that can be used in a Set-based fashion to return this information, unlike the RBAR method required forsp_MStablespace.  Like I stated in the first post, this analysis will be based on SQL 2008.</p>
<h3>Problem</h3>
<p>When one uses sp_MStablespace, one may be assuming that it will return the same information that sp_spaceused would return.  While this procedure is undocumented and less widely used, the design is that it will give table and index information for the table one provides as an input into the procedure.  In order to gain this information for more than one table (using this procedure), one must implement a looping mechanism.</p>
<h4>Looping</h4>
<p>I have been using a script that was passed along to me many years ago that helps to find the table information for all of the tables in a database.  I have seen a similar script passed around on the internet in several locations.  This script uses another Microsoft procedure to help loop through the tables and provide this sought-after information.  The name of that procedure is sp_msforeachtable.  Despite the looping mechanism employed, the script is pretty quick and dependable.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Create the temp table for further querying
CREATE TABLE #temp(
	rec_id		int IDENTITY (1, 1),
	table_name	varchar(128),
	nbr_of_rows	int,
	data_space	decimal(15,2),
	index_space	decimal(15,2),
	total_size	decimal(15,2),
	percent_of_db	decimal(15,12),
	db_size		decimal(15,2))

-- Get all tables, names, and sizes
EXEC sp_msforeachtable @command1=&quot;insert into #temp(nbr_of_rows, data_space, index_space) exec sp_mstablespace '?'&quot;,
			@command2=&quot;update #temp set table_name = '?' where rec_id = (select max(rec_id) from #temp)&quot;

-- Set the total_size and total database size fields
UPDATE #temp
SET total_size = (data_space + index_space)/1024, db_size = (SELECT SUM(data_space + index_space)/1024 FROM #temp)

-- Set the percent of the total database size
UPDATE #temp
SET percent_of_db = (total_size/db_size) * 100

-- Get the data
SELECT *
FROM #temp
--ORDER BY nbr_of_rows DESC
ORDER BY total_size DESC

-- Comment out the following line if you want to do further querying
DROP TABLE #temp</pre><p>[/codesyntax]</p>
<p>The script is pretty straight forward in its design and goals.  This looping can be resolved with a set based solution that works faster in most of my test cases.</p>
<h4>Inconsistencies</h4>
<p>The second problem noted was that the data returned from the sp_MStablespace proc does not always match the data returned by sp_spaceused.  This is a substantially different problem to tackle.  I poured over the two procedures for hours trying to find what the problem was that was causing the difference.  My findings are somewhat surprising &#8211; they are both accurate and correct.  How can they both be correct when both return different values?  I hope to also explain that between this post and the subsequent post that will discuss sp_spaceused.</p>
<h3>Discovery</h3>
<p>In the first article, I mentioned some of the differences and subtleties of this stored procedure.  I also made an assumption that this procedure will be deprecated or at least massively changed.  As I discuss the internals of this procedure, I hope that assumption will be validated.</p>
<p>The objects employed in sp_MStablespace are <span style="color: #008000;">sysobjects</span>, <span style="color: #008000;">sysindexes</span>, <span style="color: #008000;">sys.indexes</span>, <span style="color: #008000;">sys.partitions</span>, and <span style="color: #008000;">sys.allocation_units</span>.  This is actually not too bad of a start for rewriting this procedure due to the use of <span style="color: #008000;">sys.indexes</span>, <span style="color: #008000;">sys.partitions</span>, and <span style="color: #008000;">sys.allocation_units</span>.  Let&#8217;s take a look at the use of the old and soon to be deprecated objects: <span style="color: #008000;">sysobjects </span>and <span style="color: #008000;">sysindexes</span>.</p>
<h4><span style="color: #008000;">sysobjects</span></h4>
<p>The role that this object plays is actually quite minor.  This object should easily be replaced by <span style="color: #008000;">sys.objects</span>.  The <span style="color: #008000;">sysobjects </span>view is being used to set the @id variable to the object id that is found in the <span style="color: #008000;">sysobjects </span>view.  If the tablename that was passed into the proc was not found in <span style="color: #008000;">sysobjects</span>, then the procedure should raise an error.</p>
<h4><span style="color: #008000;">sysindexes</span></h4>
<p><span style="color: #000000;">The real heavy lifting of this procedure is being doing through the sysindexes view.  From sysindexes, we are trying to determine the index size and the table size.  The calculation is based on dpages and used.  By summing those two fields, we will determine the size of the data in the table.  Through the used value, we will determine the size of the index by subtracting the data size from the value we get from the used value.  There are some additional qualifiers on those formulas to limit which index types will be calculated in which size calculation (i.e. datasize would be blobs, heaps and clustered indexes only).  A further calculation is used in this procedure via the use of the spt_values table.  The table is being used as a lookup to assign a pagesize value based on the value returned for the low attribute of &#8220;WINDOWS/NT.&#8221;  One could have chosen to hard code this since it is just calculating the page size and we know that a page size is ~8k.</span></p>
<h4><span style="color: #008000;">Caveat</span></h4>
<p><span style="color: #000000;">Now that I have explained what is happening with those old deprecated objects, the caveat is that the procedure has a bit of logic in there to check for the version of SQL Server.  Depending on the version, you could end up running the calculations based off the new objects.  However, that does not eliminate the dependency on the compatibility objects.  The same kind of logic is used to calculate the size of the data, but the indexes are still calculated via the <span style="color: #008000;">sysindexes </span>view.  I find myself asking &#8220;Why Bother?&#8221;  Take a look for yourself.  I don&#8217;t see this procedure being released to a SQL 2000 environment, but it was written for backward compatibility.  That seems like a waste of resources and development time to me.  Either leave it as it was or rewrite the whole thing &#8211; that seems to make more sense to me than to make this procedure backwards compatible with the release of SQL 2005.  The only thing I could imagine is that it was done with the intent of being able to be used in a Central Management server type of configuration.</span></p>
<h3>Revision</h3>
<p>I was looking to write a query that would replace the query I posted at the beginning of this article.  As I delved into this, I knew I wanted something that would return consistent results with sp_spaceused.  I wanted to have a reliable query that was quick and used the 2005 objects and DMVs.  What I ended up with was something a bit bigger than the original query.</p>
<p>In SQL 2005, one can find a lot of information through the use of <span style="color: #008000;">sys.dm_db_index_physical_stats.  <span style="color: #000000;">This function is quite handy in many situations where <span style="color: #008000;">sysindexes </span>was used previously.  This function can be used to help determine index size as well as fragmentation levels as a couple of examples.  For this new script, I needed to return all of the same data as the old script.  I also wanted to include some additional information that I felt was beneficial to having a good insight into the database.  So let&#8217;s break this script up again like I have shown in the past.  I am reusing some code that I have demonstrated a few times for other scripts.</span></span></p>
<h4><span style="color: #008000;"><span style="color: #0000ff;">Part I</span></span></h4>
<p><span style="color: #008000;"><span style="color: #000000;">[codesyntax lang=&#8221;tsql&#8221;]</span></span></p><pre class="urvanov-syntax-highlighter-plain-tag">/* Part I */
--Drop Table #indstats
If exists (select * from tempdb.sys.objects where name like '%#indstats%')
Begin
	Drop table tempdb.dbo.#indstats
End

Begin
CREATE TABLE #indstats (
         IndStatsID Int PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,OBJECT_ID	BIGINT
);
End

INSERT INTO #indstats (IndStatsID,database_id,index_id,OBJECT_ID,IndexSizeMB)
        SELECT Row_Number() over (order by Object_id) as IndStatsID
				,database_id,index_id,OBJECT_ID
				,CONVERT(DECIMAL(19,2),(SUM(ps.page_count))) * 8 /1024 AS IndexSizeMB					--for accuracy
			FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
			GROUP BY database_id,OBJECT_ID,index_id;</pre><p>[/codesyntax]</p>
<p>I have one major departure here from how I populated this temp table in the past.  I have opted to use the windowing function Row_Number rather than an Identity value.  I made this change due to the fewer resources required to run it.  Using an Identity could require more disk IO than using the Row_Number.  I want this to run quickly and not hamper system responsiveness or system resources.  In observed testing, this change helps improve overall performance by 50%.  I tested this against SQL 2008 and SQL 2005 running different patches and on different hardware.  The overall improvement in performance was consistent.</p>
<h4><span style="color: #0000ff;">Part II</span></h4>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Part II */
declare @dbsize decimal(19,2)

set nocount on

/*
**  Summary data.
*/
begin
	select @dbsize = sum(convert(decimal(19,2),case when type = 0 then size else 0 end)) * 8/1024
		from sys.database_files

end</pre><p>[/codesyntax]</p>
<p>This bit is quite simply just so I could provide the total data file size (excluding log file).  <strong><span style="color: #ff0000;">Spoiler alert</span></strong>:  This piece of code is also used in my new script for sp_spaceused.</p>
<h4><span style="color: #0000ff;">Part III</span></h4>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">/* Part III */
Begin
	With RegData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				On p.hobt_id = a.container_id
				And a.type = 1
			LEFT Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON us.index_id = ps.index_id
				And us.database_id = ps.database_id
				And us.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	)
	, LOBData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				ON p.partition_id = a.container_id
				And a.type = 2
			LEFT Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON us.index_id = ps.index_id
				And us.database_id = ps.database_id
				And us.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	)
	, OverFlowData as (
		SELECT a.container_id,p.OBJECT_ID,p.index_id,us.database_id
			,FileGroupName = FILEGROUP_NAME(a.data_space_id)
			,TableName = OBJECT_NAME(p.OBJECT_ID)
			,NumRows = p.rows
			,UsedPages = IsNull(a.used_pages,0)
			,TotalPages = IsNull(a.total_pages,0)
			,DataSizeMB = Convert(decimal(19,2),IsNull(a.used_pages,0)) * 8/1024
			,IndexSizeMB = case when ps.index_id &amp;lt; 2 then 0 else ps.IndexSizeMB end
			,UserRequests = IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0)
			,UserUpdates = IsNull(us.user_updates,0)
			,LastUpdate = IsNull(us.last_user_update,null)
			,RatioRequestsToUpdates = CAST(IsNull(us.user_seeks,0) + IsNull(us.user_scans,0) + IsNull(us.user_lookups,0) AS REAL)
				/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
		FROM sys.allocation_units a
			Inner Join sys.partitions p
				On p.hobt_id = a.container_id
				And a.type = 3
			LEFT Outer Join sys.dm_db_index_usage_stats us
				ON us.OBJECT_ID = p.OBJECT_ID
				And us.index_id = p.index_id
				And us.database_id = DB_ID()
			Left Outer Join #indstats ps
				ON us.index_id = ps.index_id
				And us.database_id = ps.database_id
				And us.OBJECT_ID = ps.OBJECT_ID
		--WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
	), IndexSum as (
		Select a.object_id
		,AllDataSizeMB = sum(case when a.index_id in (0,1)
							Then IsNull(a.DataSizeMB,0) +  IsNull(p2.DataSizeMB,0) +  IsNull(p3.DataSizeMB,0)
							Else IsNull(p2.DataSizeMB,0) + IsNull(p3.DataSizeMB,0)
							End)
		From RegData a
			Left Outer Join LOBData p2
				ON p2.container_id = a.container_id
			Left Outer Join OverFlowData p3
				ON p3.container_id = a.container_id
		Group By a.object_id
	), SummaryInfo as (
		SELECT
			TableName = Max(a.TableName)
			,InRowDataSizeMB = sum(IsNull(a.DataSizeMB,0))
			,LOBDataSizeMB = sum(IsNull(p2.DataSizeMB,0))
			,OFlowDataSizeMB = sum(IsNull(p3.DataSizeMB,0))
			,NumRows = Max(Coalesce(a.NumRows,p2.NumRows,p3.NumRows,0))
			,AllUsedPages = sum(IsNull(a.UsedPages,0) + IsNull(p2.UsedPages,0) + IsNull(p3.UsedPages,0))
			,AllPages = sum(IsNull(a.TotalPages,0) + IsNull(p2.TotalPages,0) + IsNull(p3.TotalPages,0))
			,FreeDataSpace = convert(decimal(19,2),sum(IsNull(a.TotalPages,0) + IsNull(p2.TotalPages,0) + IsNull(p3.TotalPages,0))
							- sum(IsNull(a.UsedPages,0) + IsNull(p2.UsedPages,0) + IsNull(p3.UsedPages,0)))* 8 / 1024
			,AllDataSizeMB = Max(ids.AllDataSizeMB)
			,IndexSizeMB = Sum(IsNull(a.IndexSizeMB,0)) + sum(IsNull(p2.IndexSizeMB,0)) + sum(IsNull(p3.IndexSizeMB,0))
			,UserRequests = Avg(IsNull(a.UserRequests,0) + IsNull(p2.UserRequests,0) + IsNull(p3.UserRequests,0))
			,UserUpdates = Avg(IsNull(a.UserUpdates,0) + IsNull(p2.UserUpdates,0) + IsNull(p3.UserUpdates,0))
			,LastUpdate = Max(Coalesce(a.LastUpdate,p2.LastUpdate,p3.LastUpdate,null))
			,DatabaseSize = @dbsize
		FROM RegData a
			Left Outer Join LOBData p2
				ON p2.container_id = a.container_id
			Left Outer Join OverFlowData p3
				ON p3.container_id = a.container_id
			Left Outer Join sys.indexes i
				ON i.OBJECT_ID = a.OBJECT_ID
				And i.index_id = a.index_id
			Left Outer Join IndexSum ids
				On i.object_id = ids.object_id
		--WHERE filegroup_name(a.data_space_id) = 'Primary'
		Group by a.object_id
	)
	Select TableName,InRowDataSizeMB,LOBDataSizeMB,OFlowDataSizeMB,NumRows,AllUsedPages
			,AllPages,FreeDataSpace,AllDataSizeMB,AllDataSizeMB,AllDataSizeMB,IndexSizeMB
			,UserRequests,UserUpdates,LastUpdate,DatabaseSize
			,PercentofDB = ((IndexSizeMB + AllDataSizeMB) / DatabaseSize) * 100
		From SummaryInfo
		Order By PercentofDB desc
End</pre><p>[/codesyntax]</p>
<p>Did I mention that this was lengthier than the predecessor?  I have five CTEs doing slightly different things here with this query.  The first three are gathering the information for the different Allocation Units and the fifth is summarizing that data into a single set.  The fourth cte is used to calculate the actual data size dependent on type of index employed.  I wanted to be able to display the size of the different Allocation Units so I could get a true feel for how the database looks in a single query (with regards to size and table size).  I also thought it important to be able to determine how much activity that table is seeing.  Knowing if the table is highly active, has BLOB data, and it&#8217;s size could potentially help me in determining if that table should be in a separate filegroup and on a separate LUN.</p>
<p>I have also thrown in some additional information that will be consistent with the new script for sp_spaceused.  The additional field here is in regards to free space.  This was mostly used as a check between the two scripts to help in developing the final solutions.  I felt it useful to get an idea of how much space is available of the allocated pages.</p>
<p>The critical calculations are performed based on information retrieved from the used_pages attribute in <span style="color: #008000;">sys.allocation_units</span> and the index size returned by <span style="color: #008000;">sys.dm_db_index_physical_stats</span>.</p>
<p>I left a few lines commented out in the script mostly for demonstration purposes.  I wanted to also be able to see just the user objects (IsMsShipped = 0 ), and also to be able to filter by specific filegroup.  Those are helpful pieces based on the task at hand.</p>
<h3>Results</h3>
<p>This script resolves the issue of returning the information for all tables in a set based fashion and it does it rapidly.  In the cases that it does not perform rapidly, one can break it up into the separate segments should one decide to tweak the column set or query.  The remaining question then is &#8220;Does it match the results of sp_spaceused?&#8221;.  The answer to that is yes and no.  I will discuss that in further detail in the final installment of this series.  As the query is currently constructed, the answer is no.  However, let it be understood that the two queries are really returning different things and one may perceive them to be returning the same thing.  That is not entirely true.</p>
<p>You can download the script from <a href="http://jasonbrimhall.info/wp-content/uploads/2010/05/TableSize_JB_tablespace.zip">here</a>.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=518" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/">SQL 2005 TableSpace</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/05/sql-2005-tablespace/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Table Sizes</title>
		<link>https://jasonbrimhall.info/2010/05/03/table-sizes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=table-sizes</link>
					<comments>https://jasonbrimhall.info/2010/05/03/table-sizes/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Mon, 03 May 2010 19:06:50 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[DMV]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Table Info]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=513</guid>

					<description><![CDATA[<p>In SQL Server there are two stored procedures that help one to determine the size of a table.  One is documented and more widely popular, the other is not.  These two stored procedures are sp_spaceused [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/05/03/table-sizes/">Table Sizes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>In SQL Server there are two stored procedures that help one to determine the size of a table.  One is documented and more widely popular, the other is not.  These two stored procedures are sp_spaceused and sp_MStablespace.  Dukagjin Maloku wrote a <a href="https://www.sqlservercentral.com/blogs/sp_spaceused-sp_mstablespace">blog article</a> about the the two stored procedures in March of this year.  I don&#8217;t intend to rehash what he has covered.  What I intend is to look at the internals of the two stored procedures.  This will be the first of a multi-part series.</p>
<h3>Why?</h3>
<p>I saw a question asking how to find the table sizes for all of the tables in a database.  A few scripts were provided (one using sp_MStablespace and one using sp_spaceused).  I had been using the msTablespace version for quite some time and had never questioned it&#8217;s accuracy.  That changed when the question evolved into why do they (the two scripts) show the same results?  So, I decided I needed to figure out what is happening inside both procedures to see if I could determine a reason for the difference.  I will be comparing these on SQL Server 2008.</p>
<h3>Comparison</h3>
<h4>sp_spaceused</h4>
<p>This stored procedure has been mostly updated to use the new DMVs available since SQL 2005.  It currently relies heavily on <span style="color: #008000;">sys.dm_db_partition_stats</span>.  This procedure determines the size of the indexes by subtracting the number of pages from the number of used pages.  The idea here is that the number of Data Pages will be less than the total number of used pages.  This stored procedure does still rely on a soon to be deprecated object called <span style="color: #008000;">sysfiles</span>.  The replacement for that object would be <span style="color: #008000;">sys.database_files</span>.  The functionality would be somewhat different, in regards to how it is used in this procedure &#8211; the results are the same.  Despite that, this proc does not look to be on the replacement block any time soon.</p>
<h4>sp_MStablespace</h4>
<p>This stored procedure on the contrary does look like it will be deprecated, though I was unable to find information to back that up.  When delving into the procedure, one can quickly spot that it relies on <span style="color: #008000;">sysindexes </span>and <span style="color: #008000;">sysobjects </span>for much of its heavy lifting.  The sizing information will be coming from <span style="color: #008000;">sys.partitions</span>, <span style="color: #008000;">sys.allocation_units</span> and <span style="color: #008000;">sysindexes</span>.  This procedure uses <span style="color: #008000;">sysindexes </span>mostly for that sizing information and then calculates the data size based on clustered indexes and heaps.  Then to calculate the remaining index size, it subtracts that size from the total for all of the indexes on the specified table.  The math is a bit different and can be the reason for the difference.  This procedure seems to be in need of a decent sized overhaul if expected to not be deprecated.</p>
<h3>Findings</h3>
<p>After looking at the code and then running some tests with each of these procedures, I was able to corroborate the claim that they don&#8217;t return the same results.  With that in hand, I decided to take a stab at writing something different to help create a consistent return.  Thus I will be sharing some queries I have been working on for each of these.  The desired goal is that both would return the same results.  Based on the consistency of information between the DMVs and the necessary (and some bonus) elements for these queries, that may be a bit more difficult to do.  For the sp_MSTablespace query, the crux of the query will be the <span style="color: #008000;">sys.dm_db_index_physical_stats</span> function, while the sp_spaceused query may continue to rely on <span style="color: #008000;">sys.dm_db_partition_stats</span> or just <span style="color: #008000;">sys.partitions</span>.  Both queries may rely on a combination of these latter two DMVs, tune in to find out.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=513" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/05/03/table-sizes/">Table Sizes</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/05/03/table-sizes/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>BLOB Index Columns</title>
		<link>https://jasonbrimhall.info/2010/04/27/blob-index-columns/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=blob-index-columns</link>
					<comments>https://jasonbrimhall.info/2010/04/27/blob-index-columns/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 27 Apr 2010 22:05:24 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[BLOB]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=495</guid>

					<description><![CDATA[<p>For the April T-SQL Tuesday, I blogged about a report to find information on the BLOBs in a database.  I have since seen a request to add to that script.  The addition would add some [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/04/27/blob-index-columns/">BLOB Index Columns</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>For the <a href="http://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/">April T-SQL Tuesday</a>, I blogged about a report to find information on the BLOBs in a database.  I have since seen a request to add to that script.  The addition would add some good information concerning the columns involved in a BLOB index.  This information is to find all of the columns that are involved in the index that includes a BLOB in the index.</p>
<h3>Base Script</h3>
<p>In that article I posted a script to help arrive at the final report.  There were a couple of things required for the setup.  I am including all of that information here in a single script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #indstats (
        indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,Object_ID	BigInt
);

INSERT INTO #indstats (database_id,index_id,object_id,IndexSizeMB)
        SELECT database_id,index_id,object_id
                ,CONVERT(DECIMAL(16,1)
                ,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
        FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
        GROUP BY database_id,object_id,index_id;

SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
	,TableName = OBJECT_NAME(p.OBJECT_ID)
        ,IndexName = i.name
        ,LOBUsedPages = a.used_pages
        ,LOBTotalPages = a.total_pages
        ,LOBDataSizeMB = a.used_pages * 8/1024
        , ps.IndexSizeMB
        , (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
        , (us.user_updates) AS UserUpdates
        , us.last_user_update AS LastUpdate
        , CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
                / CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
        ,a.type_desc AS AllocUnitType
        FROM sys.allocation_units a
                INNER Join sys.partitions p
                        ON p.partition_id = a.container_id
                        And a.type = 2                                  --LOB data is stored in pages of type Text/Image
                LEFT Outer Join sys.dm_db_index_usage_stats us
					ON us.OBJECT_ID = p.OBJECT_ID
                        And us.index_id = p.index_id
                        And us.database_id = DB_ID()
                LEFT Outer Join #indstats ps
                        ON us.index_id = ps.index_id
                        And us.database_id = ps.database_id
                        And us.OBJECT_ID = ps.OBJECT_ID
                LEFT Outer Join sys.indexes i
                        ON i.OBJECT_ID = p.OBJECT_ID
                        And i.index_id = p.index_id
        WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
                --And a.data_pages &amp;gt; 0
                --And filegroup_name(a.data_space_id) = 'Primary'
UNION
SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
        ,TableName = OBJECT_NAME(p.OBJECT_ID)
        ,IndexName = i.name
        ,LOBUsedPages = a.used_pages
        ,LOBTotalPages = a.total_pages
        ,LOBDataSizeMB = a.used_pages * 8/1024
        , ps.IndexSizeMB
        , (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
        , (us.user_updates) AS UserUpdates
        , us.last_user_update AS LastUpdate
        , CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
                / CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
        ,a.type_desc AS AllocUnitType
        FROM sys.allocation_units a
                INNER Join sys.partitions p
                        ON p.hobt_id = a.container_id
                        And a.type = 3                                  --Overflow data is stored in pages of type Text/Image
                LEFT Outer Join sys.dm_db_index_usage_stats us
                        ON us.OBJECT_ID = p.OBJECT_ID
                        And us.index_id = p.index_id
                        And us.database_id = DB_ID()
                LEFT Outer Join #indstats ps
                        ON us.index_id = ps.index_id
                        And us.database_id = ps.database_id
						And us.OBJECT_ID = ps.OBJECT_ID
                LEFT Outer Join sys.indexes i
						ON i.OBJECT_ID = p.OBJECT_ID
						And i.index_id = p.index_id
        WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
                --And filegroup_name(a.data_space_id) = 'Primary'
                --And a.data_pages &amp;gt; 0
        ORDER BY TableName ASC,a.type_desc;

GO

drop table #indstats
GO</pre><p>[/codesyntax]</p>
<p>In this script, I made a slight alteration from the article I posted.  In that article, I somehow missed a change to the script I had been testing.  That change is in the Temp table that I created (to properly support the Join statements on each side of the Union Select statement).  I simply added the object_id.</p>
<h3>The Change</h3>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #indstats (
        indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
        ,database_id BIGINT
        ,index_id BIGINT
        ,IndexSizeMB DECIMAL(16,1)
        ,Object_ID	BigInt
);

INSERT INTO #indstats (database_id,index_id,object_id,IndexSizeMB)
	SELECT database_id,index_id,object_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,object_id,index_id;
;
With IndexStuff as (
    SELECT
      icol.object_id
      ,i.name
      ,icol.index_id
      ,STUFF(
		(
			SELECT ',' + c.name AS [text()] --text should be lower case
				FROM sys.index_columns ic
					Inner Join sys.columns c
						ON ic.object_id = c.object_id
						AND ic.column_id = c.column_id
				WHERE ic.object_id = icol.object_id
					AND ic.index_id = icol.index_id
			ORDER BY ic.key_ordinal
			FOR XML PATH('')
	    ), 1, 1, '') AS ColList
	FROM sys.index_columns icol
		Inner Join sys.indexes i
			ON icol.object_id = i.object_id
			AND icol.index_id = i.index_id
    GROUP BY icol.object_id, i.name, icol.index_id
)

SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
		,TableName = OBJECT_NAME(p.OBJECT_ID)
		,IndexName = i.name
		,LOBUsedPages = a.used_pages
		,LOBTotalPages = a.total_pages
		,LOBDataSizeMB = a.used_pages * 8/1024
		, ps.IndexSizeMB
		, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
		, (us.user_updates) AS UserUpdates
		, us.last_user_update AS LastUpdate
		, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
			/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
				AS RatioRequestsToUpdates
		,a.type_desc AS AllocUnitType
		,s.collist	--Added for Column Output
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.partition_id = a.container_id
			And a.type = 2
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
		Left Outer Join IndexStuff s
			On s.object_id = i.object_id
			And s.index_id = i.index_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
UNION
	SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
		,TableName = OBJECT_NAME(p.OBJECT_ID)
		,IndexName = i.name
		,LOBUsedPages = a.used_pages
		,LOBTotalPages = a.total_pages
		,LOBDataSizeMB = a.used_pages * 8/1024
		, ps.IndexSizeMB
		, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
		, (us.user_updates) AS UserUpdates
		, us.last_user_update AS LastUpdate
		, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
			/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL)
				AS RatioRequestsToUpdates
		,a.type_desc AS AllocUnitType
		,s.ColList	--Added for Column output
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.hobt_id = a.container_id
			And a.type = 3
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
		Left Outer Join IndexStuff s
			On s.object_id = i.object_id
			And s.index_id = i.index_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0
	ORDER BY TableName ASC,a.type_desc;

GO

drop table #indstats
GO</pre><p>[/codesyntax]</p>
<p>The guts of the change to add in the columns for this script comes with the following segment of code.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">With IndexStuff as (
    SELECT
      icol.object_id
      ,i.name
      ,icol.index_id
      ,STUFF(
		(
			SELECT ',' + c.name AS [text()] --text should be lower case
				FROM sys.index_columns ic
					Inner Join sys.columns c
						ON ic.object_id = c.object_id
						AND ic.column_id = c.column_id
				WHERE ic.object_id = icol.object_id
					AND ic.index_id = icol.index_id
			ORDER BY ic.key_ordinal
			FOR XML PATH('')
	    ), 1, 1, '') AS ColList
	FROM sys.index_columns icol
		Inner Join sys.indexes i
			ON icol.object_id = i.object_id
			AND icol.index_id = i.index_id
    GROUP BY icol.object_id, i.name, icol.index_id
)</pre><p>[/codesyntax]</p>
<p>With that snippet, I also needed to Join it to the select statements, and thus it was added on both sides of the Union statement as illustrated in the next example.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">Left Outer Join IndexStuff s
			On s.object_id = i.object_id
			And s.index_id = i.index_id</pre><p>[/codesyntax]</p>
<p>In the above CTE, you will note that I used the STUFF function along with a FOR XML Path statement.  The combination of these statements allows one to concatenate a list into a comma separated list as I have done with the ColList (column list) column.  I also want to note here that I am using the text() keyword along with the FOR XML Path.  There are other methods of returning information back to the screen when using FOR XML Path.  I chose to use the text() in this case because I am just returning a concatenated list of columns that really only should read as text.  If I were returning a SQL statement, I would choose a different method to make the text more readable.</p>
<h3>Conclusion</h3>
<p>I chose to make this subtle change via the CTE due to the ease of understanding and readability of the code for me.  By illustrating the columns involved in an index that is on a BLOB column, one can gain greater insight into the use of the database.  I am glad that this change was requested because it makes sense to me.</p>
<p>I hope you find it useful.</p>
<p>Edit: Made a correction to the first script</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=495" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/04/27/blob-index-columns/">BLOB Index Columns</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/04/27/blob-index-columns/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Index Stats Duplication</title>
		<link>https://jasonbrimhall.info/2010/04/21/index-stats-duplication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=index-stats-duplication</link>
					<comments>https://jasonbrimhall.info/2010/04/21/index-stats-duplication/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Thu, 22 Apr 2010 06:00:39 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[Index]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=491</guid>

					<description><![CDATA[<p>I came across a recent posting about seeing multiple entries in sys.dm_db_index_usage_stats for the same index.  This kind of behavior can be somewhat concerning since that view should have a unique entry for each index. [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/04/21/index-stats-duplication/">Index Stats Duplication</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>I came across a recent posting about seeing multiple entries in <span style="color: #008000;">sys.dm_db_index_usage_stats</span> for the same index.  This kind of behavior can be somewhat concerning since that view should have a unique entry for each index.  As described by Microsoft, this view</p>
<p style="padding-left: 30px;"><strong><em>&#8220;Returns counts of different types of index operations and the time each type of operation was last performed.&#8221; </em></strong></p>
<p>You can read more about it <a href="http://msdn.microsoft.com/en-us/library/ms188755.aspx">here</a>.  Further in the same document, one will read</p>
<p style="padding-left: 30px;"><strong><em>&#8220;When an index is used, a row is added to </em></strong><strong><em>sys.dm_db_index_usage_stats</em></strong><strong><em> if a row does not already exist for the index. When the row is added, its counters are initially set to zero.&#8221;</em></strong></p>
<p>Thus, I started checking to see if I could reproduce the same sort of results.  While investigating, I determined that I should Join that view to the sys.indexes view.  Since the <span style="color: #008000;">sys.dm_db_index_usage_stats</span> view does not contain an Index Name, I felt it necessary to be able to see the name and not just a number.</p>
<p>My first run at the query to try and reproduce the results is displayed below.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select db_name(s.database_id) as DBNAME, object_name(s.object_id) as ObjectName
	, i.name as IndexName
	,user_seeks, user_scans,user_lookups,user_updates,system_seeks, system_scans
	From sys.dm_db_index_usage_stats s
		Inner Join sys.indexes i
			on i.object_id = s.object_id
			And i.index_id = s.index_id
			And s.database_id = db_id()
	Where objectproperty(s.object_id,'ISMSShipped') = 0
	Group by s.database_id,s.object_id,i.name,s.index_id, user_seeks, user_scans
		,user_lookups,user_updates,system_seeks, system_scans</pre><p>[/codesyntax]</p>
<p>Well this appears to produce results that are consistent with the description offered by Microsoft.  So I wanted to verify and added a windowing function into the mix.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select db_name(s.database_id) as DBNAME, object_name(s.object_id) as ObjectName
	, i.name as IndexName
	,user_seeks, user_scans,user_lookups,user_updates,system_seeks, system_scans
	,Row_number() over (partition by s.object_id,s.index_id order by s.index_id) as RowNum
	From sys.dm_db_index_usage_stats s
		Inner Join sys.indexes i
			on i.object_id = s.object_id
			And i.index_id = s.index_id
			And s.database_id = db_id()
	Where objectproperty(s.object_id,'ISMSShipped') = 0
	Group by s.database_id,s.object_id,i.name,s.index_id, user_seeks, user_scans
		,user_lookups,user_updates,system_seeks, system_scans</pre><p>[/codesyntax]</p>
<p>You will notice the line with <span style="color: #ff00ff;">Row_Number</span>().  This gives me a count of each time that IndexName appears in the system view.  Well, now having verified further, I still have results consistent with the documentation from Microsoft.  I decided to work backwards from this script (yeah I know).  I will reduce the number of fields I have returned and try to get a duplication on a base level and then re-expand the fields being gathered.  The next stab at this looked like the following script.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select db_name(s.database_id) as DBNAME,s.database_id, object_name(s.object_id) as ObjectName, i.name as IndexName
	,Row_number() over (partition by s.object_id,s.index_id order by s.index_id) as RowNum
	From sys.dm_db_index_usage_stats s
		Inner Join sys.indexes i
			on i.object_id = s.object_id
			And i.index_id = s.index_id
			And s.database_id = db_id()
	Where objectproperty(s.object_id,'ISMSShipped') = 0</pre><p>[/codesyntax]</p>
<p>So for this revision, I simply removed any of the counter fields and the group by clause.  I was hoping that my Group By would reveal the answer.  Lo and behold, I am still unable to reproduce the results.  Ok, time to trim a little bit more as I work backward trying to create the same results.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select object_name(s.object_id) as ObjectName, i.name as IndexName
	,Row_number() over (partition by s.object_id,s.index_id order by s.index_id) as RowNum
	From sys.dm_db_index_usage_stats s
		Inner Join sys.indexes i
			on i.object_id = s.object_id
			And i.index_id = s.index_id
	Where objectproperty(s.object_id,'ISMSShipped') = 0</pre><p>[/codesyntax]</p>
<p>This time, I removed a Join condition of s.database = <span style="color: #ff00ff;">db_id</span>() and the database_id and DatabaseName.  When I run the query now, I start to see the same results.  So the immediate indicator to me is that there is a duplication of indexes but not within the same database.  The duplication appears across different databases.  To verify, I know need to expand my query just a bit.</p>
<p>[codesyntax lang=&#8221;tsql&#8221;]</p><pre class="urvanov-syntax-highlighter-plain-tag">select db_name(s.database_id) as DBNAME,s.database_id, object_name(s.object_id) as ObjectName, i.name as IndexName
	,Row_number() over (partition by s.object_id,s.index_id order by s.index_id) as RowNum
	From sys.dm_db_index_usage_stats s
		Inner Join sys.indexes i
			on i.object_id = s.object_id
			And i.index_id = s.index_id
	Where objectproperty(s.object_id,'ISMSShipped') = 0</pre><p>[/codesyntax]</p>
<p>Here, I was able to verify that the places where RowNum did not equal one &#8211; I had an index in a different database by the same name.  Not only is the index name the same, but the Object holding that index is also the same in the other database.  Now, if I want, I can expand my query all the way back to the original query knowing that I verified that the entries in <span style="color: #008000;">sys.dm_db_index_usage_stats</span> are unique for each index.  The conclusion I would draw from this exercise is that a query can have an impact on the results displayed.  One should check and then double check to make sure the results jive.  Try the query a few different ways and see if the results are consistent.  If not, what factor in the query was changed that changed your results?</p>
<p>Or is it?</p>
<p>While exploring this further I decided to verify some of the objects in different databases.  For instance, I might see the object being reported in the ReportServer database, and then also in msdb and then again in another database.  But the object only exists in ReportServer.  Why is this happening?  My thoughts on this are currently just an educated guess.  It appears that a connection is established in one database and then makes a call to an object in a <strong>second </strong>database and causing a use against the actual index in the call to the <strong>second </strong>database.  The record gets inserted into the metadata tables that this view pulls from with each database that was touched &#8211; but each time with the object_id and index_id of the <strong>second</strong> database.  Does that make sense?</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=491" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/04/21/index-stats-duplication/">Index Stats Duplication</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/04/21/index-stats-duplication/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Stepping Stone Cert II (ssp)</title>
		<link>https://jasonbrimhall.info/2010/04/20/stepping-stone-cert-ii-ssp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stepping-stone-cert-ii-ssp</link>
					<comments>https://jasonbrimhall.info/2010/04/20/stepping-stone-cert-ii-ssp/#respond</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 20 Apr 2010 19:24:10 +0000</pubDate>
				<category><![CDATA[SQLServerPedia Syndication]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=485</guid>

					<description><![CDATA[<p>Back on March 30, I wrote about a Stepping Stone Certification that seems to be missing between the MCM and MCITP.  I had planned on keeping regular updates about the topic on my blog and have [&#8230;]</p>
The post <a href="https://jasonbrimhall.info/2010/04/20/stepping-stone-cert-ii-ssp/">Stepping Stone Cert II (ssp)</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>Back on March 30, I wrote about a <a href="http://jasonbrimhall.info/2010/03/30/stepping-stone-cert/">Stepping Stone Certification</a> that seems to be missing between the MCM and MCITP.  I had planned on keeping regular updates about the topic on my blog and have been slacking a bit.  It is certainly time to post an update.</p>
<p>Since that post, the forum chatter has slowed a bit, but it has also been more focused.  Yes, we recently ran into a lull &#8211; but that is not an indication of the direction we hope to push with this effort.  We had been tossing the name MCJ around &#8211; that has changed.  Jack Corbett has posted a blog on the same topic, you can find his post <a href="https://www.sqlservercentral.com/blogs/pass-microsoft-and-certification">here</a>.  There has also been mention of it by Steve Jones in his blog <a href="https://www.sqlservercentral.com/blogs/what-to-do-about-certification">here</a>.</p>
<h3>Recap</h3>
<p>So what have we been up to?  We have been discussing the items listed under &#8220;Bridging the Gap&#8221; in my first article on the subject.</p>
<p>We have also been working on trying to spread the word and get a better feel for what the community wants and sees fit.  Several of us have taken the topic to our Users&#8217; Groups and presented the idea.  There has been good feedback from those groups and many are on par with what we have discussed so far.  The biggest consensus is that the MCITP means little to nothing to a lot of SQL Server Professionals, and the MCM is too restrictive for many to even attempt.  Along these same lines, a <a href="http://www.surveymonkey.com/s/HLR8V5S">SURVEY</a> has been setup with a few questions to get a general feel for how the community thinks the certification should be handled.  We really want this survey to reach as many people as possible.  The more input, the more valid the findings would be.  Please take the survey &#8211; and pass it along to anybody else who you know.</p>
<p>We have also come to a decision that we need more help from the community in getting this thing rolling.  This is a volunteer type effort and would be a pretty big commitment.  It could mean quite a bit of change for the community as well.  More information on that will be forthcoming.</p>
<p>We also think there is a need to find a good name for the certification.  We do not believe at this juncture that the MCJ would be an appropriate name.  It should be something to designate that the certification is specific to SQL Server, but that it is not endorsed / sponsored by Microsoft (Microsoft would likely not be implementing this very soon).</p>
<p>Specifics</p>
<h4>Time In Service</h4>
<p>A general consensus on this topic was reached with the following criteria.  The candidate would sign a statement attesting to this.</p>
<p>The candidate attests to a minimum of 18 months hands-on experience in SQL Server. Willfully misrepresenting (lying) about this is subject to a permanent revocation of this certification.</p>
<p>This does NOT mean an equivalent of 18 months of 8 hr days with hands-on experience; this means 18 months of any hands-on experience. This can be as a developer, DBA, or in BI (SSAS/SSIS/SSRS).</p>
<h4>Review Board</h4>
<p>The review board should be a panel of 3-5 people (with a preference for an odd number).  The review board may consist of people from local chapters, at least one member of the review board must be a disinterested party (not from the local chapter).  These reviews may be done in person, via phone conference, and may or may not include an interview of the candidate.  Anybody on the review board will be required to sign an NDA as well as some confidentiality agreements.  This would be a volunteer type position.  Those we have discussed as being qualified to be on the board would be 1.  MVPs, 2. Individuals already holding the certification, 3. Recognized industry Gurus on the topic.  These review boards may also be potentially performed at User Conferences.</p>
<p>The review board will need to review all materials pertinent to the candidate being certified.  This includes reviewing the Time in Service, Labs, presentation reviews / scores, interview, and exam scores.</p>
<h4>Renewal</h4>
<p>There are three facets to renewal.  The first facet is a need for continuing education credits.  The idea here is that the candidate will continue to contribute in the community, provide evidence of the contributions or retake exams to maintain certification.  The second facet is that the candidate will have a review after a period of time (not yet determined as to the interval of the renewal requirement) by the review board.  The third facet is closely tied to the first two facets &#8211; a review is required for any elective exams taken after the initial certification.  These exams may be counted as continuing education credits.</p>
<h4>Focus Areas for Exams</h4>
<p>There is a need to test candidates in specific areas of SQL Server.  However, a candidate need not take all of these exams.  There should be a set of core exams and then some electives.  The electives allow you to add an emphasis to your certification much the same as many Bachelors Degree programs (i.e. MCJ with an Emphasis in DR/HA).</p>
<p>TSQL</p>
<ul>
<li>Basic ANSI SQL</li>
<li>T-SQL Enhancements (from 2005/2008)</li>
<li>High performing T-SQL – Covering improvements that avoid RBAR type solutions and write code that performs extremely well.</li>
</ul>
<p>HA / DR</p>
<ul>
<li>Clustering</li>
<li>Mirroring</li>
<li>Log-Shipping</li>
<li>Backup / Restore</li>
<li>Replication</li>
</ul>
<p>Administration</p>
<ul>
<li>DMV</li>
<li>T-SQL</li>
<li>Backup / Restore</li>
<li>Indexing</li>
<li>Performance Tuning</li>
<li>Execution Plans</li>
<li>Corruption</li>
<li>Notification Services</li>
<li>Troubleshooting?</li>
</ul>
<p>BI</p>
<ul>
<li>SSIS</li>
<li>SSRS</li>
<li>SSAS Administration</li>
<li>SSAS Development</li>
</ul>
<p>SSBS &#8211; SQL Server Service Broker</p>
<ul>
<li>Not sure where to place this one.  I can see it fitting in a few spots.</li>
</ul>
<p>Development</p>
<ul>
<li>CLR</li>
<li>PowerShell</li>
<li>TSQL</li>
</ul>
<p>It has also been noted that we need to develop a curriculum with specific study materials and resources.</p>
<h3>Conclusion</h3>
<p>There are more areas to add.  We need more input on what needs to be added.  These are the groupings and notes I have to date.  I am sure I have missed something &#8211; however, this is a good amount of information.  So far, we have had some really good discussions.  We have many more good discussions to come.  I hope that this process takes on a high adoption rate and is accepted by the community.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=485" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/04/20/stepping-stone-cert-ii-ssp/">Stepping Stone Cert II (ssp)</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/04/20/stepping-stone-cert-ii-ssp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>BLOB Report T-SQL Tuesday #005- Reporting</title>
		<link>https://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=blob-report-t-sql-tuesday-005-reporting</link>
					<comments>https://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/#comments</comments>
		
		<dc:creator><![CDATA[Jason Brimhall]]></dc:creator>
		<pubDate>Tue, 13 Apr 2010 22:19:38 +0000</pubDate>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[SQLServerPedia Syndication]]></category>
		<category><![CDATA[TSQL Tuesday]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://jason.brimhall.info/?p=453</guid>

					<description><![CDATA[<p>Checking for BLOBs that were created in the Primary Filegroup by default.  To move them was a manual process and is a different topic from the crux of this one.  Since the initial report to find the BLOBs, I have evolved it somewhat to try and find the size of each object, as well as to report on the usage related with each.</p>
The post <a href="https://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/">BLOB Report T-SQL Tuesday #005- Reporting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></description>
										<content:encoded><![CDATA[<p>This month for my second submission into T-SQL Tuesday, I decided to go with something that provides some insight into the data that is being stored and the impact it may have on storage.  If you haven&#8217;t seen it by now, I made a bone-headed mistake last week by submitting my entry one week early.  That <a href="http://jasonbrimhall.info/2010/04/06/ip-and-default-trace-t-sql-tuesday-005/">entry</a> was about trying to create a report that would join information between some DMVs and the Default Trace.  I posted an <a href="http://jasonbrimhall.info/2010/04/07/how-silly/">admission about the mistake</a> as well.  That brings us to the current post.</p>
<p>This month T-SQL Tuesday (brainchild of Adam Machanic (<a href="http://sqlblog.com/blogs/adam_machanic/default.aspx" class="broken_link">blog</a> | <a href="http://twitter.com/adammachanic">Twitter</a>) is being hosted by <a href="http://sqlvariant.com/wordpress/index.php/2010/04/t-sql-tuesday-005-reporting/">Aaron Nelson</a>, and the topic is reporting.  It looks like there are a lot of submissions this month, and I am a little behind at this point.  I hope this is useful to somebody.  I know from reading the submission of <a href="http://bradsruminations.blogspot.com/2010/04/t-sql-tuesday-005-reporting.html">Brad Schulz</a>, I knew of some immediate uses for his handy little report.</p>
<h3>Background</h3>
<p>This new idea was born out of necessity for me about a year ago.  I was having a hard time finding why my primary file group was still so large after moving all of the User objects out of that filegroup and into new filegroups.  I couldn&#8217;t find the tying factor &#8211; until I checked for BLOBs that were created in the Primary Filegroup by default.  To move them was a manual process and is a different topic from the crux of this one.  Since the initial report to find the BLOBs, I have evolved it somewhat to try and find the size of each object, as well as to report on the usage related with each.  To do this, I needed to use a method I posted about in a different post about finding some <a href="http://jasonbrimhall.info/2010/03/31/index-info/">Index Information</a>.</p>
<h3>Pre-Req</h3>
<p>This is a simple requirement for later consumption by the reporting queries.  In favor of time, I am creating a populating a staging table that can be disposed of later, after the queries have been executed and the necessary information has been gleaned from them.</p><pre class="urvanov-syntax-highlighter-plain-tag">CREATE TABLE #indstats (
	indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,database_id BIGINT
	,index_id BIGINT
	,IndexSizeMB DECIMAL(16,1)
)

INSERT INTO #indstats (database_id,index_id,IndexSizeMB)
	SELECT database_id,index_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,index_id
;</pre><p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">To get things rolling I want to show what the initial query looked like.  The only point here was to show what objects held BLOB data.</span></p><pre class="urvanov-syntax-highlighter-plain-tag">Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And a.data_pages &amp;gt; 0
		--And filegroup_name(a.data_space_id) = 'Primary'
Union
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0
	Order By TableName asc</pre><p>The query requires a union select in order to find all of the BLOBS involved.  Depending on whether it is LOB or it is OverFlow_Data, the query will be different and needs to account for both types.  The views relevant to finding this information and being queried are <span style="color: #008000;"><a href="http://msdn.microsoft.com/en-us/library/ms175012.aspx">sys.partitions</a></span> and <span style="color: #008000;"><a href="http://msdn.microsoft.com/en-us/library/ms189792.aspx">sys.allocation_units</a>.  <span style="color: #000000;">This query was adequate for the initial needs in determining what was causing the bloat in my primary filegroup.  This is why it is also the base query.  Now, I would like to build on it and find more information concerning these BLOBs.</span></span></p>
<h3><span style="color: #008000;"><span style="color: #000000;">Up a Step</span></span></h3>
<p><span style="color: #008000;"><span style="color: #000000;">Using the same views as the base query and just expanding the results returned, I can calculate an approximate size for each BLOB.  This additional information is more useful to me.  This gives me a greater insight into my database objects.  The changes are quite simple, just to iterate, since the pertinent information is obtainable from the present structure of the query.</span></span></p><pre class="urvanov-syntax-highlighter-plain-tag">Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And a.data_pages &amp;gt; 0
		--And filegroup_name(a.data_space_id) = 'Primary'
Union
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0
	Order By TableName asc</pre><p>Besides the additional fields pulled into the query, you can see that I also left a couple of comment lines in the query.  This is for informational purposes.  Sometimes, I like to filter out the BLOBs by specific filegroup or by whether or not they have any data in them.</p>
<h3>Taking it to the Xtreme</h3>
<p>OK, cheesy subheading but it has been getting ingrained in my head from <a href="http://www.beachbody.com/product/fitness_programs/p90x.do?code=GWO_P90X-NAV_A">Tony Horton</a>.  This is not an advertisement for that product, but it is kinda like how I feel about the next query.  In this query I will be querying that table that was pre-populated as well as adding a view.  The view that has been added is <span style="color: #008000;">sys.dm_db_index_usage_stats</span>.  I am also querying these via a Left Outer Join.  I want to return the additional reporting fields for the BLOB related items even if there is not index statistics associated with it.  With these additional objects added to the base query, I have also added a handful of fields to return in the report.</p>
<p>And now the beef of the query.</p><pre class="urvanov-syntax-highlighter-plain-tag">Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And a.data_pages &amp;gt; 0
		--And filegroup_name(a.data_space_id) = 'Primary'
Union
Select FileGroupName = filegroup_name(a.data_space_id)
	,TableName = object_name(p.object_id)
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType
	From sys.allocation_units a
		Inner Join sys.partitions p
			On p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		Left Outer Join sys.dm_db_index_usage_stats us
			On us.object_id = p.object_id
			And us.index_id = p.index_id
			And us.database_id = db_id()
		Left Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.object_id = ps.object_id
		Left Outer Join sys.indexes i
			On i.object_id = p.object_id
			And i.index_id = p.index_id
	Where OBJECTPROPERTY(p.object_id,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages &amp;gt; 0
	Order By TableName asc,a.type_desc</pre><p>The fields that I added to the above query are listed below.</p><pre class="urvanov-syntax-highlighter-plain-tag">, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc as AllocUnitType</pre><p>The field that I considered omitting is the ps.IndexSizeMB.  This field reports the size of the Index and not necessarily the size of BLOB data.  I decided to keep it because it can prove useful when trying to determine where the bloat may or may not be.  I also added the type_desc field so I could determine the type of data reported in the query.  Without this field, I think it would be too easy to dismiss some of the entries as duplicates when they really should be present in the report.  The others are information on the usage of the data related to the index and BLOB data.</p>
<h3>Conclusion</h3>
<p>As you run these queries you will find that there are useful tidbits of information for administrative reporting purposes.  It should also be noted that running the final query will produce the same index usage info for an Index involved in the two types of BLOB data being reported.  It will not split out the UserRequests (for instance) that are performed against LOB_DATA versus ROW_OVERFLOW_DATA.  This can create a reporting problem / mis-perception if one is not aware of it first.</p>
<p>Scripts can be downloaded <a href="http://jasonbrimhall.info/wp-content/uploads/2010/04/TSQL-Tuesday-Reporting.zip">here</a>.</p>
<p><strong>Edit</strong>: Added the scripts for download.</p>
 <img src="https://jasonbrimhall.info/?feed-stats-post-id=453" width="1" height="1" style="display: none;" />The post <a href="https://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/">BLOB Report T-SQL Tuesday #005- Reporting</a> first appeared on <a href="https://jasonbrimhall.info">SQL RNNR</a>.<div id="crp_related"> </div>]]></content:encoded>
					
					<wfw:commentRss>https://jasonbrimhall.info/2010/04/13/blob-report-t-sql-tuesday-005-reporting/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
