<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Isaac @ MSDN : t-sql</title><link>http://blogs.msdn.com/isaac/archive/tags/t-sql/default.aspx</link><description>Tags: t-sql</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Where are my Spatial Columns?</title><link>http://blogs.msdn.com/isaac/archive/2008/04/15/where-are-my-spatial-columns.aspx</link><pubDate>Tue, 15 Apr 2008 23:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398197</guid><dc:creator>isaac</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/isaac/comments/8398197.aspx</comments><wfw:commentRss>http://blogs.msdn.com/isaac/commentrss.aspx?PostID=8398197</wfw:commentRss><wfw:comment>http://blogs.msdn.com/isaac/rsscomments.aspx?PostID=8398197</wfw:comment><description>&lt;DIV&gt;
&lt;P&gt;Hi Folks,&lt;/P&gt;
&lt;P&gt;I've been asked a few times how to find out what spatial columns are defined in a database.&amp;nbsp; We don't have any special table for this, but you can easily find out by looking at the usual system views:&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; ta.name &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; table_name, co.name &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; column_name&lt;BR&gt;&lt;SPAN class=kwrd&gt;FROM&lt;/SPAN&gt; sys.tables ta &lt;SPAN class=kwrd&gt;JOIN&lt;/SPAN&gt; sys.columns co&lt;BR&gt;      &lt;SPAN class=kwrd&gt;ON&lt;/SPAN&gt; ta.object_id = co.object_id&lt;BR&gt;&lt;SPAN class=kwrd&gt;JOIN&lt;/SPAN&gt; sys.types ty&lt;BR&gt;      &lt;SPAN class=kwrd&gt;ON&lt;/SPAN&gt; co.user_type_id = ty.user_type_id&lt;BR&gt;&lt;SPAN class=kwrd&gt;WHERE&lt;/SPAN&gt; ty.name = &lt;SPAN class=str&gt;'geography'&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;OR&lt;/SPAN&gt; ty.name = &lt;SPAN class=str&gt;&lt;FONT color=red&gt;'geometry'&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;There's nothing special about spatial here: you can replace the type names in the WHERE clause of the query with any other type you'd like to find as well.&amp;nbsp; For example, a simple change finds all integer columns:&lt;/P&gt;
&lt;DIV&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; ta.name &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; table_name, co.name &lt;SPAN class=kwrd&gt;as&lt;/SPAN&gt; column_name&lt;BR&gt;&lt;SPAN class=kwrd&gt;FROM&lt;/SPAN&gt; sys.tables ta &lt;SPAN class=kwrd&gt;JOIN&lt;/SPAN&gt; sys.columns co&lt;BR&gt;      &lt;SPAN class=kwrd&gt;ON&lt;/SPAN&gt; ta.object_id = co.object_id&lt;BR&gt;&lt;SPAN class=kwrd&gt;JOIN&lt;/SPAN&gt; sys.types ty&lt;BR&gt;      &lt;SPAN class=kwrd&gt;ON&lt;/SPAN&gt; co.user_type_id = ty.user_type_id&lt;BR&gt;&lt;SPAN class=kwrd&gt;WHERE&lt;/SPAN&gt; ty.name = &lt;SPAN class=str&gt;'int'&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Cheers, &lt;BR&gt;-Isaac&lt;/P&gt;
&lt;P&gt;[16 April 2008]:&amp;nbsp;Updated to correct a typo in the first query.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8398197" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/isaac/archive/tags/sql+server/default.aspx">sql server</category><category domain="http://blogs.msdn.com/isaac/archive/tags/t-sql/default.aspx">t-sql</category><category domain="http://blogs.msdn.com/isaac/archive/tags/spatial/default.aspx">spatial</category></item><item><title>Connect and Implicit Casts</title><link>http://blogs.msdn.com/isaac/archive/2008/04/10/connect-and-implicit-casts.aspx</link><pubDate>Thu, 10 Apr 2008 19:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8375523</guid><dc:creator>isaac</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/isaac/comments/8375523.aspx</comments><wfw:commentRss>http://blogs.msdn.com/isaac/commentrss.aspx?PostID=8375523</wfw:commentRss><wfw:comment>http://blogs.msdn.com/isaac/rsscomments.aspx?PostID=8375523</wfw:comment><description>&lt;P&gt;Hi Folks,&lt;/P&gt;
&lt;P&gt;Perhaps it is surprising, based on the content here, that I'm not a full-time spatial head here in SQL Server land.&amp;nbsp; (We leave that job to &lt;A href="http://blogs.msdn.com/edkatibah/default.aspx" mce_href="http://blogs.msdn.com/edkatibah/default.aspx"&gt;Ed&lt;/A&gt;.)&amp;nbsp; I have, of course, been spending a lot of time on spatial, but it turns out I have other responsibilities as well, particularly around the broader type system.&amp;nbsp; One of my jobs is to take a look at issues that come in through &lt;A href="http://connect.microsoft.com/" mce_href="http://connect.microsoft.com"&gt;Connect&lt;/A&gt; that have to do with the type system and make sure they get handled appropriately.&lt;/P&gt;
&lt;P&gt;(If you don't use Connect, please do!&amp;nbsp; Issues filed there funnel directly into our bug-tracking system, giving you a direct line to the engineering team.&amp;nbsp; It is &lt;I&gt;the&lt;/I&gt; place to go with that pesky bug or feature request.)&lt;/P&gt;
&lt;P&gt;These Connect issues are an interesting mix. some good, solid bugs, and some not bugs at all.&amp;nbsp; It's these latter ones I find most interesting, since the majority of them point out quirks in our behavior that, while correct (and often even documented) are still somewhat confusing.&amp;nbsp; I'm going to try to start writing a bit more about common issues here in the hopes of clearing at least a little of that confusion.&lt;/P&gt;
&lt;P&gt;Which brings us to implicit casts.&amp;nbsp; An implicit cast is a cast that happens without any explicit direction from the user.&amp;nbsp; If you use CAST or CONVERT, you're using an explicit cast, and that's not what we're talking about here.&amp;nbsp; We're talking about code like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; &lt;SPAN class=str&gt;'1'&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;UNION&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; 37&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Since the UNION operator has to produce a consistent result, the types of each of its inputs must be the same.&amp;nbsp; Of course, that's not the case here: the first SELECT yields a varchar, the second an int.&amp;nbsp; Faced with this, the system inserts an implicit conversion, attempting to coerce the varchar to an int.&lt;/P&gt;
&lt;P&gt;But why convert the varchar to an int and not the other way around?&amp;nbsp; After all, it could convert 37 to '37' instead.&amp;nbsp; First, we have to understand that while this case is simple---the values are literals---this need not be the case. and so it may be very hard for the system to determine up-front what the actual values are.&amp;nbsp; E.g.:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; T.a &lt;SPAN class=rem&gt;-- a varchar column&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;UNION&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; U.b &lt;SPAN class=rem&gt;-- an int column&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Or worse:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; M.a &lt;SPAN class=kwrd&gt;FROM&lt;/SPAN&gt; &lt;SPAN class=rem&gt;-- some horribly complex query returning a varchar&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;UNION&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; N.b &lt;SPAN class=kwrd&gt;FROM&lt;/SPAN&gt; -- another equally horrible query returning an int&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In order to base this decision on the actual data, SQL Server would have to accumulate each side of the UNION, inspect all of the values, and hope to find a type that each of the values could be coerced to.&amp;nbsp; Perhaps worse, if the type depended on the actual data retrieved, then it could be very hard to determine what the result type of the query would be; it could even change if the data were updated.&lt;/P&gt;
&lt;P&gt;So SQL Server doesn't do this.&amp;nbsp; Instead of basing the conversion on the data itself, it bases it on the type of the data.&amp;nbsp; So, when the server looks at any of these examples, all it really sees is:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; &amp;lt;&lt;SPAN class=kwrd&gt;varchar&lt;/SPAN&gt;&amp;gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;UNION&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; &amp;lt;&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;&amp;gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The server then decides which one to convert, in this case it converts the varchar to an int.&amp;nbsp; How does it make this choice?&amp;nbsp; It simply has a precedence list of types, which we can see in the &lt;A href="http://msdn2.microsoft.com/en-us/library/ms190309%28SQL.100%29.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms190309(SQL.100).aspx"&gt;Data Type Precedence&lt;/A&gt; topic of Books Online.&amp;nbsp; The abbreviated version is:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;1. user-defined data types (highest) &lt;BR&gt;2. sql_variant &lt;BR&gt;3. xml &lt;BR&gt;... &lt;BR&gt;16. int &lt;BR&gt;... &lt;BR&gt;27. varchar &lt;BR&gt;...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Int lands higher than varchar, and so the varchar is converted to an int.&amp;nbsp; The actual data returned by each select is not used at all in making this decision, only the types.&amp;nbsp; The system can make this decision with relatively simple logic, and the type of the result is consistent as well.&lt;/P&gt;
&lt;P&gt;This brings us to our pop-quiz.&amp;nbsp; What will this do?&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; &lt;SPAN class=str&gt;'a'&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;UNION&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=kwrd&gt;SELECT&lt;/SPAN&gt; 37&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'll give you a minute...&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Got it?&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Okay, here's the result:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;Msg 245, &lt;SPAN class=kwrd&gt;Level&lt;/SPAN&gt; 16, &lt;SPAN class=kwrd&gt;State&lt;/SPAN&gt; 1, Line 1&lt;BR&gt;Conversion failed &lt;SPAN class=kwrd&gt;when&lt;/SPAN&gt; converting the &lt;SPAN class=kwrd&gt;varchar&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;value&lt;/SPAN&gt; &lt;SPAN class=str&gt;'a'&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;to&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;data&lt;/SPAN&gt; type &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;.&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Make sense?&lt;/P&gt;
&lt;P&gt;Cheers, &lt;BR&gt;-Isaac&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8375523" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/isaac/archive/tags/sql+server/default.aspx">sql server</category><category domain="http://blogs.msdn.com/isaac/archive/tags/t-sql/default.aspx">t-sql</category></item></channel></rss>