<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Lenni Lobel on SQL Server and .NET Development</title>
	<atom:link href="http://lennilobel.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://lennilobel.wordpress.com</link>
	<description>SQL Server, data access and general .NET development</description>
	<lastBuildDate>Tue, 26 Feb 2013 20:46:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='lennilobel.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Lenni Lobel on SQL Server and .NET Development</title>
		<link>http://lennilobel.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://lennilobel.wordpress.com/osd.xml" title="Lenni Lobel on SQL Server and .NET Development" />
	<atom:link rel='hub' href='http://lennilobel.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Book Announcement! Windows Azure SQL Database &#8211; Step By Step</title>
		<link>http://lennilobel.wordpress.com/2013/02/25/book-announcement-windows-azure-sql-database-step-by-step/</link>
		<comments>http://lennilobel.wordpress.com/2013/02/25/book-announcement-windows-azure-sql-database-step-by-step/#comments</comments>
		<pubDate>Mon, 25 Feb 2013 01:41:20 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[Community Events]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[Windows Azure]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1344</guid>
		<description><![CDATA[Just when I thought it was safe to go back in the water&#8230; I’m very happy to announce that I’ll be authoring a new book on Windows Azure SQL Database. The book, part of the Microsoft Press &#8220;Step By Step&#8221; series, is designed for readers to quickly get productive with Windows Azure SQL Database &#8212; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1344&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Just when I thought it was safe to go back in the water&#8230;</p>
<p>I’m very happy to announce that I’ll be authoring a new book on Windows Azure SQL Database. The book, part of the Microsoft Press &#8220;Step By Step&#8221; series, is designed for readers to quickly get productive with Windows Azure SQL Database &mdash; the cloud version of SQL Server.</p>
<p>I&#8217;m especially lucky and honored to work with my friend and collegue Brian Reynolds, who is co-authoring the book with me. Brian has great knowledge and experience with the Windows Azure platform, which is sure to shine through in his chapters. Plus, I&#8217;m once again delighted to work in partnership with Craig Branning and all the wonderful folks at Tallan, Inc.</p>
<p>So who is this book for? Well, anyone interested in quickly getting up and running with SQL Database on Windows Azure. This includes not only those experienced with SQL Server, but readers having general experience with other database technologies, and even those with little to no experience at all. The Step By Step series follows an inviting format that&#8217;s chock full of quick rewards &mdash; small bits of conceptual information are presented, and that information is then immediately put to practical use by walking through a relatively short procedure, one step at a time.</p>
<p>I&#8217;m also happy that the title will once again be published by O&#8217;Reilly Media and branded as an MS Press book. Years back, O’Reilly acquired MS Press, but retained the Microsoft logo with the black and red theme, which I think we all agree looks really, really cool.</p>
<p>So (once more!) busy days lie ahead. We&#8217;re still in the early stages, so some of this could easily change somewhat, but here&#8217;s what we have planned so far to cover:</p>
<ul>
<li>Quick-Start, Setup, and Configuration</li>
<li>Security in the cloud</li>
<li>Reporting Services in the cloud</li>
<li>SQL Data Sync</li>
<li>Migration and Backup</li>
<li>Using the online management portal, and familiar tools like SSMS and SSDT</li>
<li>Programming using such tools as the Entity Framework ORM layer</li>
<li>Scalability, Federations, and Performance</li>
<li>Differences from on-premise SQL Server</li>
</ul>
<p>With luck, the book should be out by Q3 2013. I’m looking forward to the work in store, and we hope to produce the best piece of work we can. Along the way, I’ll be blogging more previews of what’s to come. So stay tuned, and thanks for reading.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1344/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1344/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1344&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2013/02/25/book-announcement-windows-azure-sql-database-step-by-step/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>New Metadata Discovery Features in SQL Server 2012</title>
		<link>http://lennilobel.wordpress.com/2012/05/29/new-metadata-discovery-features-in-sql-server-2012/</link>
		<comments>http://lennilobel.wordpress.com/2012/05/29/new-metadata-discovery-features-in-sql-server-2012/#comments</comments>
		<pubDate>Tue, 29 May 2012 00:00:49 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1320</guid>
		<description><![CDATA[It has always been possible to interrogate SQL Server for metadata (schema) information. You can easily discover all the objects in a database (tables, views, stored procedures, and so on) and their types by directly querying system tables (not recommended, as they can change from one version of SQL Server to another) or information schema [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1320&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>It has always been possible to interrogate SQL Server for metadata (schema) information. You can easily discover all the objects in a database (tables, views, stored procedures, and so on) and their types by directly querying system tables (not recommended, as they can change from one version of SQL Server to another) or information schema views (which are consistent in each SQL Server version). It is significantly more challenging, however, to discover the result set schema for T-SQL statements or stored procedures that contain conditional logic. Using <em>SET FMTONLY ON/OFF</em> has been the common technique in the past for discovering the schema of a query’s result set without actually executing the query itself. For example, consider the following code:</p>
<p><pre class="brush: plain;">USE AdventureWorks2012
GO

SET FMTONLY ON
SELECT * FROM HumanResources.Employee;
SET FMTONLY OFF</pre></p>
<p>This <em>SELECT</em> statement, which would normally return all the rows from the <em>HumanResources.Employee</em> table, returns no rows at all. It just reveals the columns. The <em>SET FMTONLY ON</em> statement prevents queries from returning rows of data so that their schemas can be discovered, and this behavior remains in effect until <em>SET FMTONLY OFF</em> is encountered. SQL Server 2012 introduces several new system stored procedures and table-valued functions (TVFs) that provide significantly richer metadata discovery than what can be discerned using the relatively inelegant (and now deprecated) <em>SET FMTONLY ON/OFF</em> approach. These new procedures and functions are:</p>
<ul>
<li>sys.sp_describe_first_result_set</li>
<li>sys.dm_exec_describe_first_result_set</li>
<li>sys.dm_exec_describe_first_result_set_for_object</li>
<li>sys.sp_describe_undeclared_parameters</li>
</ul>
<p>In this blog post, I&#8217;ll explain how to use these new objects to discover schema information in SQL Server 2012.</p>
<h3>sys.sp_describe_first_result_set</h3>
<p>The <em>sys.sp_describe_first_result_set</em> stored procedure accepts a T-SQL statement and produces a highly detailed schema description of the first possible result set returned by that statement. The following code retrieves schema information for the same <em>SELECT</em> statement you used earlier to get information on all the columns in the <em>HumanResources.Employee</em> table:</p>
<p><pre class="brush: plain;">EXEC sp_describe_first_result_set
 @tsql = N'SELECT * FROM HumanResources.Employee'</pre></p>
<p>The following screenshot shows the wealth of information that SQL Server returns about each column in the result set returned by the <em>sp_describe_first_result_set</em> call:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/05/f02xx03.png"><img title="F02xx03" src="http://lennilobel.files.wordpress.com/2012/05/f02xx03.png?w=780&#038;h=520" alt="" width="780" height="520" /></a></p>
<h3>sys.dm_exec_describe_first_result_set</h3>
<p>There is also a data management function named <em>sys.dm_exec_describe_first_result_set</em> that works very similar to <em>sys.sp_describe_first_result_set</em>. But because it is implemented as a table-valued function (TVF), it is easy to query against it and limit the metadata returned. For example, the following query examines the same T-SQL statement, but returns just the name and data type of nullable columns:</p>
<p><pre class="brush: plain;">SELECT name, system_type_name
 FROM sys.dm_exec_describe_first_result_set(
  'SELECT * FROM HumanResources.Employee', NULL, 1)
 WHERE is_nullable = 1</pre></p>
<p>Here is the output:</p>
<p><pre class="brush: plain;">name               system_type_name
-----------------  ----------------
OrganizationNode   hierarchyid
OrganizationLevel  smallint</pre></p>
<p>Parameterized queries are also supported, if you supply an appropriate parameter signature after the T-SQL. The T-SQL in the previous example had no parameters, so it passed <em>NULL</em> for the “parameters parameter.” The following example discovers the schema of a parameterized query.</p>
<p><pre class="brush: plain;">SELECT name, system_type_name, is_hidden
 FROM sys.dm_exec_describe_first_result_set('
  SELECT OrderDate, TotalDue
   FROM Sales.SalesOrderHeader
   WHERE SalesOrderID = @OrderID',
  '@OrderID int', 1)</pre></p>
<p>Here is the output:</p>
<p><pre class="brush: plain;">name             system_type_name  is_hidden
---------------  ----------------  ---------
OrderDate        datetime          0
TotalDue         money             0
SalesOrderID     int               1</pre></p>
<p>You’d be quick to question why the <em>SalesOrderID</em> column is returned for a <em>SELECT</em> statement that returns only <em>OrderDate</em> and <em>TotalDue</em>. The answer lies in the last parameter passed to the data management function. A bit value of 1 (for true) tells SQL Server to return the identifying <em>SalesOrderID</em> column, because it is used to “browse” the result set. Notice that it is marked true (1) for <em>is_hidden</em>. This informs the client that the <em>SalesOrderID</em> column is not actually revealed by the query, but can be used to uniquely identify each row in the query’s result set.</p>
<p>What if multiple result sets are possible? There’s no problem with this as long as they all have the same schema. In fact, SQL Server will even try to forgive cases where multiple possible schemas are not exactly identical. For example, if the same column is nullable in one result set and non-nullable in the other, schema discovery will succeed and indicate the column as nullable. It will even tolerate cases where the same column has a different name (but same type) between two possible result sets, and indicate <em>NULL</em> for the column name, rather than arbitrarily choosing one of the possible column names or failing altogether.</p>
<p>The following code demonstrates this with a T-SQL statement that has two possible result sets depending on the value passed in for the <em>@SortOrder</em> parameter. Because both result sets have compatible schemas, the data management function succeeds in returning schema information.</p>
<p><pre class="brush: plain;">SELECT name, system_type_name
 FROM sys.dm_exec_describe_first_result_set('
    IF @SortOrder = 1
      SELECT OrderDate, TotalDue
       FROM Sales.SalesOrderHeader
       ORDER BY SalesOrderID ASC
    ELSE IF @SortOrder = -1
      SELECT OrderDate, TotalDue
       FROM Sales.SalesOrderHeader
       ORDER BY SalesOrderID DESC',
   '@SortOrder AS tinyint', 0) </pre></p>
<p>Here is the output:</p>
<p><pre class="brush: plain;">name         system_type_name
-----------  ----------------
OrderDate    datetime
TotalDue     money</pre></p>
<p>Discovery won’t succeed if SQL Server detects incompatible schemas. In this next example, the call to the system stored procedure specifies a T-SQL statement with two possible result sets, but one returns three columns while the other returns only two columns.</p>
<p><pre class="brush: plain;">EXEC sys.sp_describe_first_result_set
  @tsql = N'
    IF @IncludeCurrencyRate = 1
      SELECT OrderDate, TotalDue, CurrencyRateID
       FROM Sales.SalesOrderHeader
    ELSE
      SELECT OrderDate, TotalDue
       FROM Sales.SalesOrderHeader'</pre></p>
<p>In this case, the system stored procedure raises an error that clearly explains the problem:</p>
<p><pre class="brush: plain;">Msg 11509, Level 16, State 1, Procedure sp_describe_first_result_set, Line 53

The metadata could not be determined because the statement 'SELECT OrderDate, TotalDue, CurrencyRateID FROM Sales.SalesOrderHeader' is not compatible with the statement 'SELECT OrderDate, TotalDue FROM Sales.SalesOrderHeader'.</pre></p>
<p>It is noteworthy to mention that the data management function copes with this scenario much more passively. Given conflicting result set schemas, it simply returns <em>NULL</em> and does not raise an error.</p>
<h3>sys.dm_exec_describe_first_result_set_for_object</h3>
<p>The data management function <em>sys.dm_exec_describe_first_result_set_for_object</em> can be used to achieve the same discovery against any object in the database. It accepts just an object ID and the Boolean “browse” flag to specify if hidden ID columns should be returned. You can use the <em>OBJECT_ID</em> function to obtain the ID of the desired object. The following code demonstrates this by returning schema information for the stored procedure <em>GetOrderInfo</em>.</p>
<p><pre class="brush: plain;">CREATE PROCEDURE GetOrderInfo(@OrderID AS int) AS
  SELECT OrderDate, TotalDue
   FROM Sales.SalesOrderHeader
   WHERE SalesOrderID = @OrderID
GO

SELECT name, system_type_name, is_hidden
 FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('GetOrderInfo'), 1)</pre></p>
<p>Here is the output:</p>
<p><pre class="brush: plain;">name             system_type_name   is_hidden
---------------  -----------------  ---------
OrderDate        datetime           0
TotalDue         money              0
SalesOrderID     int                1</pre></p>
<h3>sys.sp_describe_undeclared_parameters</h3>
<p>Finally, the <em>sys.sp_describe_undeclared_parameters</em> stored procedure parses a T-SQL statement to discover type information about the parameters expected by the statement, as the following code demonstrates:</p>
<p><pre class="brush: plain;">EXEC sys.sp_describe_undeclared_parameters
 N'IF @IsFlag = 1 SELECT 1 ELSE SELECT 0'</pre></p>
<p>Here is the output:</p>
<p><pre class="brush: plain;">parameter_ordinal name    suggested_system_type_id suggested_system_type_name ...
----------------- ------- ------------------------ -------------------------- -------
1                 @IsFlag 56                       int                        ... </pre></p>
<p>In this example, SQL Server detects the <em>@IsFlag</em> parameter, and suggests the <em>int</em> data type based on the usage in the T-SQL statement it was given to parse.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1320/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1320&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/05/29/new-metadata-discovery-features-in-sql-server-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/05/f02xx03.png" medium="image">
			<media:title type="html">F02xx03</media:title>
		</media:content>
	</item>
		<item>
		<title>Download Visual Studio Live! New York Slides and Code</title>
		<link>http://lennilobel.wordpress.com/2012/05/22/download-visual-studio-live-new-york-slides-and-code/</link>
		<comments>http://lennilobel.wordpress.com/2012/05/22/download-visual-studio-live-new-york-slides-and-code/#comments</comments>
		<pubDate>Tue, 22 May 2012 15:50:41 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[Community Events]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1313</guid>
		<description><![CDATA[A very successful Visual Studio Live! just wrapped up two weeks ago here in my hometown of Brooklyn, NY. Thanks again to all the good folks that attended my sessions. As promised, I&#8217;ve posted all the slides and code from my sessions for you to download. You can grab the stuff here: May 14, 2012 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1313&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A very successful Visual Studio Live! just wrapped up two weeks ago here in my hometown of Brooklyn, NY. Thanks again to all the good folks that attended my sessions.</p>
<p>As promised, I&#8217;ve posted all the slides and code from my sessions for you to download. You can grab the stuff here:</p>
<table>
<tbody>
<tr>
<td width="100">May 14, 2012</td>
<td width="300">SQL Server Workshop for Developers</td>
<td><a href="http://sdrv.ms/VSLiveNY2012SQL">http://sdrv.ms/VSLiveNY2012SQL</a></td>
</tr>
<tr>
<td>May 17, 2012</td>
<td>Introducing SQL Server Data Tools</td>
<td><a href="http://sdrv.ms/VSLiveNY2012SSDT">http://sdrv.ms/VSLiveNY2012SSDT</a></td>
</tr>
<tr>
<td>May 17, 2012</td>
<td>T-SQL Enhancements in SQL Server 2012</td>
<td><a href="http://sdrv.ms/VSLiveNY2012TSql">http://sdrv.ms/VSLiveNY2012TSql</a></td>
</tr>
</tbody>
</table>
<p>Looking forward to Visual Studio Live! in Redmond this coming August! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1313/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1313/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1313&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/05/22/download-visual-studio-live-new-york-slides-and-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>Enhance Portability with Partially Contained Databases in SQL Server 2012</title>
		<link>http://lennilobel.wordpress.com/2012/04/10/enhance-portability-with-partially-contained-databases-in-sql-server-2012/</link>
		<comments>http://lennilobel.wordpress.com/2012/04/10/enhance-portability-with-partially-contained-databases-in-sql-server-2012/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 11:40:36 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>
		<category><![CDATA[Contained databases]]></category>
		<category><![CDATA[Contained logins]]></category>
		<category><![CDATA[Contained users]]></category>
		<category><![CDATA[Partial containment]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1265</guid>
		<description><![CDATA[The dependency of database-specific users upon server-based logins poses a challenge when you need to move or restore a database to another server. Although the users move with the database, their associated logins do not, and thus the relocated database will not function properly until you also setup and map the necessary logins on the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1265&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The dependency of database-specific users upon server-based logins poses a challenge when you need to move or restore a database to another server. Although the users move with the database, their associated logins do not, and thus the relocated database will not function properly until you also setup and map the necessary logins on the target server. To resolve these types of dependency problems and help make databases more easily portable, SQL Server 2012 introduces “partially contained” databases.</p>
<p>The term “partially contained” is based on the fact that SQL Server itself merely enables containment—it does not enforce it. It’s still your job to actually implement true containment. From a security perspective, this means that partially contained databases allow you to create a special type of user called a contained user. The contained user’s password is stored right inside the contained database, rather than being associated with a login defined at the server instance level and stored in the master database. Then, unlike the standard SQL Server authentication model, contained users are authenticated directly against the credentials in the contained database without ever authenticating against the server instance. Naturally, for this to work, a connection string with a contained user’s credentials must include the Initial Catalog keyword that specifies the contained database name.</p>
<h3>Creating a Partially Contained Database</h3>
<p>To create a partially contained database, first enable the contained database authentication setting by calling sp_configure and then issue a <em>CREATE DATABASE</em> statement with the new <em>CONTAINMENT=PARTIAL</em> clause as the following code demonstrates.</p>
<p><pre class="brush: plain;">-- Enable database containment

USE master
GO

EXEC sp_configure 'contained database authentication', 1
RECONFIGURE

-- Delete database if it already exists
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'MyDB')
 DROP DATABASE MyDB
GO

-- Create a partially contained database
CREATE DATABASE MyDB CONTAINMENT = PARTIAL
GO

USE MyDB
GO</pre></p>
<p>To reiterate, SQL Server doesn’t enforce containment. You can still break containment by creating ordinary database users for server-based logins. For this reason, it’s easy to convert an ordinary (uncontained) database to a partially contained database; simply issue an <em>ALTER DATABASE</em> statement and specify <em>SET CONTAINMENT=PARTIAL</em>. You’ll then be able to migrate the server-based logins to contained logins and achieve server independence.</p>
<h3>Creating a Contained User</h3>
<p>Once you have a contained database, you can create a contained user for it by issuing a <em>CREATE USER</em> statement and specifying <em>WITH PASSWORD</em>, as shown here:</p>
<p><pre class="brush: plain;">CREATE USER UserWithPw
 WITH PASSWORD = N'password$1234'</pre></p>
<p>This syntax is valid only for contained databases; SQL Server will raise an error if you attempt to create a contained user in the context of an uncontained database.</p>
<p>That’s all there is to creating partially contained databases with contained users. The only remaining point that’s worth calling out is that an Initial Catalog clause pointing to a partially contained database must be specified explicitly in a connection string that also specifies the credentials of a contained user in that database. If just the credentials are specified without the database, SQL Server will not scan the partially contained databases hosted on the instance for one that has a user with matching credentials. Instead, it will consider the credentials to be those of an ordinary SQL Server login, and will not authenticate against the contained database.</p>
<h3>Other Partially Contained Database Features</h3>
<p>Aside from server-based logins, there are many other dependencies that a database might have on its hosted instance. These include linked servers, SQL CLR, database mail, service broker objects, endpoints, replication, SQL Server Agent jobs, and <em>tempdb</em> collation. All these objects are considered to be uncontained entities since they all exist outside the database.</p>
<p>Uncontained entities threaten a database’s portability. Since these objects are all defined at the server instance level, behavior can vary unpredictably when databases are shuffled around from one instance to another. Let&#8217;s examine features to help you achieve the level of containment and stability that your circumstances require.</p>
<h3>Uncontained Entities View</h3>
<p>SQL Server provides a new data management view (DMV) called <em>sys.dm_db_uncontained_entities</em> that you can query on to discover potential threats to database portability. This DMV not only highlights dependent objects, it will even report the exact location of all uncontained entity references inside of stored procedures, views, functions, and triggers.</p>
<p>The following code creates a few stored procedures, and then joins <em>sys.dm_db_uncontained_entities</em> with <em>sys.objects</em> to report the name of all objects having uncontained entity references in them.</p>
<p><pre class="brush: plain;">-- Create a procedure that references a database-level object
CREATE PROCEDURE GetTables AS
BEGIN
  SELECT * FROM sys.tables
END
GO

-- Create a procedure that references an instance-level object
CREATE PROCEDURE GetEndpoints AS
BEGIN
  SELECT * FROM sys.endpoints
END
GO

-- Identify objects that break containment
SELECT
  UncType = ue.feature_type_name,
  UncName = ue.feature_name,
  RefType = o.type_desc,
  RefName = o.name,
  Stmt = ue.statement_type,
  Line = ue.statement_line_number,
  StartPos = ue.statement_offset_begin,
  EndPos = ue.statement_offset_end
 FROM
  sys.dm_db_uncontained_entities AS ue
  INNER JOIN sys.objects AS o ON o.object_id = ue.major_id</pre></p>
<p>Here is the result of the query:</p>
<p><pre class="brush: plain;">UncType      UncName    RefType               RefName       Stmt    Line  StartPos  EndPos
-----------  ---------  --------------------  ------------  ------  ----  --------  ---
System View  endpoints  SQL_STORED_PROCEDURE  GetEndpoints  SELECT  5     218       274</pre></p>
<p>The DMV identifies the stored procedure <em>GetEndpoints</em> as an object with an uncontained entity reference. Specifically, the output reveals that a stored procedure references the <em>sys.endpoints</em> view in a <em>SELECT</em> statement on line 5 at position 218. This alerts you to a database dependency on endpoints configured at the server instance level that could potentially pose an issue for portability. The <em>GetTables</em> stored procedure does not have any uncontained entity references (sys.tables is contained), and is therefore not reported by the DMV.</p>
<h3>Collations and <em>tempdb</em></h3>
<p>Ordinarily, all databases hosted on the same SQL Server instance share the same <em>tempdb</em> database for storing temporary tables, and all the databases (including <em>tempdb</em>) on the instance use the same collation setting (collation controls string data character set, case sensitivity, and accent sensitivity). When joining between regular database tables and temporary tables, both your user database and <em>tempdb</em> must use a compatible collation. This, again, represents an instance-level dependency with respect to the fact that the collation setting can vary from one server instance to another. Thus, problems arise when moving databases between servers that have different collation settings for <em>tempdb</em>. The code below demonstrates the problem, and how to avoid it by using a contained database.</p>
<p><pre class="brush: plain;">-- Create an uncontained database with custom collation
USE master
GO
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'MyDB')
 DROP DATABASE MyDB
GO
CREATE DATABASE MyDB COLLATE Chinese_Simplified_Pinyin_100_CI_AS
GO

USE MyDB
GO

-- Create a table in MyDB (uses Chinese_Simplified_Pinyin_100_CI_AS collation)
CREATE TABLE TestTable (TextValue nvarchar(max))

-- Create a temp table in tempdb (uses SQL_Latin1_General_CP1_CI_AS collation)
CREATE TABLE #TempTable (TextValue nvarchar(max))

-- Fails, because MyDB and tempdb uses different collation
SELECT *
 FROM TestTable INNER JOIN #TempTable ON TestTable.TextValue = #TempTable.TextValue

-- Convert to a partially contained database
DROP TABLE #TempTable
USE master

ALTER DATABASE MyDB SET CONTAINMENT=PARTIAL
GO

USE MyDB
GO

-- Create a temp table in MyDB (uses Chinese_Simplified_Pinyin_100_CI_AS collation)
CREATE TABLE #TempTable (TextValue nvarchar(max))

-- Succeeds, because the table in tempdb now uses the same collation as MyDB
SELECT *
 FROM TestTable INNER JOIN #TempTable ON TestTable.TextValue = #TempTable.TextValue

-- Cleanup
DROP TABLE #TempTable
USE master
DROP DATABASE MyDB
GO</pre></p>
<p>This code first creates an uncontained database that uses <em>Chinese_Simplified_Pinyin_100_CI_AS</em> collation on a server instance that uses (the default) <em>SQL_Latin1_General_CP1_CI_AS</em> collation. The code then creates a temporary table and then attempts to join an ordinary database table against it. The attempt fails because the two tables have different collations (that is, they each reside in databases that use different collations), and SQL Server issues the following error message:</p>
<pre>Msg 468, Level 16, State 9, Line 81
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and
"Chinese_Simplified_Pinyin_100_CI_AS" in the equal to operation.</pre>
<p>Then the code issues an <em>ALTER DATABASE…SET CONTAINMENT=PARTIAL</em> statement to convert the database to a partially contained database. As a result, SQL Server resolves the conflict by collating the temporary table in <em>tempdb</em> in the same collation as the contained database, and the second join attempt succeeds.</p>
<h3>Summary</h3>
<p>Partially contained databases in SQL Server 2012 go a long way helping to improve the portability of databases across servers and instances. In this blog post, I demonstrated how to create a partially contained database with contained users, how to deal with collation issues, and how to use the new data management view to discover threats to containment and identify external dependencies. These capabilities are welcome news for SQL Server DBAs everywhere. Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1265/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1265&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/04/10/enhance-portability-with-partially-contained-databases-in-sql-server-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>Download Visual Studio Live Las Vegas and SQLBits London Slides and Code</title>
		<link>http://lennilobel.wordpress.com/2012/04/08/download-visual-studio-live-las-vegas-and-sqlbits-london-slides-and-code/</link>
		<comments>http://lennilobel.wordpress.com/2012/04/08/download-visual-studio-live-las-vegas-and-sqlbits-london-slides-and-code/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 19:21:32 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[Community Events]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1283</guid>
		<description><![CDATA[I just returned from Visual Studio Live (Las Vegas) and SQLBits (London), and both shows were very successful. Thanks again to all the good folks that attended my sessions, your positive energy was amazing and I hope you had as much fun as I did. As promised, I&#8217;ve posted the slides and code from all [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1283&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I just returned from Visual Studio Live (Las Vegas) and SQLBits (London), and both shows were very successful. Thanks again to all the good folks that attended my sessions, your positive energy was amazing and I hope you had as much fun as I did.</p>
<p>As promised, I&#8217;ve posted the slides and code from all my sessions for you to download. You can grab the stuff here:</p>
<h3>Visual Studio Live (Las Vegas)</h3>
<table>
<tr>
<td width="100">Mar 26, 2012</td>
<td width="300">SQL Server Workshop for Developers</td>
<td><a href="http://sdrv.ms/VSLiveVegas2012SQL">http://sdrv.ms/VSLiveVegas2012SQL</a></td>
</tr>
<tr>
<td>Mar 27, 2012</td>
<td>Introducing SQL Server Data Tools</td>
<td><a href="http://sdrv.ms/VSLiveVegas2012SSDT">http://sdrv.ms/VSLiveVegas2012SSDT</a></td>
</tr>
<tr>
<td>Mar 27, 2012</td>
<td>Understanding Your .NET Data Access Choices</td>
<td><a href="http://sdrv.ms/VSLiveVegas2012DataAccess">http://sdrv.ms/VSLiveVegas2012DataAccess</a></td>
</tr>
</table>
<p></p>
<h3>SQLBits (London)</h3>
<table>
<tr>
<td width="100">Mar 29, 2012</td>
<td width="300">SQL Server Workshop for Developers</td>
<td><a href="http://sdrv.ms/SQLBits2012WorkshopForDevelopers">http://sdrv.ms/SQLBits2012WorkshopForDevelopers</a></td>
</tr>
<tr>
<td>Mar 30, 2012</td>
<td>Native File Streaming</td>
<td><a href="http://sdrv.ms/SQLBits2012NativeFileStreaming">http://sdrv.ms/SQLBits2012NativeFileStreaming</a></td>
</tr>
</table>
<p>
Looking forward to Visual Studio Live (New York) next month, to be held right here in my hometown Brooklyn, NY! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1283/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1283&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/04/08/download-visual-studio-live-las-vegas-and-sqlbits-london-slides-and-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>New Spatial Features in SQL Server 2012</title>
		<link>http://lennilobel.wordpress.com/2012/03/08/new-spatial-features-in-sql-server-2012/</link>
		<comments>http://lennilobel.wordpress.com/2012/03/08/new-spatial-features-in-sql-server-2012/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 21:37:03 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>
		<category><![CDATA[SQL Server Spatial]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1233</guid>
		<description><![CDATA[SQL Server 2012 adds many significant improvements to the spatial support that was first introduced with SQL Server 2008. Among the more notable enhancements is support for curves (arcs), where SQL Server 2008 only supported straight lines, or polygons composed of straight lines. Microsoft also provides methods that test for non-2012-compatible (curved) shapes, and convert [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1233&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2012 adds many significant improvements to the spatial support that was first introduced with SQL Server 2008. Among the more notable enhancements is support for curves (arcs), where SQL Server 2008 only supported straight lines, or polygons composed of straight lines. Microsoft also provides methods that test for non-2012-compatible (curved) shapes, and convert circular data to line data for backward compatibility with SQL Server 2008 (as well as other mapping platforms that don’t support curves).</p>
<h3>New Spatial Data Classes</h3>
<p>The three new spatial data classes in SQL Server 2012 are:</p>
<ul>
<li>Circular strings</li>
<li>Compound curves</li>
<li>Curve polygons</li>
</ul>
<p>All three of these shapes are supported in WKT, WKB, and GML by both the <em>geometry</em> and <em>geography</em> data types, and all of the existing methods work on all of the new circular shapes. My previous post, <a href="http://bit.ly/lenniblog_SQL2012CircularData">Geospatial Support for Circular Data in SQL Server 2012</a> covers these new spatial classes in detail, and shows you how to use them to create circular data. This post focuses on additional spatial features that are new in SQL Server 2012.</p>
<h3>New Spatial Methods</h3>
<p>Let’s explore a few of the new spatial methods. Some of these new methods complement the new curved shapes, while others add new spatial features that work with all shapes.</p>
<h3>The <em>STNumCurves</em> and <em>STCurveN</em> Methods</h3>
<p>These two methods can be invoked on any <em>geometry</em> or <em>geography</em> instance. They can be used together to discover information about the curves contained within the spatial instance. The <em>STNumCurves</em> method returns the total number of curves in the instance. You can then pass any number between 1 and what <em>STNumCurves</em> returns to extract each individual curve, and thus iterate all the curves in the instance.</p>
<p>For example, the WKT string <em>CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4)</em> defines a perfect circle composed of two connected segments; 0 4, 4 0, 8, 4 and 8 4, 4 8, 0 4 (the third coordinate 8 4 is used both as the ending point of the first arc and the starting point of the second arc. The following code demonstrates how to obtain curve information from this circular string using the <em>STNumCurves</em> and <em>STCurveN</em> methods.<br />
<pre class="brush: plain;">-- Create a full circle shape (two connected semi-circles)
DECLARE @C geometry = 'CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4)'

-- Get the curve count (2) and the 1st curve (bottom semi-circle)
SELECT
  CurveCount = @C.STNumCurves(),
  SecondCurve = @C.STCurveN(2),
  SecondCurveWKT = @C.STCurveN(2).ToString()</pre><br />
This query produces the following output:</p>
<p><pre class="brush: plain;">CurveCount SecondCurve                                     SecondCurveWKT
---------- ----------------------------------------------- -------------------------------
2          0x000000000204030000000000000000002040000000... CIRCULARSTRING (8 4, 4 8, 0 4)</pre></p>
<p>You can see that <em>STNumCurves</em> indicates there are two curves, and that <em>STCurveN(2)</em> returns the second curve. If you view the results in the spatial viewer, you’ll see just the top half of the circle. This is the semi-circle defined by the second curve, which is converted back to WKT as <em>CIRCULARSTRING (8 4, 4 8, 0 4)</em>. Notice that this represents the second segment of the full circle.</p>
<h3>The <em>BufferWithCurves </em>Method</h3>
<p>SQL Server 2008 introduced the <em>STBuffer</em> method which “pads” a line, effectively converting it into a polygon. If you look closely at the resulting polygon shapes in the spatial viewer, it appears that the points of each line string (including the mid points) are transformed into rounded edges in the polygon. However, the rounded edge look is actually produced by plotting many short straight lines that are clustered very closely together, presenting the illusion of a curve. This approach is necessary since curves were not previously supported before SQL Server 2012 (but the <em>STBuffer</em> method was).</p>
<p>Clearly, using native curve definitions in a curve polygon is more efficient than clustering a multitude of straight lines in an ordinary polygon. For backward compatibility, <em>STBuffer</em> continues to return the (inefficient) polygon as before. So SQL Server 2012 introduces a new method, <em>BufferWithCurves</em>, for this purpose. The following code uses <em>BufferWithCurves</em> to pad lines using true curves, and compares the result with its straight-line cousin, <em>STBuffer</em>.</p>
<p><pre class="brush: plain;">DECLARE @streets geometry = '
 GEOMETRYCOLLECTION(
  LINESTRING (100 -100, 20 -180, 180 -180),
  LINESTRING (300 -300, 300 -150, 50 -50)
 )'
SELECT @streets.BufferWithCurves(10)

SELECT
  AsWKT = @streets.ToString(),
  Bytes = DATALENGTH(@streets),
  Points = @streets.STNumPoints()
 UNION ALL
 SELECT
  @streets.STBuffer(10).ToString(),
  DATALENGTH(@streets.STBuffer(10)),
  @streets.STBuffer(10).STNumPoints()
 UNION ALL
 SELECT
  @streets.BufferWithCurves(10).ToString(),
  DATALENGTH(@streets.BufferWithCurves(10)),
  @streets.BufferWithCurves(10).STNumPoints()</pre></p>
<p>Here is the resulting shape returned by the first <em>SELECT</em> statement (the collection of padded line shapes generated by <em>BufferWithCurves</em>):</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/03/pic1.jpg"><img class="alignnone size-full wp-image-1250" title="Pic1" src="http://lennilobel.files.wordpress.com/2012/03/pic1.jpg?w=780" alt=""   /></a></p>
<p>As with <em>STBuffer</em>, the new shapes have rounded edges around the points of the original line strings. However, <em>BufferWithCurves</em> generates actual curves, and thus, produces a significantly smaller and simpler polygon. The second <em>SELECT</em> statement demonstrates by comparing the three shapes—the original line string collection, the polygon returned by <em>STBuffer</em>, and the curve polygon returned by <em>BufferWithCurves</em>. Here are the results:</p>
<p><pre class="brush: plain;">AsWKT                                                                       Bytes  Points
--------------------------------------------------------------------------  -----  ------
GEOMETRYCOLLECTION (LINESTRING (100 -100, 20 -180, 180 -180), LINESTRIN...  151    6
MULTIPOLYGON (((20.000000000000796 -189.99999999999858, 179.99999999999...  5207   322
GEOMETRYCOLLECTION (CURVEPOLYGON (COMPOUNDCURVE ((20.000000000000796 -1...  693    38</pre></p>
<p>The first shape is the original geometry collection of line strings used for input, which requires only 151 bytes of storage, and has only 6 points. For the second shape, <em>STBuffer</em> pads the line strings to produce a multi-polygon (a set of polygons) that consumes 5,207 bytes and has a total of 322 points—a whopping 3,448 percent increase from the original line strings. In the third shape, <em>BufferWithCurves</em> is used to produce the equivalent padding using a collection of curve polygons composed of compound curves, so it consumes only 693 bytes and has only 38 points—a (relatively) mere 458 percent increase from the original line strings.</p>
<h3>The <em>ShortestLineTo </em>Method</h3>
<p>This new method examines any two shapes and figures out the shortest line between them. The following code demonstrates:</p>
<p><pre class="brush: plain;">DECLARE @Shape1 geometry = 'POLYGON ((-20 -30, -3 -26, 14 -28, 20 -40, -20 -30))'
DECLARE @Shape2 geometry = 'POLYGON ((-18 -20, 0 -10, 4 -12, 10 -20, 2 -22, -18 -20))'

SELECT @Shape1
UNION ALL
SELECT @Shape2
UNION ALL
SELECT @Shape1.ShortestLineTo(@Shape2).STBuffer(.25)</pre></p>
<p>This code defines two polygons and then uses <em>ShortestLineTo</em> to determine, generate, and return the shortest straight line that connects them. <em>STBuffer</em> is also used to pad the line string so that it is more clearly visible in the spatial viewer:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/03/pic2.jpg"><img class="alignnone size-full wp-image-1251" title="Pic2" src="http://lennilobel.files.wordpress.com/2012/03/pic2.jpg?w=780" alt=""   /></a></p>
<h3>The <em>MinDbCompatibilityLevel</em> Method</h3>
<p>With the added support for curves in SQL Server 2012 comes support for backward compatibility with previous versions of SQL Server (2008 and 2008 R2) that don’t support curves. The new <em>MinDbCompatibilityLevel</em> method accepts any WKT string and returns the minimum version of SQL Server required to support the shape defined by that string. For example, consider the following code:</p>
<p><pre class="brush: plain;">DECLARE @Shape1 geometry = 'CIRCULARSTRING(0 50, 90 50, 180 50)'
DECLARE @Shape2 geometry = 'LINESTRING (0 50, 90 50, 180 50)'

SELECT
 Shape1MinVersion = @Shape1.MinDbCompatibilityLevel(),
 Shape2MinVersion = @Shape2.MinDbCompatibilityLevel()</pre></p>
<p>The <em>MinDbCompatibilityLevel</em> method returns 110 (referring to version 11.0) for the first WKT string and 100 (version 10.0) for the second one. This is because the first WKT string contains a circular string, which requires SQL Server 2012 (version 11.0), while the line string in the second WKT string is supported by SQL Server 2008 (version 10.0) and higher.</p>
<h3>The <em>STCurveToLine</em> and <em>CurveToLineWithTolerance</em> Methods</h3>
<p>These are two methods you can use to convert curves to roughly equivalent straight line shapes. Again, this is to provide compatibility with previous versions of SQL Server and other mapping platforms that don’t support curves.</p>
<p>The <em>STCurveToLine</em> method converts a single curve to a line string with a multitude of segments and points that best approximate the original curve. The technique is similar to what we just discussed for <em>STBuffer</em>, where many short straight lines are connected in a cluster of points to simulate a curve. And, as explained in that discussion, the resulting line string requires significantly more storage than the original curve. To offer a compromise between fidelity and storage, the <em>CurveToLineWithTolerance</em> method accepts “tolerance” parameters to produce line strings that consume less storage space than those produced by <em>STCurveToLine</em>. The following code demonstrates by using both methods to convert the same circle shape from the previous <em>STNumCurves</em> and <em>STCurveN</em> example into line strings.</p>
<p><pre class="brush: plain;">-- Create a full circle shape (two connected semi-circles)
DECLARE @C geometry = 'CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4)'

-- Render as curved shape
SELECT
  Shape = @C,
  ShapeWKT = @C.ToString(),
  ShapeLen = DATALENGTH(@C),
  Points = @C.STNumPoints()

-- Convert to lines (much larger, many more points)
SELECT
  Shape = @C.STCurveToLine(),
  ShapeWKT = @C.STCurveToLine().ToString(),
  ShapeLen = DATALENGTH(@C.STCurveToLine()),
  Points = @C.STCurveToLine().STNumPoints()

-- Convert to lines with tolerance (not as much larger, not as many more points)
SELECT
  Shape = @C.CurveToLineWithTolerance(0.1, 0),
  ShapeWKT = @C.CurveToLineWithTolerance(0.1, 0).ToString(),
  ShapeLen = DATALENGTH(@C.CurveToLineWithTolerance(0.1, 0)),
  Points = @C.CurveToLineWithTolerance(0.1, 0).STNumPoints()</pre></p>
<p>The query results show that the original circle consumes only 112 bytes and has 5 points. Invoking <em>STCurveToLine</em> on the circle converts it into a line string that consumes 1,072 bytes and has 65 points. That’s a big increase, but the resulting line string represents the original circle in high fidelity; you will not see a perceptible difference in the two when viewing them using the spatial viewer. However, the line string produced by <em>CurveToLineWithTolerance</em> consumes only 304 bytes and has only 17 points; a significantly smaller footprint, paid for with a noticeable loss in fidelity. As shown by the spatial viewer results below, using <em>CurveToLineWithTolerance</em> produces a circle made up of visibly straight line segments:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/03/pic3.jpg"><img class="alignnone size-full wp-image-1252" title="Pic3" src="http://lennilobel.files.wordpress.com/2012/03/pic3.jpg?w=780" alt=""   /></a></p>
<h3>The <em>STIsValid</em>, <em>IsValidDetailed</em> and <em>MakeValid</em> Methods</h3>
<p>Spatial instance validation has improved greatly in SQL Server 2012. The <em>STIsValid</em> method evaluates a spatial instance and returns a 1 (for true) or 0 (for false) indicating if the instance represents a valid shape (or shapes). If the instance is invalid, the new <em>IsValidDetailed</em> method will return a string explaining the reason why. The following code demonstrates.</p>
<p><pre class="brush: plain;">DECLARE @line geometry = 'LINESTRING(1 1, 2 2, 3 2, 2 2)'

SELECT
 IsValid = @line.STIsValid(),
 Details = @line.IsValidDetailed()</pre></p>
<p>This line string is invalid because the same point (2 2) is repeated, which results in “overlapping edges,” as revealed by the output from <em>IsValidDetailed</em>:</p>
<p><pre class="brush: plain;">IsValid  Details
-------  -------------------------------------------------------------------
0        24413: Not valid because of two overlapping edges in curve (1).</pre></p>
<p>SQL Server 2012 is more tolerant of invalid spatial instances than previous versions. For example, you can now perform metric operations (such as <em>STLength</em>) on invalid instances, although you still won’t be able to perform other operations (such as <em>STBuffer</em>) on them.</p>
<p>The new <em>MakeValid</em> method can “fix” an invalid spatial instance and make it valid. Of course, the shape will shift slightly, and there are no guarantees on the accuracy or precision of the changes made. The code in Listing 10-27 uses <em>MakeValid</em> to remove overlapping parts (which can be caused by anomalies such as inaccurate GPS traces), effectively converting the invalid line string into a valid spatial instance.</p>
<p><pre class="brush: plain;">DECLARE @line geometry = 'LINESTRING(1 1, 2 2, 3 2, 2 2)'
SELECT @line.MakeValid().ToString() AS Fixed</pre><br />
The WKT string returned by the <em>SELECT</em> statement shows the “fixed” line string:</p>
<p><pre class="brush: plain;">Fixed
-------------------------------------------------------------------
LINESTRING (3 2, 2 2, 1.0000000000000071 1.0000000000000036)</pre></p>
<h2>Other Enhancements</h2>
<p>The remainder of this post gives brief mention to several other noteworthy spatial enhancements added in SQL Server 2012. These include better <em>geography</em> support, and precision and optimization improvements.</p>
<h3>Support for <em>geography</em> Instances Exceeding a Logical Hemisphere</h3>
<p>Previous versions of SQL Server supported <em>geography</em> objects as large as (slightly less than) a logical hemisphere (half the globe). This limitation has been removed in SQL Server 2012, which now supports <em>geography</em> instances of any size (even the entire planet).</p>
<p>When you define a <em>geography</em> polygon, the order in which you specify the ring’s latitude and longitude coordinates (known as <em>vertex order</em>) is significant (unlike <em>geometry</em>, where vertex order is insignificant). The coordinate points are always defined according to the <em>left-foot inside</em> rule; when you “walk” the boundary of the polygon, your left foot is on the inside. Thus, vertex order determines whether you are defining a small piece of the globe, relative to the larger piece defined by the entire globe <em>except</em> for the small piece (that is, the rest of the globe).</p>
<p>Since previous versions of SQL Server were limited to half the globe, it was impossible to specify the points of a polygon in the “wrong order,” simply because doing so resulted in too large a shape (and thus, raised an error). That error potential no longer exists in SQL Server 2012, so it’s even more critical to make sure your vertex order is correct, or you’ll be unwittingly working with the exact “opposite” shape.</p>
<p>If you have a <em>geography</em> instance that is known have the wrong vertex order, you can repair it using the new <em>ReorientObject</em> method. This method operates only on polygons (it has no effect on points, line strings, or curves), and can be used to correct the ring orientation (vertex order) of the polygon. The following code demonstrates.</p>
<p><pre class="brush: plain;">-- Small (less than a logical hemisphere) polygon
SELECT geography::Parse('POLYGON((-10 -10, 10 -10, 10 10, -10 10, -10 -10))')

-- Reorder in the opposite direction for &quot;rest of the globe&quot;
SELECT geography::Parse('POLYGON((-10 -10, -10 10, 10 10, 10 -10, -10 -10))')

-- Reorient back to the small polygon
SELECT geography::Parse('POLYGON((-10 -10, -10 10, 10 10, 10 -10, -10 -10))').ReorientObject()</pre></p>
<p>Three <em>geography</em> polygon instances are defined in this code. The first <em>geography</em> instance defines a very small polygon. The second instance uses the exact same coordinates, but because the vertex order reversed, it defines an enormous polygon whose area represents the entire globe <em>except</em> for the small polygon. As explained, such a definition would cause an error in previous versions of SQL Server, but is now accommodated without a problem by SQL Server 2012. The third instance reverses the vertex order on the same shape as the second instance, thereby producing the same small polygon as the first instance.</p>
<h3>Full Globe Support</h3>
<p>Along with the aforementioned support for <em>geography</em> instances to exceed a single logical hemisphere comes a new spatial data class called <em>FULLGLOBE</em>. As you may have guessed, this is a shape that represents the entire planet. If you’ve ever wondered how many square meters there are in the entire world, the following query gives you the answer (which is 510,065,621,710,996 square meters, so you can stop wondering).</p>
<p><pre class="brush: plain;">-- Construct a new FullGlobe object (a WGS84 ellipsoid)
DECLARE @Earth geography = 'FULLGLOBE'

-- Calculate the area of the earth
SELECT PlanetArea = @Earth.STArea()</pre></p>
<p>All of the common spatial methods work as expected on a full globe object. So you could, for example, “cut away” at the globe by invoking the <em>STDifference</em> and <em>STSymDifference</em> method against it using other polygons as cookie-cutter shapes.</p>
<h3>New “Unit Sphere” Spatial Reference ID</h3>
<p>The default spatial reference ID (SRID) in SQL Server 2012 is 4326, which uses the metric system as its unit of measurement. This SRID also represents the true ellipsoidal sphere shape of the earth. While this representation is most accurate, it’s also more complex to calculate precise ellipsoidal mathematics. SQL Server 2012 offers a compromise in speed and accuracy, by adding a new spatial reference id (SRID), 104001, which uses a sphere of radius 1 to represent a <em>perfectly</em> round earth.</p>
<p>You can create <em>geography</em> instances with SRID 104001 when you don’t require the greatest accuracy. The <em>STDistance</em>, <em>STLength</em>, and <em>ShortestLineTo</em> methods are optimized to run faster on the unit sphere, since it takes a relatively simple formula to compute measures against a perfectly round sphere (compared to an ellipsoidal sphere).</p>
<h3>Better Precision</h3>
<p>Internal spatial calculations in SQL Server 2012 are now performed with 48 bits of precision, compared to 27 bits used in SQL Server 2008 and SQL Server 2008 R2. This can reduce the error caused by rounding of floating point coordinates for original vertex points by the internal computation.</p>
<h3>Summary</h3>
<p>This blog post introduced you to some of the powerful new spatial capabilities added to SQL Server 2012. You saw how to use <em>STNumCurves</em> and <em>STCurveN</em> to obtain curve information from circular data, the <em>BufferWithCurves</em> method to produce more efficient padded line shapes than <em>STBuffer</em>, and the <em>ShortestLineTo</em> method to figure out the shortest distance between two shapes. Then you saw how to use the new <em>MinDbCompatibilityLevel</em>, <em>STCurveToLine</em>, and <em>CurveToLineWithTolerance</em> methods for supporting backward compatibility with SQL Server 2008. You also learned how SQL Server 2012 is much better at handling invalid spatial data, using the <em>STIsValid</em>, <em>IsValidDetailed</em>, and <em>MakeValid</em> methods. Finally, you learned about the new full globe support, unit sphere SRID, and improved precision.</p>
<p>You can learn much more about spatial functionality in my new book Programming Microsoft SQL Server 2012, which has an entire chapter dedicated to the topic. I hope you get to enjoy these powerful new spatial capabilities in SQL Server 2012!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1233/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1233&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/03/08/new-spatial-features-in-sql-server-2012/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/03/pic1.jpg" medium="image">
			<media:title type="html">Pic1</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/03/pic2.jpg" medium="image">
			<media:title type="html">Pic2</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/03/pic3.jpg" medium="image">
			<media:title type="html">Pic3</media:title>
		</media:content>
	</item>
		<item>
		<title>WCF Data Services vs. WCF RIA Services – Making the Right Choice</title>
		<link>http://lennilobel.wordpress.com/2012/02/19/wcf-data-services-vs-wcf-ria-services-making-the-right-choice/</link>
		<comments>http://lennilobel.wordpress.com/2012/02/19/wcf-data-services-vs-wcf-ria-services-making-the-right-choice/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 04:11:53 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[WCF Data Services]]></category>
		<category><![CDATA[WCF RIA Services]]></category>
		<category><![CDATA[WCF Data Services vs WCF RIA Services]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1201</guid>
		<description><![CDATA[Windows Communication Foundation (WCF) provides all the support you need to build distributed service-oriented data access solutions. You can certainly work with WCF directly to create custom services and expose data from an Entity Data Model (EDM) with the ADO.NET Entity Framework, or from any other data access layer (DAL) of your choosing. To take [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1201&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Windows Communication Foundation (WCF) provides all the support you need to build distributed service-oriented data access solutions. You can certainly work with WCF directly to create custom services and expose data from an Entity Data Model (EDM) with the ADO.NET Entity Framework, or from any other data access layer (DAL) of your choosing. To take this “raw” approach, you need to start with the basics, or what is commonly referred to as the ABC’s of WCF: Addresses, Bindings, and Contracts. You must create service, operation, and data contracts, and then configure your service model with appropriate endpoint addresses and compatible bindings to be reachable by clients. Services are usually stateless, so you must also handle client-side change tracking and multi-user conflict resolution entirely on your own. The learning curve can be quite steep, after which you will still need to expend a great deal of effort to make it work.</p>
<p>Alternatively, you can turn to one of the two later technologies that Microsoft has built on top of WCF. These are WCF Data Services and WCF RIA Services, and they represent two very different approaches for building data-oriented services. Both provide abstractions that shield you from many underlying WCF particulars, so you get to spend more time focusing on your application and less time on plumbing. For one thing, you don’t need to code WCF contracts or manage change tracking on the client; all that gets done for you. With WCF RIA Services (and Silverlight), you don’t even need to create and update service references; Visual Studio generates code automatically via a special link that keeps your client and WCF RIA Services projects in sync at all times.</p>
<p>Both WCF Data Services and WCF RIA Services can solve many of the same problems, so it is only natural to question which one to use. The answer extends a bit beyond the standard “it depends on your scenario” response, since WCF RIA Services offers a lot more than just data access functionality. It also features client-side self-tracking entities, client-side validation, automatic server-to-client code generation, and more. In this blog post, I&#8217;ll discuss both platforms at a high level to help guide you in making the right choice.</p>
<h2>WCF Data Services</h2>
<p>Microsoft designed WCF Data Services as a thin layer over Entity Framework that exposes data-centric services to client applications. Out of the box, you can quickly build WCF Data Services over an Entity Data Model with virtually no effort. Custom providers for WCF Data Services for data sources other than Entity Framework are available; however, considerable additional effort is required to implement them. You can think of WCF Data Services as universal Web Services built just for data, although it can be easily extended with custom service operation methods. The platform is based on the industry standards of Representational State Transfer (REST) and the Open Data Protocol (OData), which means that these services are consumable by virtually every type of client in the world.</p>
<p>REST provides a uniform interface for querying and updating data. It is based on HTTP, meaning that client requests are issued in the form of GET, POST, MERGE, and DELETE actions — standard verbs understood by all HTTP clients. Any REST query can be invoked with an HTTP GET request by expressing all the elements of the query in a properly formed Uniform Resource Identifier (a URI, which is a more general term than Uniform Resource Locator [URL]). You can even test the service with an ordinary browser; simply type the properly formed URI directly into the address bar and you will receive the Atom Publishing Protocol (AtomPub) response (an XML dialect very similar to the Really Simply Syndication [RSS] feed format). The POST, MERGE, and DELETE verbs correspond respectively to insert, update, and delete operations supported by the service, and the payload (parameters, data, and other metadata) for these operations is passed in HTTP headers.</p>
<p>Just as REST enables universal data access via HTTP, the Open Data Protocol (OData) establishes universal data structure via standard serialization formats (see <a href="http://www.odata.org" target="_blank">http://www.odata.org</a>). All clients can handle plain text formats such as JavaScript Object Notation (JSON) and of course XML, and so OData defines standard response formats based on both formats. JSON provides a compact structure suitable for many basic types of services, while XML forms the basis for the more verbose AtomPub feed format. AtomPub is the default serialization format in WCF Data Services, because it effectively leverages the hierarchical nature of XML to describe the rich structure of data and metadata in an Entity Data Model.</p>
<p>The WCF Data Services client libraries for Windows/WPF, ASP.NET, Silverlight, and Windows Phone 7 include a special LINQ provider, commonly known as LINQ to REST. This provider automatically translates client-side LINQ queries into an equivalent OData URI, meaning that you don’t need to learn the OData URI syntax if you are building Microsoft clients over WCF Data Services (just use good old LINQ). The client libraries automatically deserialize the AtomPub feed response from WCF Data Services into ready-to-use objects. They also provide a stateful context object that can track changes on the client for pushing updates back to the server, although your code needs to explicitly notify the context about objects as they are changed.</p>
<h2>WCF RIA Services</h2>
<p>WCF RIA Services is, well, richer than WCF Data Services (and also newer). Indeed, the R in RIA means rich, although the full TLA (Three-Letter Acronym) can stand for Rich <em>Internet</em> Application or Rich <em>Interactive</em> Application—depending on who you’re talking to. Since its earliest days, WCF RIA Services was designed to work best with Silverlight, although it now also supports OData, SOAP, and JSON to reach a wider range of clients as well. You can build WCF RIA Services over any data access layer, including Entity Framework and LINQ to SQL. You can also use Plain Old CLR Objects (POCOs), in which case you handle the persistence yourself using your data access technique of choice, even conventional ADO.NET (raw readers and command objects, or DataSets). In any case, you expose WCF RIA Services by coding domain service classes that support CRUD operations, as well as other custom service operations. You also maintain a special metadata class for each entity that auto-magically surfaces on the client for effortless end-to-end validation across the wire.</p>
<p>When WCF RIA Services is used with Silverlight, you don’t need to create and update service references; Visual Studio generates code automatically via a special link that keeps your client and WCF RIA Services projects in sync at all times. Like a service reference, this link binds the two projects together, only a WCF RIA Services link couples them much more tightly than an ordinary service reference does. Public changes on the service side are reflected automatically in corresponding classes on the client side every time you perform a build, so you never need to worry about working against an outdated proxy in the client project simply because you forgot to manually update a service reference.</p>
<p>The WCF RIA Services link greatly simplifies the n-tier pattern, and makes traditional n-tier development feel more like the client/server experience. With the link established, Visual Studio continuously regenerates the client-side proxies to match the domain services on each build. It also auto-generates client-side copies of shared application logic you define in the services project, simply by looking for classes you’ve defined in files named *.shared.cs, or *.shared.vb. The link enforces automatic client-side validation and keeps validation rules in sync between the the domain services and the client at all times. Furthermore, client-side entities are completely self-tracking; you do not need to manually notify the context object of every change to every entity, as you are required to do with the WCF Data Services client library.</p>
<h2>Comparing WCF Data Services and WCF RIA Services</h2>
<p>The following table summarizes several key differences between the two platforms.</p>
<table style="border-bottom:1px solid black;" width="100%" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-top:1px solid black;padding-left:4px;font-weight:bold;background-color:#e0e0e0;" valign="top"></td>
<td style="border-top:1px solid black;padding-left:4px;font-weight:bold;background-color:#e0e0e0;" valign="top">WCF Data Services</td>
<td style="border-top:1px solid black;padding-left:4px;font-weight:bold;background-color:#e0e0e0;" valign="top">WCF RIA Services</td>
</tr>
<tr>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Supported Clients</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Resource-based API, supports all clients via deep REST and OData support.</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Domain-based API, most tailored for use with Silverlight, but supports other clients via SOAP, JSON, and OData.</td>
</tr>
<tr>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Supported Data Access Layers</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Targets EF. Other DALs are supported, but greater effort is required.</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Supports EF, LINQ to SQL, and POCO (custom persistence layer).</td>
</tr>
<tr>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Client Development</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Requires you to notify the context for change tracking.</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Supports self-tracking entities, synchronized client/server logic, and much more (particularly with Silverlight).</td>
</tr>
<tr>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Service Development</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Instant, code-less, extensible REST services out of the box (with EF); “free CRUD.”</td>
<td style="border-top:1px solid black;padding-left:4px;" valign="top">Requires you to code CRUD operations manually in domain service classes.</td>
</tr>
</tbody>
</table>
<p>From this comparison, it looks like WCF RIA Services is more attractive for Silverlight clients than non-Silverlight clients—regardless of which data access layer is used. Conversely, it shows that WCF Data Services is more appropriate for use with Entity Framework than it is with other data access layers—regardless of which client is used. But let’s examine things in a bit more detail.</p>
<p>If your scenario uses EF on the back end and targets Silverlight on the front end, then you are in the best position. Both WCF frameworks pack a huge win over writing traditional WCF services “by hand.” Your decision at this point is based on whether you simply require services to provide data access (that is, you primarily need CRUD support), or if you are seeking to leverage additional benefits. Another consideration is whether you are targeting Silverlight as the client exclusively or not.</p>
<p>Of the two, WCF Data Services is relatively lightweight, and requires almost no effort to get up and running. So it’s the better choice if you primarily require data access functionality in your services, particularly if you want to keep your service open to non-Silverlight clients as well. WCF RIA Services is more robust, and offers numerous additional features. This makes it a very compelling choice for the development of rich client applications. Although it began as a platform almost exclusively designed for Silverlight, support is steadily emerging for other client platforms via OData, SOAP, and JSON, as well as self-tracking entity libraries now available for jQuery. However, it requires the effort of creating domain service classes to support CRUD operations.</p>
<p>Finally, both frameworks are extensible, and both can be secured by traditional authentication and authorization techniques. They are also both capable of integrating with the ASP.NET Membership provider for role management and personalization.</p>
<p>What if you are using neither Silverlight nor Entity Framework? Well, then your work will be cut out for you whatever choice you make. With WCF Data Services, you will need to implement either the <a href="http://msdn.microsoft.com/en-us/library/dd723653.aspx" target="_blank">Reflection</a> or <a href="http://msdn.microsoft.com/en-us/library/ee960144.aspx" target="_blank">Streaming</a> provider, or write your own <a href="http://msdn.microsoft.com/en-us/data/gg191846" target="_blank">custom provider</a>. And with WCF RIA Services, you will not get to fully enjoy all the benefits of the framework, but you will still need to write domain services and metadata classes. After careful consideration, you may well conclude that neither choice is appropriate, and decide instead to stick with tried and true WCF services, coding your own service contracts, data contracts, binding configurations, change tracking, validations, and so on.</p>
<h3>Summary</h3>
<p>Both WCF Data Services and WCF RIA Services can represent huge savings in development effort. Which one you choose (or whether indeed you choose to use either) depends a great deal on your data access layer of choice and the types of clients you intend to reach. This post tells you what you need to know to intelligently distinguish between them.</p>
<p>My upcoming book, Programming Microsoft SQL Server 2012, has an entire chapter dedicated to this topic. Look forward to extensive coverage and code samples for complete data access solutions using both platforms. The release date is just a few short months away, so stay tuned!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1201/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1201/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1201&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/02/19/wcf-data-services-vs-wcf-ria-services-making-the-right-choice/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>How Significant is the SQL Server 2012 Release?</title>
		<link>http://lennilobel.wordpress.com/2012/02/05/how-significant-is-the-sql-server-2012-release-2/</link>
		<comments>http://lennilobel.wordpress.com/2012/02/05/how-significant-is-the-sql-server-2012-release-2/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 16:48:21 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1185</guid>
		<description><![CDATA[SQL Server, particularly its relational database engine, matured quite some time ago. So the “significance” of every new release over recent years can be viewed—in some ways—as relatively nominal. The last watershed release of the product was actually SQL Server 2005, which was when the relational engine (that, for years, defined SQL Server) stopped occupying [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1185&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>SQL Server, particularly its relational database engine, matured quite some time ago. So the “significance” of every new release over recent years can be viewed—in some ways—as relatively nominal. The last watershed release of the product was actually SQL Server 2005, which was when the relational engine (that, for years, defined SQL Server) stopped occupying “center stage,” and instead took its position alongside a set of services that now, collectively, define the product. These of course include the Business Intelligence (BI) components Reporting Services, Analysis Services, and Integration Services—features that began appearing as early as 1999 but, prior to SQL Server 2005, were integrated sporadically as a patchwork of loosely coupled add-ons, wizards, and management consoles. SQL Server 2005 changed all that with a complete overhaul. For the first time, SQL Server delivered a broader, richer, and more consolidated set of features and services which are built into—rather than bolted onto—the platform. None of the product versions that have been released since that time—SQL Server 2008, 2008 R2, and now 2012—have changed underlying architecture this radically.</p>
<p>That said, each SQL Server release continues to advance itself in vitally significant ways. SQL Server 2008 (released August 6, 2008) added a host of new features to the relational engine—T-SQL enhancements, Change Data Capture (CDC), Transparent Data Encryption (TDE), SQL Audit, FILESTREAM—plus powerful BI capabilities with Excel PivotTables, charts, and <em>CUBE</em> formulas. SQL Server 2008 R2 (released April 21, 2010) was dubbed the “BI Refresh,” adding PowerPivot for Excel, Master Data Services, and StreamInsight, but offering nothing more than minor tweaks and fixes in the relational engine.</p>
<p>The newest release—SQL Server 2012—is set to officially launch on March 7, 2012, and like every new release, this version improves on all of the key “abilities” (availability, scalability, manageability, programmability, and so on). The chief reliability improvement is the new High Availability Disaster Recovery (HADR) alternative to database mirroring. HADR (also commonly known as “Always On”) utilizes multiple secondary servers in an “availability group” for scale-out read-only operations (rather than forcing them to sit idle, just waiting for a failover to occur). Multi-subnet failover clustering is another notable new manageability feature.</p>
<p>SQL Server 2012 adds many new features to the relational engine, many of which I have blogged about, and most of which I cover in my new book (soon to be published). There are powerful T-SQL extensions, most notably the windowing enhancements, 22 new T-SQL functions, improved error handling, server-side paging, sequence generators, and rich metadata discovery techniques. There are also remarkable improvements for unstructured data, such as the FileTable abstraction over FILESTREAM and the Windows file system API, full-text property searching, and Statistical Semantic Search. Spatial support gets a big boost as well, with support for circular data, full-globe support, increased performance, and greater parity between the <em>geometry</em> and <em>geography</em> data types. Contained databases simplify portability, and new “columnstore” technology drastically increases performance of huge OLAP cubes (VertiPaq for PowerPivot and Analysis Services) and data warehouses (a similar implementation in the relational engine).</p>
<p>The aforementioned features are impressive, but still don’t amount to much more than “additives” over an already established database platform. A new release needs more than just extra icing on the cake for customers to perceive an upgrade as compelling. To that end, Microsoft has invested heavily in BI with SQL Server 2012, and the effort shows. The BI portion of the stack has been expanded greatly, delivering key advances in “pervasive insight.” This includes major updates to the product’s analytics, data visualization (such as self-service reporting with Power View), and master data management capabilities, as well Data Quality Services (DQS), a brand new data quality engine. There is also a new Business Intelligence edition of the product that includes all of these capabilities without requiring a full Enterprise edition license. Finally, SQL Server Data Tools (SSDT) brings brand new database tooling inside Visual Studio 2010. SSDT provides a declarative, model-based design-time experience for developing databases while connected, offline, on-premise, or in the cloud.</p>
<div>Of course there are more new features; I&#8217;ve only mentioned the most notable ones in this post. Although the relational engine has been rock-solid for several releases, it continues to enjoy powerful enhancements, while the overall product continues to reinvent itself by expanding its stack of services, particularly in the Business Intelligence space.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1185/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1185&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/02/05/how-significant-is-the-sql-server-2012-release-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
		<item>
		<title>Geospatial Support for Circular Data in SQL Server 2012</title>
		<link>http://lennilobel.wordpress.com/2012/01/22/geospatial-support-for-circular-data-in-sql-server-2012/</link>
		<comments>http://lennilobel.wordpress.com/2012/01/22/geospatial-support-for-circular-data-in-sql-server-2012/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 03:25:07 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>
		<category><![CDATA[SQL Server 2012 Circular Spatial Data]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1154</guid>
		<description><![CDATA[SQL Server 2012 adds many significant improvements to the spatial support that was first introduced with SQL Server 2008. In this blog post, I&#8217;ll explore one of the more notable enhancements: support for curves and arcs (circular data). SQL Server 2008 only supported straight lines, or polygons composed of straight lines. The three new shapes in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1154&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2012 adds many significant improvements to the spatial support that was first introduced with SQL Server 2008. In this blog post, I&#8217;ll explore one of the more notable enhancements: support for curves and arcs (circular data). SQL Server 2008 only supported straight lines, or polygons composed of straight lines. The three new shapes in SQL Server 2012 are circular strings, compound curves, and curve polygons. All three are supported in Well-Known Text (WKT), Well-Known Binary (WKB), and Geometry Markup Language (GML) by both the <em>geometry</em> (planar, or &#8220;flat-earth&#8221; model) and <em>geography</em> (ellipsoidal sphere, or geodetic) data types, and all of the existing methods work on the new shapes.</p>
<h3>Circular Strings</h3>
<p>A circular string defines a basic curved line, similar to how a line string defines a straight line. It takes a minimum of three coordinates to define a circular string; the first and third coordinates define the end points of the line, and the second coordinate (the “anchor” point, which lies somewhere between the end points) determines the arc of the line. Here is the shape represented by <em>CIRCULARSTRING(0 1, .25 0, 0 -1):</em></p>
<p><a href="http://lennilobel.files.wordpress.com/2012/01/10x21.png"><img class="alignnone size-full wp-image-1157" title="10x21" src="http://lennilobel.files.wordpress.com/2012/01/10x21.png?w=780" alt=""   /></a></p>
<p>The following code produces four circular strings. All of them have the same start and end points, but different anchor points. The lines are buffered slightly to make them easier to see in the spatial viewer.</p>
<p><pre class="brush: plain;">-- Create a &quot;straight&quot; circular line
SELECT geometry::Parse('CIRCULARSTRING(0 8, 4 0, 8 -8)').STBuffer(.1)
UNION ALL  -- Curve it
SELECT geometry::Parse('CIRCULARSTRING(0 8, 4 4, 8 -8)').STBuffer(.1)
UNION ALL  -- Curve it some more
SELECT geometry::Parse('CIRCULARSTRING(0 8, 4 6, 8 -8)').STBuffer(.1)
UNION ALL  -- Curve it in the other direction
SELECT geometry::Parse('CIRCULARSTRING(0 8, 4 -6, 8 -8)').STBuffer(.1)</pre></p>
<p>The spatial viewer in SQL Server Management Studio shows the generated shapes:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/01/10x22.png"><img class="alignnone size-full wp-image-1158" title="10x22" src="http://lennilobel.files.wordpress.com/2012/01/10x22.png?w=780" alt=""   /></a></p>
<p>The first shape is a “straight circular” line, because the anchor point is position directly between the start and end points. The next two shapes use the same end points with the anchor out to the right (4), one a bit further than the other (6). The last shape also uses the same end points, but specifies an anchor point that curves the line to the left rather than the right (-6).</p>
<p>You can extend circular strings with as many curve segments as you want. Do this by defining another two coordinates for each additional segment. The last point of the previous curve serves as the first end point of the next curve segment, so the two additional coordinates respectively specify the next segment’s anchor and second end point. Thus, valid circular strings will always have an odd number of points. You can extend a circular string indefinitely to form curves and arcs of any kind.</p>
<p>It’s easy to form a perfect circle by connecting two semi-circle segments. For example, the following illustration shows the circle produced by <em>CIRCULARSTRING(0 4, 4 0, 8 4, 4 8, 0 4)</em>.</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/01/circle.png"><img class="alignnone size-full wp-image-1163" title="Circle" src="http://lennilobel.files.wordpress.com/2012/01/circle.png?w=780" alt=""   /></a></p>
<p>This particular example connects the end of the second segment to the beginning of the first segment to form a closed shape. Note that this is certainly not required of circular strings (or line strings), and that closing the shape by connecting the last segment to the first still does not result in a polygon, which is a two dimensional shape that has area. Despite being closed, this circle is still considered a one-dimensional shape with no area. As you’ll soon see, the curve polygon can be used to convert closed line shapes into true polygons.</p>
<h3>Compound Curves</h3>
<p>A compound curve is a set of circular strings, or circular strings combined with line strings, that form a desired curved shape. The end point of each element in the collection must match the starting point of the following element, so that compound curves are defined in a “connect-the-dots” fashion. The following code produces a compound curve and compares it with the equivalent geometry collection shape.</p>
<p><pre class="brush: plain;">-- Compound curve
 DECLARE @CC geometry = '
  COMPOUNDCURVE(
   (4 4, 4 8),
   CIRCULARSTRING(4 8, 6 10, 8 8),
   (8 8, 8 4),
   CIRCULARSTRING(8 4, 2 3, 4 4)
  )'

-- Equivalent geometry collection
 DECLARE @GC geometry = '
  GEOMETRYCOLLECTION(
   LINESTRING(4 4, 4 8),
   CIRCULARSTRING(4 8, 6 10, 8 8),
   LINESTRING(8 8, 8 4),
   CIRCULARSTRING(8 4, 2 3, 4 4)
  )'

-- They both render the same shape in the spatial viewer
 SELECT @CC.STBuffer(.5)
 UNION ALL
 SELECT @GC.STBuffer(1.5)</pre></p>
<p>This code creates a keyhole shape using a compound curve, and also creates an identical shape as a geometry collection (though notice that the <em>LINESTRING</em> keyword is not—and cannot—be specified when defining a compound curve). It then buffers both of them with different padding, so that the spatial viewer clearly shows the two identical shapes on top of one another, as shown:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/01/compoundcurve.png"><img class="alignnone size-full wp-image-1164" title="CompoundCurve" src="http://lennilobel.files.wordpress.com/2012/01/compoundcurve.png?w=780" alt=""   /></a></p>
<p>Both the compound curve and the geometry collection yield identical shapes. In fact, the expression <em>@CC.STEquals(@GC)</em> which compares the two instances for equality returns 1 (for true). The <em>STEquals</em> method tests for “spatial equality,” meaning it returns true if two instances produce the same shape even if they are being rendered using different spatial data classes. Furthermore, recall that segments of a circular string can be made perfectly straight by positioning the anchor directly between the end points, meaning that the circular string offers yet a third option for producing the very same shape. So which one should you use? Comparing these spatial data classes will help you determine which one is best to use in different scenarios.</p>
<p>A geometry collection (which was already supported in SQL Server 2008) is the most accommodating, but carries the most storage overhead. Geometry collections can hold instances of any spatial data class, and the instances don’t need to be connected to (or intersected with) each other in any way. The collection simply holds a bunch of different shapes as a set, which in this example just happens to be several line strings and circular strings connected at their start and end points.</p>
<p>In contrast, the new compound curve class in SQL Server 2012 has the most constraints but is the most lightweight in terms of storage. It can <em>only</em> contain line strings or circular strings, and each segment’s start point must be connected to the previous segment’s end point (although it is most certainly <em>not</em> necessary to connect the first and last segments to form a closed shape as in this example). The <em>DATALENGTH</em> function shows the difference in storage requirements; <em>DATALENGTH(@CC)</em> returns 152 and <em>DATALENGTH(@GC)</em> returns 243. In our current example, <em>DATALENGTH(@CC)</em> returns 152 and <em>DATALENGTH(@GC)</em> returns 243. This means that the same shape requires 38% less storage space by using a compound curve instead of a geometry collection. A compound curve is also more storage-efficient than a multi-segment circular line string when straight lines are involved. This is because there is overhead for the mere potential of a curve, since the anchor point requires storage even when it’s position produces straight lines, whereas compound curves are optimized specifically to connect circular strings and (always straight) line strings.</p>
<h3>Curve Polygons</h3>
<p>A curve polygon is very similar to an ordinary polygon; like an ordinary polygon, a curve polygon specifies a “ring” that defines a closed shape, and can also specify additional inner rings to define “holes” inside the shape. The only fundamental difference between a polygon and a curve polygon is that the rings of a curve polygon can include circular shapes, whereas an ordinary polygon is composed exclusively with straight lines. Specifically, each ring in a curve polygon can consist of any combination of line strings, circular strings, and compound curves that collectively define the closed shape. For example, the following code produces a curve polygon with the same keyhole outline that I just demonstrated for the compound curve.</p>
<p><pre class="brush: plain;">-- Curve polygon
 SELECT geometry::Parse('
  CURVEPOLYGON(
   COMPOUNDCURVE(
    (4 4, 4 8),
    CIRCULARSTRING(4 8, 6 10, 8 8),
    (8 8, 8 4),
    CIRCULARSTRING(8 4, 2 3, 4 4)
   )
  )')</pre></p>
<p>This code has simply specified the same compound curve as the closed shape of a curve polygon. Although the shape is the same, the curve polygon is a two-dimensional object, whereas the compound curve version of the same shape is a one-dimensional object. This can be seen visually by the spatial viewer results, which shades the interior of the curve polygon as shown here:</p>
<p><a href="http://lennilobel.files.wordpress.com/2012/01/curvepolygon.png"><img class="alignnone size-full wp-image-1165" title="CurvePolygon" src="http://lennilobel.files.wordpress.com/2012/01/curvepolygon.png?w=780" alt=""   /></a></p>
<h3>Conclusion</h3>
<p>Circular data support is an important new capability added to the spatial support in SQL Server 2012. In this blog post, I demonstrated the three new spatial data classes for curves and arcs: circular strings, compound curves, and curve polygons. Stay tuned for my next post (coming soon), for more powerful and fun spatial enhancements coming soon in SQL Server 2012!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1154&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/01/22/geospatial-support-for-circular-data-in-sql-server-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/01/10x21.png" medium="image">
			<media:title type="html">10x21</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/01/10x22.png" medium="image">
			<media:title type="html">10x22</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/01/circle.png" medium="image">
			<media:title type="html">Circle</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/01/compoundcurve.png" medium="image">
			<media:title type="html">CompoundCurve</media:title>
		</media:content>

		<media:content url="http://lennilobel.files.wordpress.com/2012/01/curvepolygon.png" medium="image">
			<media:title type="html">CurvePolygon</media:title>
		</media:content>
	</item>
		<item>
		<title>SQL Server 2012 Windowing Functions Part 2 of 2: New Analytic Functions</title>
		<link>http://lennilobel.wordpress.com/2012/01/03/sql-server-2012-windowing-functions-part-2-of-2-new-analytic-functions/</link>
		<comments>http://lennilobel.wordpress.com/2012/01/03/sql-server-2012-windowing-functions-part-2-of-2-new-analytic-functions/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 15:47:28 +0000</pubDate>
		<dc:creator>Leonard Lobel</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server 2012 Code-Named "Denali"]]></category>
		<category><![CDATA[CUME_DIST]]></category>
		<category><![CDATA[FIRST_VALUE]]></category>
		<category><![CDATA[LAG]]></category>
		<category><![CDATA[LAST_VALUE]]></category>
		<category><![CDATA[LEAD]]></category>
		<category><![CDATA[PERCENTILE_CONT]]></category>
		<category><![CDATA[PERCENTILE_DISC]]></category>
		<category><![CDATA[PERCENT_RANK]]></category>
		<category><![CDATA[SQL Server 2012 Analytic Windowing Functions]]></category>
		<category><![CDATA[T-SQL Analytic Functions]]></category>
		<category><![CDATA[T-SQL Analytic Windowing Functions]]></category>

		<guid isPermaLink="false">http://lennilobel.wordpress.com/?p=1112</guid>
		<description><![CDATA[This is the second half of my two-part article on windowing functions in SQL Server 2012. In Part 1, I explained the new running and sliding aggregation capabilities added to the OVER clause in SQL Server 2012. In this post, I&#8217;ll explain the new T-SQL analytic windowing functions. All of these functions operate using the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1112&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This is the second half of my two-part article on windowing functions in SQL Server 2012. In <a href="http://lennilobel.wordpress.com/2011/12/12/sql-server-2012-windowing-functions-part-1-of-2-running-and-sliding-aggregates/">Part 1</a>, I explained the new running and sliding aggregation capabilities added to the <em>OVER</em> clause in SQL Server 2012. In this post, I&#8217;ll explain the new T-SQL analytic windowing functions. All of these functions operate using the windowing principles I explained in <a href="http://lennilobel.wordpress.com/2011/12/12/sql-server-2012-windowing-functions-part-1-of-2-running-and-sliding-aggregates/">Part 1</a>.</p>
<h3>Eight New Analytic Functions</h3>
<p>There are eight new analytic functions that have been added to T-SQL. All of them work in conjunction with an ordered window defined with an associated <em>ORDER BY</em> clause that can be optionally partitioned with a <em>PARTITION BY</em> clause and framed with a <em>BETWEEN</em> clause. The new functions are:</p>
<p><em> • FIRST_VALUE</em><br />
<em> • LAST_VALUE</em><br />
<em> • LAG</em><br />
<em> • LEAD</em><br />
<em> • PERCENT_RANK</em><br />
<em> • CUME_DIST</em><br />
<em> • PERCENTILE_CONT</em><br />
<em> • PERCENTILE_DISC</em></p>
<p>In the following code listing, the <em>FIRST_VALUE</em>, <em>LAST_VALUE</em>, <em>LAG</em>, and <em>LEAD</em> functions are used to analyze a set of orders at the product level.</p>
<p><pre class="brush: plain;">DECLARE @Orders AS table(OrderDate date, ProductID int, Quantity int)
INSERT INTO @Orders VALUES
 ('2011-03-18', 142, 74),
 ('2011-04-11', 123, 95),
 ('2011-04-12', 101, 38),
 ('2011-05-21', 130, 12),
 ('2011-05-30', 101, 28),
 ('2011-07-25', 123, 57),
 ('2011-07-28', 101, 12)

SELECT
  OrderDate,
  ProductID,
  Quantity,
  WorstOn = FIRST_VALUE(OrderDate) OVER(PARTITION BY ProductID ORDER BY Quantity),
  BestOn = LAST_VALUE(OrderDate) OVER(PARTITION BY ProductID ORDER BY Quantity
                          ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
  PrevOn = LAG(OrderDate, 1) OVER(PARTITION BY ProductID ORDER BY OrderDate),
  NextOn = LEAD(OrderDate, 1) OVER(PARTITION BY ProductID ORDER BY OrderDate)
 FROM @Orders
 ORDER BY OrderDate

OrderDate   ProductID  Quantity  WorstOn     BestOn      PrevOn      NextOn
----------  ---------  --------  ----------  ----------  ----------  ----------
2011-03-18  142        74        2011-03-18  2011-03-18  NULL        NULL
2011-04-11  123        95        2011-07-25  2011-04-11  NULL        2011-07-25
2011-04-12  101        38        2011-07-28  2011-04-12  NULL        2011-05-30
2011-05-21  130        12        2011-05-21  2011-05-21  NULL        NULL
2011-05-30  101        28        2011-07-28  2011-04-12  2011-04-12  2011-07-28
2011-07-25  123        57        2011-07-25  2011-04-11  2011-04-11  NULL
2011-07-28  101        12        2011-07-28  2011-04-12  2011-05-30  NULL</pre></p>
<p>In this query, four analytic functions specify an <em>OVER</em> clause that partitions the result set by <em>ProductID</em>. The product partitions defined for <em>FIRST_VALUE</em> and <em>LAST_VALUE</em> are sorted by <em>Quantity</em>, while the product partitions for <em>LAG</em> and <em>LEAD</em> are sorted by <em>OrderDate</em>. The full result set is sorted by <em>OrderDate</em>, so you need to visualize the sorted partition for each of the four functions to understand the output—the result set sequence is not the same as the row sequence used in the windowing functions.</p>
<h3><em>FIRST_VALUE</em> and <em>LAST_VALUE</em></h3>
<p>The <em>WorstOn</em> and <em>BestOn</em> columns use <em>FIRST_VALUE</em> and <em>LAST_VALUE</em> respectively to return the “worst” and “best” dates for the product in each partition. Performance is measured by quantity, so sorting each product’s partition by quantity will position the worst order at the first row in the partition and the best order at the last row in the partition. <em>FIRST_VALUE</em> and <em>LAST_VALUE</em> can return the value of any column (<em>OrderDate</em>, in this case), not just the aggregate column itself. For <em>LAST_VALUE</em>, it is also necessary to explicitly define a window over the entire partition with <em>ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING</em>. Otherwise, as explained in my coverage of <em>OVER</em> clause enhancements in <a href="http://lennilobel.wordpress.com/2011/12/12/sql-server-2012-windowing-functions-part-1-of-2-running-and-sliding-aggregates/">Part 1</a>, the default window is <em>ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW</em>, which frames (constrains) the window, and does not consider the remaining rows in the partition that are needed to obtain the highest quantity for <em>LAST_VALUE</em>.</p>
<p>In the output, notice that <em>OrderDate</em>, <em>LowestOn</em>, and <em>HighestOn</em> for the first order (product 142) are all the same value (3/18). This is because product 142 was only ordered once, so <em>FIRST_VALUE</em> and <em>LAST_VALUE</em> operate over a partition that has only this one row in it, with an <em>OrderDate</em> value of 3/18. The second row is for product 123, quantity 95, ordered on 4/11. Four rows ahead in the result set (not the partition) there is another order for product 123, quantity 57, placed on 7/25. This means that, for this product, <em>FIRST_VALUE</em> and <em>LAST_VALUE</em> operate over a partition that has these two rows in it, sorted by quantity. This positions the 7/25 order (quantity 57) first and the 4/11 (quantity 95) last within the partition. As a result, rows for product 123 report 7/25 for <em>WorstDate</em> and 4/11 for <em>BestDate</em>. The next order (product 101) appears two more times in the result set, creating a partition of three rows. Again, based on the <em>Quantity</em> sort of the partition, each row in the partition reports the product’s worst and best dates (which are 7/28 and 4/12, respectively).</p>
<h3><em>LAG</em> and <em>LEAD</em></h3>
<p>The <em>PrevOn</em> and <em>NextOn</em> columns use <em>LAG</em> and <em>LEAD</em> to return the previous and next date that each product was ordered. They specify an <em>OVER</em> clause that partitions by <em>ProductId</em> as before, but the rows in these partitions are sorted by <em>OrderDate</em>. Thus, the <em>LAG</em> and <em>LEAD</em> functions examine each product’s orders in chronological sequence, regardless of quantity. For each row in each partition, <em>LAG</em> is able to access previous (lagging) rows within the same partition. Similarly, <em>LEAD</em> can access subsequent (leading) rows within the same partition. The first parameter to <em>LAG</em> and <em>LEAD</em> specifies the column value to be returned from a lagging or leading row, respectively. The second parameter specifies the number of rows back or forward <em>LAG</em> and <em>LEAD</em> should seek within each partition, relative to the current row. The query passes <em>OrderDate</em> and <em>1</em> as parameters to <em>LAG</em> and <em>LEAD</em>, using product partitions that are ordered by date. Thus, the query returns the most recent past date, and nearest future date, that each product was ordered.</p>
<p>Because the first order’s product (142) was only ordered once, its single-row partition has no lagging or leading rows, and so <em>LAG</em> and <em>LEAD</em> both return <em>NULL</em> for <em>PrevOn</em> and <em>NextOn</em>. The second order (on 4/11) is for product 123, which was ordered again on 7/25, creating a partition with two rows sorted by <em>OrderDate</em>, with the 4/11 order positioned first and the 7/25 order positioned last within the partition. The first row in a multi-row window has no lagging rows, but at least one leading row. Similarly, the last order in a multi-row window has at least one lagging row, but no leading rows. As a result, the first order (4/11) reports <em>NULL</em> and 7/25 for <em>PrevOn</em> and <em>NextOn</em> (respectively), and the second order (7/25) reports 4/11 and <em>NULL</em> for <em>PrevOn</em> and <em>NextOn</em> (respectively). Product 101 was ordered three times, which creates a partition of three rows. In this partition, the second row has both a lagging row and a leading row. Thus, the three orders report <em>PrevOn</em> and <em>NextOn</em> values for product 101, respectively indicating <em>NULL</em>-5/30 for the first (4/12) order, 4/12-7/28 for the second (5/30) order, and 5/30-<em>NULL</em> for the third and last order.</p>
<p>The last functions to examine are <em>PERCENT_RANK</em> (rank distribution), <em>CUME_DIST</em> (cumulative distribution, or percentile), PERCENTILE_CONT (continuous percentile lookup), and PERCENTILE_DISC (discreet percentile lookup). The following queries demonstrate these functions, which are all closely related, by querying sales figures across each quarter of two years.</p>
<p><pre class="brush: plain;">DECLARE @Sales table(Yr int, Qtr int, Amount money)
INSERT INTO @Sales VALUES
  (2010, 1, 5000), (2010, 2, 6000), (2010, 3, 7000), (2010, 4, 2000),
  (2011, 1, 1000), (2011, 2, 2000), (2011, 3, 3000), (2011, 4, 4000)

-- Distributed across all 8 quarters
SELECT
  Yr, Qtr, Amount,
  R = RANK() OVER(ORDER BY Amount),
  PR = PERCENT_RANK() OVER(ORDER BY Amount),
  CD = CUME_DIST() OVER(ORDER BY Amount)
 FROM @Sales
 ORDER BY Amount

-- Distributed (partitioned) by year with percentile lookups
SELECT
  Yr, Qtr, Amount,
  R = RANK() OVER(PARTITION BY Yr ORDER BY Amount),
  PR = PERCENT_RANK() OVER(PARTITION BY Yr ORDER BY Amount),
  CD = CUME_DIST() OVER(PARTITION BY Yr ORDER BY Amount),
  PD5 = PERCENTILE_DISC(.5) WITHIN GROUP (ORDER BY Amount) OVER(PARTITION BY Yr),
  PD6 = PERCENTILE_DISC(.6) WITHIN GROUP (ORDER BY Amount) OVER(PARTITION BY Yr),
  PC5 = PERCENTILE_CONT(.5) WITHIN GROUP (ORDER BY Amount) OVER(PARTITION BY Yr),
  PC6 = PERCENTILE_CONT(.6) WITHIN GROUP (ORDER BY Amount) OVER(PARTITION BY Yr)
 FROM @Sales
 ORDER BY Yr, Amount

Yr    Qtr  Amount   R  PR                 CD
----  ---  -------  -  -----------------  -----
2011  1    1000.00  1  0                  0.125
2011  2    2000.00  2  0.142857142857143  0.375
2010  4    2000.00  2  0.142857142857143  0.375
2011  3    3000.00  4  0.428571428571429  0.5
2011  4    4000.00  5  0.571428571428571  0.625
2010  1    5000.00  6  0.714285714285714  0.75
2010  2    6000.00  7  0.857142857142857  0.875
2010  3    7000.00  8  1                  1

Yr    Qtr  Amount   R  PR                 CD    PD5      PD6      PC5   PC6
----  ---  -------  -  -----------------  ----  -------  -------  ----  ----
2010  4    2000.00  1  0                  0.25  5000.00  6000.00  5500  5800
2010  1    5000.00  2  0.333333333333333  0.5   5000.00  6000.00  5500  5800
2010  2    6000.00  3  0.666666666666667  0.75  5000.00  6000.00  5500  5800
2010  3    7000.00  4  1                  1     5000.00  6000.00  5500  5800
2011  1    1000.00  1  0                  0.25  2000.00  3000.00  2500  2800
2011  2    2000.00  2  0.333333333333333  0.5   2000.00  3000.00  2500  2800
2011  3    3000.00  3  0.666666666666667  0.75  2000.00  3000.00  2500  2800
2011  4    4000.00  4  1                  1     2000.00  3000.00  2500  2800</pre></p>
<p>The new functions are all based on the <em>RANK</em> function introduced in SQL Server 2005. So both these queries also report on <em>RANK</em>, which will aid both in my explanation and your understanding of each of the new functions.</p>
<h3><em>PERCENT_RANK</em> and <em>CUME_DIST</em></h3>
<p>In the first query, <em>PERCENT_RANK</em> and <em>CUME_DIST</em> (aliased as <em>PR</em> and <em>CD</em> respectively) rank quarterly sales across the entire two year period. Look at the value returned by <em>RANK</em> (aliased as <em>R</em>). It ranks each row in the unpartitioned window (all eight quarters) by dollar amount. Both 2011Q2 and 2010Q4 are tied for $2,000 in sales, so <em>RANK</em> assigns them the same value (2). The next row break the tie, so <em>RANK</em> continues with 4, which accounts for the “empty slot” created by the two previous rows that were tied.</p>
<p>Now examine the values returned by <em>PERCENT_RANK</em> and <em>CUME_DIST</em>. Notice how they reflect the same information as <em>RANK</em> with decimal values ranging from 0 and 1. The only difference between the two is a slight variation in their formulaic implementation, such that <em>PERCENT_RANK</em> always starts with 0 while <em>CUME_DIST</em> always starts with a value greater than 0. Specifically, <em>PERCENT_RANK</em> returns (<em>RANK</em> – 1) / (N – 1) for each row, where N is the total number of rows in the window. This always returns 0 for the first (or only) row in the window. <em>CUME_DIST</em> returns <em>RANK</em> / N, which always returns a value greater than 0 for the first row in the window (which would be 1, if there’s only row). For windows with two or more rows, both functions return 1 for the last row in the window with decimal values distributed among all the other rows.</p>
<p>The second query examines the same sales figures, only this time the result set is partitioned by year. There are no ties within each year, so <em>RANK</em> assigns the sequential numbers 1 through 4 to each of the quarters, for 2010 and 2011, by dollar amount. You can see that <em>PERCENT_RANK</em> and <em>CUME_DIST</em> perform the same <em>RANK</em> calculations as explained for the first query (only, again, partitioned by year this time).</p>
<h3><em>PERCENTILE_DISC</em> and <em>PERCENTILE_CONT</em></h3>
<p>This query also demonstrates <em>PERCENTILE_DISC</em> and <em>PERCENTILE_CONT</em>. These very similar functions each accept a percentile parameter (the desired <em>CUME_DIST</em> value) and “reach in” to the window for the row at or near that percentile. The code demonstrates by calling both functions twice, once with a percentile parameter value of .5 and once with .6, returning columns aliased as <em>PD5</em>, <em>PD6</em>, <em>PC5</em>, and <em>PC6</em>. Both functions examine the <em>CUME_DIST</em> value for each row in the window to find the one nearest to .5 and .6. The subtle difference between them is that <em>PERCENTILE_DISC</em> will return a precise (discreet) value from the row with the matching percentile (or greater), while <em>PERCENTILE_CONT</em> interpolates a value based on a continuous range. Specifically, <em>PERCENTILE_CONT</em> returns a value ranging from the row matching the specified percentile—or a calculated value higher than that (based on the specified percentile) if there is no exact match—and the row with the next higher percentile in the window. This explains the values they return in this query.</p>
<blockquote><p>Notice that these functions define their window ordering using <em>ORDER BY</em> in a <em>WITHIN GROUP</em> clause rather than in the <em>OVER</em> clause. Thus, you do not (and cannot) specify <em>ORDER BY</em> in the <em>OVER</em> clause. The <em>OVER</em> clause is still required, however, so <em>OVER</em> (with empty parentheses) must be specified even if you don’t want to partition using <em>PARTITION BY</em>.</p></blockquote>
<p>For the year 2010, the .5 percentile (<em>CUME_DIST</em> value) is located exactly on quarter 1, which had $5,000 in sales. Thus <em>PERCENTILE_DISC(.5)</em> returns 5000. There is no row in the window with a percentile of .6, so <em>PERCENTILE_DISC(.6)</em> matches up against the first row with a percentile greater than or equal to .6, which is the row for quarter 2 with $6,000 in sales, and thus returns 6000. In both cases, <em>PERCENTILE_DISC</em> returns a discreet value from a row in the window at or greater than the specified percentile. The same calculations are performed for 2011, returning 2000 for <em>PERCENTILE_DISC(.5)</em> and 3000 for <em>PERCENTILE_DISC(.6)</em>, corresponding to the $2,000 in sales for quarter 2 (percentile .5) and the $3,000 in sales for quarter 3 (percentile .75)</p>
<p>As I stated, <em>PERCENTILE_CONT</em> is very similar. It takes the same percentile parameter to find the row in the window matching that percentile. If there is no exact match, the function calculates a value based on the scale of percentiles distributed across the entire window, rather than looking ahead to the row having the next greater percentile value, as <em>PERCENTILE_DISC</em> does. Then it returns the median between that value and the value found in the row with the next greater percentile. For 2010, the .5 percentile matches up with 5000 (as before). The next percentile in the window is for .75 for 6000. The median between 5000 and 6000 is 5500 and thus, <em>PERCENTILE_CONT(.5)</em> returns 5500. There is no row in the window with a percentile of .6, so <em>PERCENTILE_CONT(.6)</em> calculates what the value for .6 would be (somewhere between 5000 and 6000, a bit closer to 5000) and then calculates the median between that value and the next percentile in the window (again, .75 for 6000). Thus, <em>PERCENTILE_CONT(.6)</em> returns 5800; slightly higher than the 5500 returned for <em>PERCENTILE_CONT(.5)</em>.</p>
<h3>Conclusion</h3>
<p>This post explained the eight new analytic functions added to T-SQL in SQL Server 2012. These new functions, plus the running and sliding aggregation capabilities covered in <a href="http://lennilobel.wordpress.com/2011/12/12/sql-server-2012-windowing-functions-part-1-of-2-running-and-sliding-aggregates/">Part 1</a>, greatly expand the windowing capabilities of the <em>OVER</em> clause available since SQL Server 2005.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/lennilobel.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/lennilobel.wordpress.com/1112/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=lennilobel.wordpress.com&#038;blog=6063141&#038;post=1112&#038;subd=lennilobel&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://lennilobel.wordpress.com/2012/01/03/sql-server-2012-windowing-functions-part-2-of-2-new-analytic-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e98e16e27fd8ae3e079834b881c74f72?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">lennilobel</media:title>
		</media:content>
	</item>
	</channel>
</rss>
