<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-2067954702285078279</atom:id><lastBuildDate>Wed, 01 Oct 2014 06:14:38 +0000</lastBuildDate><category>E-Book</category><category>Free</category><category>70-445</category><category>Code Camp</category><category>For XML</category><category>MS-Press</category><category>Profiler</category><category>SDS</category><category>SQL</category><category>SQL Rank() Adventureworks Sample</category><category>SQL in the cloud</category><category>SSIS</category><category>TDS</category><category>Tabular Data Stream</category><category>alive</category><category>certification</category><category>first</category><category>moved</category><category>send_DBEmail</category><title>B.I. for the SQL Guy</title><description></description><link>http://sqljohn.blogspot.com/</link><managingEditor>noreply@blogger.com (John)</managingEditor><generator>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-7307542160218185969</guid><pubDate>Fri, 27 Aug 2010 02:51:00 +0000</pubDate><atom:updated>2010-08-27T13:37:48.507+10:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">moved</category><title>Blog Moved</title><description>After using the wordpress platform for another Blog i have decided to move this blog there. All content and comments here, to date, will appear over there as well&lt;br /&gt;&lt;br /&gt;Please point your browser to &lt;a href=&quot;http://sqljohn.wordpress.com&quot;&gt;http://sqljohn.wordpress.com&lt;/a&gt;, where you can also subscribe via a button or by using the RSS feed from here &lt;a href=&quot;http://sqljohn.wordpress.com/feed/&quot;&gt;http://sqljohn.wordpress.com/feed/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There will be a new post series that will be popping very shortly that is all about performance monitoring.</description><link>http://sqljohn.blogspot.com/2010/08/blog-moved.html</link><author>noreply@blogger.com (John)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-804001202332760564</guid><pubDate>Tue, 06 Apr 2010 05:05:00 +0000</pubDate><atom:updated>2010-04-06T15:09:53.903+10:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">alive</category><title>Oh I, oh, I&#39;m still alive</title><description>Just a very quick note to say that, although it seems otherwise, i am still alive and wanting to contribute to this blog.&lt;br /&gt;&lt;br /&gt;Unfortunately work and life infringed upon my blogging time to the point where i did not have the chance to write up my materials from the code camp presentation. I am now going to allocate time for this and hope to have it up in the next couple of weeks (it is 3/4s done).&lt;br /&gt;&lt;br /&gt;As penance, once it is up, i would like to video capture the presentation as well and post that too.</description><link>http://sqljohn.blogspot.com/2010/04/oh-i-oh-im-still-alive.html</link><author>noreply@blogger.com (John)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-3504711375492907244</guid><pubDate>Sun, 11 Oct 2009 21:54:00 +0000</pubDate><atom:updated>2009-10-12T09:02:46.288+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Code Camp</category><title>SDU Code Camp Material</title><description>This is just a short note to let those that are looking for the material from my &lt;a href=&quot;http://www.sqldownunder.com/SDUCodeCamp/tabid/100/Default.aspx&quot;&gt;SQL Code Camp 09&lt;/a&gt; presentation on SSIS debugging know that it will be placed here during this week. &lt;br /&gt;&lt;br /&gt;I will break down the presentation into separate posts on Breakpoints, Data Viewer and Error Redirection. There will also be a short post on extracting information from the filename and storing this into a variable (one of the tasks in the package) at the request of one of the attendees.&lt;br /&gt;&lt;br /&gt;Finally, thanks to &lt;a href=&quot;http://www.lobsterpot.com.au/&quot;&gt;Rob Farley&lt;/a&gt; for his support and tips on my presentation and to &lt;a href=&quot;http://sqlblog.com/blogs/greg_low/default.aspx&quot;&gt;Greg Low &lt;/a&gt;for giving me the opportunity to present.</description><link>http://sqljohn.blogspot.com/2009/10/sdu-code-camp-material.html</link><author>noreply@blogger.com (John)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-2236548934485257494</guid><pubDate>Tue, 10 Mar 2009 23:24:00 +0000</pubDate><atom:updated>2009-03-11T10:30:50.554+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SDS</category><category domain="http://www.blogger.com/atom/ns#">SQL</category><category domain="http://www.blogger.com/atom/ns#">SQL in the cloud</category><category domain="http://www.blogger.com/atom/ns#">Tabular Data Stream</category><category domain="http://www.blogger.com/atom/ns#">TDS</category><title>A Storm is brewing,  no wait,  its SQL in the cloud</title><description>SQL Data Services (SDS) has been available as a cloud service but until now we have been told it is NOT SQL Server in the cloud and is not to be seen as a RDBMS.  There has since been a big change to that with the announcement that SDS will be enchanced with TDS,  yay another TLA, TDS = Tabular Data Stream, or, a full RBBMS in the cloud.&lt;br /&gt;&lt;br /&gt;The SQL Data Services Team blog lists, among other features:&lt;br /&gt;Tables?...Check&lt;br /&gt;&lt;br /&gt;                Stored Procedures?...Check&lt;br /&gt;&lt;br /&gt;                Triggers?...Check&lt;br /&gt;&lt;br /&gt;                Views?...Check&lt;br /&gt;&lt;br /&gt;                Indexes?...Check&lt;br /&gt;&lt;br /&gt;                Visual Studio Compatibility?...Check&lt;br /&gt;&lt;br /&gt;                ADO.Net Compatibility?...Check&lt;br /&gt;&lt;br /&gt;                ODBC Compatibility?...Check&lt;br /&gt;&lt;br /&gt;so there we have it,  apparently you can just point your connection string towards the gathering clouds and thats it.  Time to run a demo on this i think, coming soon....&lt;br /&gt;&lt;br /&gt;The full announcment is available &lt;a href=&quot;http://blogs.msdn.com/ssds/archive/2009/03/10/9469228.aspx&quot;&gt;here &lt;/a&gt;.</description><link>http://sqljohn.blogspot.com/2009/03/storm-is-brewing-no-wait-its-sql-in.html</link><author>noreply@blogger.com (John)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-8622426455007466473</guid><pubDate>Wed, 18 Feb 2009 01:46:00 +0000</pubDate><atom:updated>2009-02-25T21:26:11.991+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Rank() Adventureworks Sample</category><title>Rank makes things less rank</title><description>A query that has popped up a few times is to retrieve a list of people along with the first/last/top sale that they have made. If we were after the last sale ever made, this query would be simple, utilising top we would order by the relevant column and get the top 1, done. However in this case we want the top item PER person, not per the entire set, this is where Rank() comes into play.&lt;br /&gt;&lt;br /&gt;Using Rank we can avoid iterating through our data with cursors to achieve this query in a single set operation.&lt;br /&gt;&lt;br /&gt;Lets use adventureWorks and retrieve the last sale date made by each of our salespeople.&lt;br /&gt;&lt;br /&gt;Our first step is to get all of our sales people and the orders they made:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;select &lt;br /&gt;    SOH.OrderDate,&lt;br /&gt;    SOH.SalesPersonID, &lt;br /&gt;    vEmp.FirstName + &#39; &#39; + vEmp.LastName Employee&lt;br /&gt;from &lt;br /&gt;    Sales.SalesOrderHeader SOH&lt;br /&gt;    inner join Sales.SalesPerson SP on SOH.SalesPersonID = SP.SalesPersonID&lt;br /&gt;    inner join HumanResources.vEmployee vEmp on SP.SalesPersonID  = vEmp.EmployeeID&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_p4ZOgKaZik0/SaUa8lVycKI/AAAAAAAAACU/FMz2r7jZTqA/s1600-h/rank1.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 230px;&quot; src=&quot;http://4.bp.blogspot.com/_p4ZOgKaZik0/SaUa8lVycKI/AAAAAAAAACU/FMz2r7jZTqA/s320/rank1.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5306677364043968674&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we would like to provide away to determine which OrderDate is the latest, per SalesPerson. This is where rank comes into play:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;select &lt;br /&gt;    SOH.OrderDate,&lt;br /&gt;    SOH.SalesPersonID, &lt;br /&gt;    vEmp.FirstName + &#39; &#39; + vEmp.LastName Employee,&lt;br /&gt;    rank() over(Partition by SOH.SalesPersonID order by OrderDate desc) OrderRank&lt;br /&gt;from &lt;br /&gt;    Sales.SalesOrderHeader SOH&lt;br /&gt;    inner join Sales.SalesPerson SP on SOH.SalesPersonID = SP.SalesPersonID&lt;br /&gt;    inner join HumanResources.vEmployee vEmp on SP.SalesPersonID  = vEmp.EmployeeID&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_p4ZOgKaZik0/SaUbbOcTzeI/AAAAAAAAACc/GDkMXEAw4DU/s1600-h/rank2.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 187px;&quot; src=&quot;http://3.bp.blogspot.com/_p4ZOgKaZik0/SaUbbOcTzeI/AAAAAAAAACc/GDkMXEAw4DU/s320/rank2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5306677890473250274&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;the key section is:&lt;br /&gt;&lt;br /&gt;rank() over(Partition by SOH.SalesPersonID order by OrderDate desc) OrderRank&lt;br /&gt;&lt;br /&gt;this now gives us a machanism for determining, per SalesPerson, which order was the latest, it will be the order with a OrderRank of 1.&lt;br /&gt;&lt;br /&gt;Breaking down the function, the key parts are the partition and the order by:&lt;br /&gt;&lt;strong&gt;Partition:&lt;/strong&gt;&lt;br /&gt;Patition is analogous with &#39;Group By&#39; and is used to literally Partition our dataset to allow for multiple ordering withing the one dataset, Partitioning by the SalesPersonID will let us provide subsequent ranking based on each ID&lt;br /&gt;&lt;strong&gt;Order By&lt;/strong&gt;&lt;br /&gt;Order By is the item which will determine our ranking and is based on the set of data provided by the partition&lt;br /&gt;&lt;br /&gt;However, this still does not give us the Last order as per our request, to get the last order, we now filter the result set by OrderRank, limiting it only to those rows with a rank of 1, giving us the last order Per SalesPerson.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As Rank() is a derived column, we must select from this result set and filter the subset:&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;select&lt;br /&gt;    OrderDate, SalesPersonID, Employee&lt;br /&gt;from&lt;br /&gt;    (&lt;br /&gt;    select&lt;br /&gt;        SOH.SalesOrderID, &lt;br /&gt;        SOH.OrderDate,&lt;br /&gt;        SOH.SalesPersonID, &lt;br /&gt;        vEmp.FirstName + &#39; &#39; + vEmp.LastName Employee,&lt;br /&gt;        rank() over(Partition by SOH.SalesPersonID order by OrderDate desc) OrderRank&lt;br /&gt;    from &lt;br /&gt;        Sales.SalesOrderHeader SOH&lt;br /&gt;        inner join Sales.SalesPerson SP on SOH.SalesPersonID = SP.SalesPersonID&lt;br /&gt;        inner join HumanResources.vEmployee vEmp on SP.SalesPersonID  = vEmp.EmployeeID&lt;br /&gt;    ) RankedOrders&lt;br /&gt;where&lt;br /&gt;    RankedOrders.OrderRank = 1&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_p4ZOgKaZik0/SaUbbKSGy6I/AAAAAAAAACk/PDlfOqOadrY/s1600-h/rank3.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 197px;&quot; src=&quot;http://2.bp.blogspot.com/_p4ZOgKaZik0/SaUbbKSGy6I/AAAAAAAAACk/PDlfOqOadrY/s320/rank3.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5306677889356712866&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we &lt;i&gt;nearly&lt;/i&gt; have the last sale date of our salesperson. as we can see from the result, any items in the ranking which have the same OrderDate are given a ranking of 1, therefore we get 2 results for Stephen Jiang as he completed two order on June 1. Depending on your reporting requirements you can handle this with a more selective ranking order or in our case simply using distinct as we require the sales person and the last sale date.&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;select distinct&lt;br /&gt;    OrderDate, SalesPersonID, Employee&lt;br /&gt;from&lt;br /&gt;    (&lt;br /&gt;    select&lt;br /&gt;        SOH.SalesOrderID, &lt;br /&gt;        SOH.OrderDate,&lt;br /&gt;        SOH.SalesPersonID, &lt;br /&gt;        vEmp.FirstName + &#39; &#39; + vEmp.LastName Employee,&lt;br /&gt;        rank() over(Partition by SOH.SalesPersonID order by OrderDate desc) OrderRank&lt;br /&gt;    from &lt;br /&gt;        Sales.SalesOrderHeader SOH&lt;br /&gt;        inner join Sales.SalesPerson SP on SOH.SalesPersonID = SP.SalesPersonID&lt;br /&gt;        inner join HumanResources.vEmployee vEmp on SP.SalesPersonID  = vEmp.EmployeeID&lt;br /&gt;    ) RankedOrders&lt;br /&gt;where&lt;br /&gt;    RankedOrders.OrderRank = 1&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_p4ZOgKaZik0/SaUbbQPfiuI/AAAAAAAAACs/oCMq-psC2-g/s1600-h/rank4.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 131px;&quot; src=&quot;http://4.bp.blogspot.com/_p4ZOgKaZik0/SaUbbQPfiuI/AAAAAAAAACs/oCMq-psC2-g/s320/rank4.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5306677890956364514&quot; /&gt;&lt;/a&gt;&lt;br /&gt;And there we have it,  a much less rank way of getting the top results without having to resort to cursors.</description><link>http://sqljohn.blogspot.com/2009/02/rank-makes-things-less-rank.html</link><author>noreply@blogger.com (John)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_p4ZOgKaZik0/SaUa8lVycKI/AAAAAAAAACU/FMz2r7jZTqA/s72-c/rank1.jpg" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-7492257148546086576</guid><pubDate>Wed, 21 Jan 2009 21:59:00 +0000</pubDate><atom:updated>2009-01-22T09:06:23.634+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">E-Book</category><category domain="http://www.blogger.com/atom/ns#">Free</category><category domain="http://www.blogger.com/atom/ns#">Profiler</category><title>Free E-Book &#39;&#39;Mastering SQL Server 2005 Profiler&#39;</title><description>Looks like its a free book frenzy today, Brad McGehee from &lt;a href=&quot;http://www.red-gate.com/&quot;&gt;RedGate&lt;/a&gt; has made available his new book &#39;Mastering SQL Server 2005 Profiler&#39; from the link below.&lt;br /&gt;&lt;br /&gt;Brad is also available on &lt;a href=&quot;http://www.simple-talk.com/community/blogs/brad_mcgehee/default.aspx&quot;&gt;&#39;Simple-Talk&#39; &lt;/a&gt; and &lt;a href=&quot;http://twitter.com/bradmcgehee&quot;&gt;&#39;Twitter&#39;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.red-gate.com/products/SQL_Response/offers/mastering_sql_profiler_ebook.htm&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 246px; height: 320px;&quot; src=&quot;http://3.bp.blogspot.com/_p4ZOgKaZik0/SXeb8QXUIHI/AAAAAAAAACE/GLIWpaHRUQw/s320/profiler.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5293871346484519026&quot; /&gt;&lt;/a&gt;</description><link>http://sqljohn.blogspot.com/2009/01/free-e-book-mastering-sql-server-2005.html</link><author>noreply@blogger.com (John)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_p4ZOgKaZik0/SXeb8QXUIHI/AAAAAAAAACE/GLIWpaHRUQw/s72-c/profiler.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-6723070750924911908</guid><pubDate>Wed, 21 Jan 2009 21:23:00 +0000</pubDate><atom:updated>2009-01-22T09:19:28.504+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">E-Book</category><category domain="http://www.blogger.com/atom/ns#">Free</category><category domain="http://www.blogger.com/atom/ns#">MS-Press</category><category domain="http://www.blogger.com/atom/ns#">SSIS</category><title>Free SSIS 2005 E-Book from MS-Press</title><description>Its not often that you can get something for nothing but the good folks at MS-Press have made SQL Server 2005 Integration Services - Step By Step available as a free download from the link below, you do have to register to receive it but im sure most people interested in its contents already receive some mails from MS.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://csna01.libredigital.com/?urrs4gt63d&quot;&gt;&lt;p align=&quot;center&quot;&gt;&lt;img id=&quot;BLOGGER_PHOTO_ID_5293862108506121426&quot; alt=&quot;Free SSIS Book&quot; src=&quot;http://4.bp.blogspot.com/_p4ZOgKaZik0/SXeTiiNoZNI/AAAAAAAAAB8/vqL-0Bct5uw/s320/ssis.jpg&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://sqljohn.blogspot.com/2009/01/free-ssis-2005-e-book-from-ms-press.html</link><author>noreply@blogger.com (John)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_p4ZOgKaZik0/SXeTiiNoZNI/AAAAAAAAAB8/vqL-0Bct5uw/s72-c/ssis.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-2979052620620413435</guid><pubDate>Fri, 09 Jan 2009 05:49:00 +0000</pubDate><atom:updated>2009-01-20T17:45:08.375+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">70-445</category><category domain="http://www.blogger.com/atom/ns#">certification</category><title>Starting to Study for MCTS 70-445 BI exam</title><description>Thanks to &lt;a href=&quot;http://blogs.msdn.com/acoat/archive/2009/01/07/want-help-with-that-new-years-resolution-take-a-free-certification-test.aspx&quot;&gt;Andrew Coates&lt;/a&gt;, who has kindly sent me a voucher for a exam, i am jumping straight back into study with 70-445. This is the 2005 flavour of &quot;Business Intelligence - Implementation and Maintenance&quot;, i already had my eye on the 2008 version but considering the study material is not released until April 1, I will go with 2005. This is not a major issue as my MCITP is in 2005 and i think its good to keep them all in sync.&lt;br /&gt;&lt;br /&gt;My first step is to grab a copy of the &lt;a href=&quot;http://www.microsoft.com/learning/en/us/books/8731.aspx&quot;&gt;MSPress Training Kit&lt;/a&gt;, i have used these kits for all my previous exams so will stick with them. after reading through this and doing all the exercises plus plenty of extra hands on work ill grab a sample exam from &lt;a href=&quot;http://www.selftestsoftware.com/dept.aspx?dept_id=1000&quot;&gt;Self-test&lt;/a&gt;, who i have also used before, and ensure that i get around 90-95% before booking the exam with Coatsies magic ticket.&lt;br /&gt;&lt;br /&gt;So you can expect to see plenty of blog posts as i work through the material. Fingers Crossed :)&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Thanks again to Andrew for the voucher.&lt;/em&gt;</description><link>http://sqljohn.blogspot.com/2009/01/starting-to-study-for-mcts-70-445-bi.html</link><author>noreply@blogger.com (John)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-8329297734459921847</guid><pubDate>Thu, 08 Jan 2009 10:36:00 +0000</pubDate><atom:updated>2009-10-12T09:10:24.220+11:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">For XML</category><category domain="http://www.blogger.com/atom/ns#">send_DBEmail</category><title>Sending &#39;FOR XML&#39; into work for the post office</title><description>One way that HTML based email bodys have been constructed is by iterating through a cursor and building your HTML with each row, the trouble with this method is that it does not scale very well. In order to over come the lineal growth of a cursor, we can utilise &#39;For XML&#39; and build our HTML content with a set based operation. This following post will compare both methods to show how this can be done.&lt;br /&gt;&lt;br /&gt;Firstly we will build a email body using cursors and see how long this takes to run, We are simply going to build an email that lists all customers* in New South Wales, from the Adventureworks database, along with their email address and phone number.&lt;br /&gt;&lt;br /&gt;The following SQL will display this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;BORDER-BOTTOM: #999999 1px dashed; BORDER-LEFT: #999999 1px dashed; PADDING-BOTTOM: 5px; LINE-HEIGHT: 14px; BACKGROUND-COLOR: #eee; PADDING-LEFT: 5px; WIDTH: 100%; PADDING-RIGHT: 5px; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; COLOR: #000000; FONT-SIZE: 12px; OVERFLOW: auto; BORDER-TOP: #999999 1px dashed; BORDER-RIGHT: #999999 1px dashed; PADDING-TOP: 5px&quot;&gt;&lt;code&gt;select&lt;br /&gt;    distinct&lt;br /&gt;    ltrim(isnull(Title,&#39;&#39;) + &#39; &#39; + FirstName + &#39; &#39; + LastName)CustomerName, &lt;br /&gt;    Phone, &lt;br /&gt;    EmailAddress&lt;br /&gt;from&lt;br /&gt;    Sales.vIndividualCustomer&lt;br /&gt;where&lt;br /&gt;    StateProvinceName = &#39;New South Wales&#39; &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This must now be built into a cursor and iterated in order to build our HTML:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;Declare @Body as varchar(max)&lt;br /&gt;&lt;br /&gt;set @Body = &#39;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&#39; + &lt;br /&gt;            &#39;&amp;lt;h1&amp;gt;NSW Customers&amp;lt;/h1&amp;gt;&lt;br /&gt;            &#39; + &#39;&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&#39; &lt;br /&gt;            &lt;br /&gt;DECLARE Customers Cursor FAST_FORWARD FOR &lt;br /&gt;    select &lt;br /&gt;        distinct&lt;br /&gt;        ltrim(isnull(Title,&#39;&#39;) + &#39; &#39; + FirstName + &#39; &#39; + LastName) CustomerName,&lt;br /&gt;        Phone,&lt;br /&gt;        EmailAddress &lt;br /&gt;    from &lt;br /&gt;        Sales.vIndividualCustomer &lt;br /&gt;    where&lt;br /&gt;    StateProvinceName = &#39;New South Wales&#39;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Declare @CustomerName varchar(200), &lt;br /&gt;        @Phone varchar(25), &lt;br /&gt;        @EmailAddress varchar(50) &lt;br /&gt;&lt;br /&gt;open Customers &lt;br /&gt;Fetch Next From Customers into @CustomerName, @Phone, @EmailAddress &lt;br /&gt;&lt;br /&gt;while @@Fetch_STatus = 0 &lt;br /&gt;begin &lt;br /&gt;    set &lt;br /&gt;        @Body = @body + &#39;&amp;lt;tr&amp;gt; &#39; &lt;br /&gt;                + &#39;&amp;lt;td&amp;gt;&#39; + @CustomerName + &#39;&amp;lt;/td&amp;gt;&#39; &lt;br /&gt;                + &#39;&amp;lt;td&amp;gt;&#39; + @Phone + &#39;&amp;lt;/td&amp;gt;&#39; &lt;br /&gt;                + &#39;&amp;lt;td&amp;gt;&#39; + @EmailAddress + &#39;&amp;lt;/td&amp;gt;&#39; &lt;br /&gt;                + &#39;&amp;lt;/tr&amp;gt;&#39; &lt;br /&gt;    Fetch Next from Customers into @CustomerName, @Phone, @EmailAddress &lt;br /&gt;end &lt;br /&gt;&lt;br /&gt;close Customers &lt;br /&gt;Deallocate Customers &lt;br /&gt;&lt;br /&gt;set @body = @body + &#39;&amp;lt;/table&amp;gt;&#39; &lt;br /&gt;&lt;br /&gt;EXEC msdb.dbo.sp_send_dbmail &lt;br /&gt;    @profile_name = &#39;AdventureWorksProfile&#39;,&lt;br /&gt;    @recipients=&#39;adventureJo@adventure-works.com&#39;,&lt;br /&gt;    @subject = &#39;NSW Customers&#39;,&lt;br /&gt;    @body = @body,&lt;br /&gt;    @body_format = &#39;HTML&#39; ;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above approach using cursors works as expected and emails our report to the sales manager, however it is not going to scale very well, a more scalable solution is to generate the same html but using a set operation, utilising For XML as below&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style=&quot;font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%&quot;&gt;&lt;code&gt;&lt;br /&gt;DECLARE @body           varchar(max),&lt;br /&gt;          @Subject    varchar(255)&lt;br /&gt;          &lt;br /&gt;SET @body = &lt;br /&gt;    N&#39;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;H1&amp;gt;NSW Customers&amp;lt;/H1&amp;gt;&#39; +&lt;br /&gt;    &#39;&amp;lt;table border=&amp;quot;1&amp;quot;&amp;gt;&#39; +&lt;br /&gt;    &#39;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Customer Name&amp;lt;/th&amp;gt;&#39; +&lt;br /&gt;    &#39;&amp;lt;th&amp;gt;Phone&amp;lt;/th&amp;gt;&#39; +&lt;br /&gt;    &#39;&amp;lt;th&amp;gt;EmailAddress&amp;lt;/th&amp;gt;&#39; +&lt;br /&gt;    (select&lt;br /&gt;        Distinct&lt;br /&gt;        ltrim(isnull(Title,&#39;&#39;) + &#39; &#39; + FirstName + &#39; &#39; + LastName) td, &#39;&#39;, &lt;br /&gt;        Phone td, &#39;&#39;, &lt;br /&gt;        EmailAddress td, &#39;&#39;&lt;br /&gt;    from &lt;br /&gt;        Sales.vIndividualCustomer &lt;br /&gt;    where&lt;br /&gt;        StateProvinceName = &#39;New South Wales&#39;&lt;br /&gt;    FOR XML PATH(&#39;tr&#39;)) + &lt;br /&gt;    N&#39;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&#39;&lt;br /&gt;&lt;br /&gt;EXEC msdb.dbo.sp_send_dbmail &lt;br /&gt;    @profile_name = &#39;AdventureWorksProfile&#39;,&lt;br /&gt;    @recipients=&#39;adventureJo@adventure-works.com&#39;,&lt;br /&gt;    @subject = &#39;NSW Customers&#39;,&lt;br /&gt;    @body = @body,&lt;br /&gt;    @body_format = &#39;HTML&#39; ;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code generates the same email many times faster with a lighter impact on our server, moreso, it is scalable as promised.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_p4ZOgKaZik0/SWXV3GxVeoI/AAAAAAAAAB0/o0vs6Xu-b5I/s1600-h/emailshot.jpg&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 229px;&quot; src=&quot;http://1.bp.blogspot.com/_p4ZOgKaZik0/SWXV3GxVeoI/AAAAAAAAAB0/o0vs6Xu-b5I/s320/emailshot.jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5288868480103578242&quot; /&gt;&lt;/a&gt;</description><link>http://sqljohn.blogspot.com/2009/01/sending-for-xml-into-work-for-post.html</link><author>noreply@blogger.com (John)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_p4ZOgKaZik0/SWXV3GxVeoI/AAAAAAAAAB0/o0vs6Xu-b5I/s72-c/emailshot.jpg" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2067954702285078279.post-5873427199023710791</guid><pubDate>Wed, 17 Sep 2008 03:10:00 +0000</pubDate><atom:updated>2008-09-18T08:33:46.253+10:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">first</category><title>The Obligatory First Post</title><description>The best place to start is the beginning, so here it is, my blog. I think this fist post should layout the reasons for this blogs existence and what i hope to achieve with it, it will be interesting to look back at this post in the future, after a hopefully long list of posts and see how close to these original reasons i am.&lt;br /&gt;&lt;br /&gt;The main purpose for this blog is essentially to provide some focus to my pottering about with SQL Server and to note down any interesting ideas and changes within this realm. Just over 2 years ago i started an &lt;a href=&quot;http://www.itmasters.com.au/&quot;&gt;IT Masters&lt;/a&gt; program at &lt;a href=&quot;http://www.csu.edu.au/&quot;&gt;CSU&lt;/a&gt;, majoring in &lt;a href=&quot;http://www.itmasters.com.au/microsoft_sql2005_mcitp.htm&quot;&gt;SQL Server Database Design and Management&lt;/a&gt; (2005). As i am now at my last subject (Planning and Designing Database Programming Solutions Using SQL Server 2005 - Exam 70-441) i thought i needed to instigate another project to give me some focus for my learning, hence the blog.&lt;br /&gt;&lt;br /&gt;Sooo. The initial focus here will be anything with the 70-441 exam that i want to dig a bit deeper with and on passing that exam i hope to then start to play in the BI space and document my journey here.&lt;br /&gt;&lt;br /&gt;As for the blog title, well coming from a transactional and business reporting background, i have found BI fascinating whenever i have touched on it and therefore hope to delve deeper into that on this blog, so i present &#39;B.I. for the SQL Guy&#39;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://feeds.feedburner.com/sqljohn&quot; rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot;&gt;&lt;img src=&quot;http://www.feedburner.com/fb/images/pub/feed-icon16x16.png&quot; alt=&quot;&quot; style=&quot;vertical-align:middle;border:0&quot;/&gt;&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://feeds.feedburner.com/sqljohn&quot; rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot;&gt;Subscribe in a reader&lt;/a&gt;&lt;/p&gt;</description><link>http://sqljohn.blogspot.com/2008/09/obligatory-first-post.html</link><author>noreply@blogger.com (John)</author><thr:total>1</thr:total></item></channel></rss>