<?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>SQL Slayer &#187; Audit</title>
	<atom:link href="http://www.sqlslayer.com/wp/category/audit/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sqlslayer.com/wp</link>
	<description>Making SQL do what we want it to do.</description>
	<lastBuildDate>Mon, 12 Dec 2011 13:53:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>An alternative to triggers</title>
		<link>http://www.sqlslayer.com/wp/2009/10/07/an-alternative-to-triggers/</link>
		<comments>http://www.sqlslayer.com/wp/2009/10/07/an-alternative-to-triggers/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 00:52:38 +0000</pubDate>
		<dc:creator>buckleyc</dc:creator>
				<category><![CDATA[Audit]]></category>

		<guid isPermaLink="false">http://www.sqlslayer.com/wp/?p=103</guid>
		<description><![CDATA[<p>As we all know, and some of us hate, triggers are not the best thing for performance. Enter SQL 2005+ with the Output clause.</p>
<p>Here is the scenario. You have a table that is transactional. You only care about the most recent record for your system, but need to have historical data available for reporting and/or [...]]]></description>
			<content:encoded><![CDATA[<p>As we all know, and some of us hate, triggers are not the best thing for performance. Enter SQL 2005+ with the Output clause.</p>
<p>Here is the scenario. You have a table that is transactional. You only care about the most recent record for your system, but need to have historical data available for reporting and/or auditing purposes. The prior developer created a trigger on the primary table that inserts the old information into an audit table on update of the primary table. That&#8217;s not a bad solution, but there is an alternative that will work as well.  Below is a very simple example of how this may work.</p>
<blockquote><p>IF OBJECT_ID(&#8217;tempdb..#Current&#8217;) IS NOT NULL<br />
DROP TABLE #Current</p>
<p>IF OBJECT_ID(&#8217;tempdb..#Hist&#8217;) IS NOT NULL<br />
DROP TABLE #Hist</p>
<p>CREATE TABLE #Current(ID int IDENTITY(1,1) , Key varchar(20), Val varchar(255))<br />
CREATE TABLE #Hist(HistID int IDENTITY(1,1) ,OriginalID int, Key varchar(20), Val varchar(255))</p>
<p>INSERT INTO #Current(Key,Val) VALUES(&#8217;Root Dir&#8217;,'X:\Files&#8217;)<br />
INSERT INTO #Current(Key,Val) VALUES(&#8217;Temp Dir&#8217;,'C:\&#8217;)</p>
<p>SELECT ID,Key,Val FROM #Current</p>
<p>&#8211; now we realise that C:\ is not the correct value for the temp dir setting, we want to update it but track history&#8230;</p>
<p>UPDATE #Current<br />
SET Val = &#8216;C:\Temp\&#8217;<br />
OUTPUT DELETED.ID,DELETED.Key,DELETED.Val INTO #Hist(OriginalId,Key,Val)<br />
WHERE Key = &#8216;Temp Dir&#8217;</p>
<p>SELECT ID, Key, Val FROM #Current<br />
SELECT HistId,OriginalId,Key,Val FROM #Hist<br />
IF OBJECT_ID(&#8217;tempdb..#Current&#8217;) IS NOT NULL<br />
DROP TABLE #Current</p>
<p>IF OBJECT_ID(&#8217;tempdb..#Hist&#8217;) IS NOT NULL<br />
DROP TABLE #Hist</p>
<p>CREATE TABLE #Current(ID int IDENTITY(1,1) , Key varchar(20), Val varchar(255))<br />
CREATE TABLE #Hist(HistID int IDENTITY(1,1) ,OriginalID int, Key varchar(20), Val varchar(255))</p>
<p>INSERT INTO #Current(Key,Val) VALUES(&#8217;Root Dir&#8217;,'X:\Files&#8217;)<br />
INSERT INTO #Current(Key,Val) VALUES(&#8217;Temp Dir&#8217;,'C:\&#8217;)</p>
<p>SELECT ID,Key,Val FROM #Current</p>
<p>&#8211; now we realise that C:\ is not the correct value for the temp dir setting, we want to update it but track history&#8230;</p>
<p>UPDATE #Current<br />
SET Val = &#8216;C:\Temp\&#8217;<br />
OUTPUT DELETED.ID,DELETED.Key,DELETED.Val INTO #Hist(OriginalId,Key,Val)<br />
WHERE Key = &#8216;Temp Dir&#8217;</p>
<p>SELECT ID, Key, Val FROM #Current<br />
SELECT HistId,OriginalId,Key,Val FROM #Hist</p></blockquote>
<p>This is something similar to the CDC functionality in SQL 2008 and should work better on sets of data than a trigger on the table. I hope to provide some benchmarks in a future post.</p>
<p>(NOTE: This is derrived from another post I made several months ago on my personal blog.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sqlslayer.com/wp/2009/10/07/an-alternative-to-triggers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sysperfinfo not matching up with sysprocesses</title>
		<link>http://www.sqlslayer.com/wp/2009/10/01/sysperfinfo-not-matching-up-with-sysprocesses/</link>
		<comments>http://www.sqlslayer.com/wp/2009/10/01/sysperfinfo-not-matching-up-with-sysprocesses/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 15:11:30 +0000</pubDate>
		<dc:creator>Adam Bean</dc:creator>
				<category><![CDATA[Audit]]></category>

		<guid isPermaLink="false">http://www.sqlslayer.com/wp/?p=68</guid>
		<description><![CDATA[<p>So this was an interesting one, never seen such a thing before.</p>
<p>I wrote a quick audit procedure to basically monitor connections to every instance in my environment by simply querying sysperfinfo. Well, for the most part the data is spot on. Except for two instances. The cntr_value in sysprocesses for counter_name = &#8216;user connections&#8217; is [...]]]></description>
			<content:encoded><![CDATA[<p>So this was an interesting one, never seen such a thing before.</p>
<p>I wrote a quick audit procedure to basically monitor connections to every instance in my environment by simply querying sysperfinfo. Well, for the most part the data is spot on. Except for two instances. The cntr_value in sysprocesses for counter_name = &#8216;user connections&#8217; is showing about 2,000 for two instances yet sysprocesses shows no more than 30-40 at a time for these instances. I have verified that using perfmon on the server, does indeed report the same number that sysperfinfo does.</p>
<p>I am polling data from over 200 instances, and only these two are showing inaccurate numbers. To add to the mystery, these servers are pretty much the same. One is a virtual and one is a physical, with the exact same layout, databases, etc. The virtual was to be a proof of concept that the physical could be turned into a virtual. The physical is in use whereas the virtual is not, yet they both have this same problem in regards to sysperfinfo not being anywhere near the actual number of connections, and the number for both is extremely high.</p>
<p>Wasn&#8217;t able to find much of anything relevant online, so I restarted the instance and the counters in sysperfinfo went back to normal. They now match sysprocesses. I&#8217;m going to keep an eye on this to see if the problem returns, but for now, all is well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sqlslayer.com/wp/2009/10/01/sysperfinfo-not-matching-up-with-sysprocesses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

