{"id":595,"date":"2007-10-04T19:57:05","date_gmt":"2007-10-04T19:57:05","guid":{"rendered":"\/blogs\/kimberly\/post\/Follow-on-post-to-The-perils-of-case-insensitive-data-(and-our-life-in-tangent-land).aspx"},"modified":"2013-01-11T23:12:13","modified_gmt":"2013-01-12T07:12:13","slug":"follow-on-post-to-the-perils-of-case-insensitive-data-and-our-life-in-tangent-land","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/follow-on-post-to-the-perils-of-case-insensitive-data-and-our-life-in-tangent-land\/","title":{"rendered":"Follow on post to &#8220;The perils of case-insensitive data (and our life in tangent-land)&#8221;"},"content":{"rendered":"<p><P>OK, so&nbsp;thought I&#8217;d do a follow up to the post I did a couple of days ago titled: <a class=\"TitleLinkStyle\" href=\"https:\/\/www.sqlskills.com\/blogs\/kimberly\/the-perils-of-case-insensitive-data-and-our-life-in-tangent-land\/\" rel=\"bookmark\">The perils of case-insensitive data (and our life in tangent-land)<\/a>. The reason I&#8217;d like to followup on it is that I received some excellent comments and I want to make sure that you&#8217;re all aware of the tips\/tricks and recommendations that there were (some of you may not have returned to see all of the comments). Really, I was impressed by the speed at which people responded as well as the great comments (and things I learned!). It just reminds me of the fact that none of us can know everything AND that our SQL community is awesome in its willingness to share and communicate. <\/P><br \/>\n<P>As for the tips\/tricks and &#8220;yes, duh!&#8221; realizations I came to&#8230; here are the interesting points from the comments:<\/P><br \/>\n<P>First &#8211; why did my comparison work for a single character (e.g. &#8216;%A%&#8217;) but not when I did a character range (e.g. &#8216;%[A-Z]%&#8217;)? Well, it was because it was unicode! This was a &#8220;right! duh!&#8221; realization that I think I dreamed after I wrote this BUT, <a class=\"commentPermalinkStyle broken_link\" href=\"http:\/\/sqlblog.com\/blogs\/hugo_kornelis\/default.aspx\" rel=\"nofollow\">Hugo Kornelis<\/a> is exactly right in his comment. Thanks Hugo! Here is a direct cut\/paste of his comment: <\/P><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P><EM><FONT face=\"Times New Roman\" size=3>The reason [A-Z] doesn&#8217;t work, is that a collation doesn&#8217;t just govern case sensitive vs case insensitive but also (amongst others) the sort order of letters. And most case sensitive collations sort like A &#8211; a &#8211; B &#8211; b &#8211; &#8230; &#8211; Z &#8211; z. So [^A-Z] would include all letters except the lowercase z. <BR><BR>You can use [A-Z] to find uppercase characters in a binary collation (since all uppercase characters are in one range of ASCII, and all lowercase characters in another), but not in any other collation.<\/FONT><\/EM><\/P><br \/>\n<P>And, you can check out more from Hugo on his blog: <a href=\"http:\/\/sqlblog.com\/blogs\/hugo_kornelis\/default.aspx\" class=\"broken_link\">http:\/\/sqlblog.com\/blogs\/hugo_kornelis\/default.aspx<\/a><\/P><\/BLOCKQUOTE><br \/>\n<P>Second &#8211; the comparison query that I wrote all together (where I stated each letter individually in the WHERE clause) only took a few seconds to write (thanks to cut and paste :) AND it did work&#8230;And, sometimes getting something to work and moving on is all we can do (come on &#8211; you&#8217;ve ALL been there, eh? :). However, my main comment was that &#8220;it wasn&#8217;t pretty&#8221;. A much more elegant and unbelievably simple solution came from <SPAN class=commentPermalinkStyle>David R Buckingham<\/SPAN> (aren&#8217;t the great answers always the really simple ones :)). Here is a direct\/cut\/paste of his comment:<\/P><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P><FONT face=\"Times New Roman\" size=3><EM>The following query will return any fully lower case names in the table: <BR><BR>SELECT LastName <BR>FROM Person.Contact <BR>WHERE LastName COLLATE Latin1_General_CS_AS_KS_WS = LOWER( LastName ) COLLATE Latin1_General_CS_AS_KS_WS <\/EM><\/FONT><\/P><br \/>\n<P>I don&#8217;t believe that David has a blog&#8230; maybe he should :).<\/P><\/BLOCKQUOTE><br \/>\n<P>Third &#8211; a very cool and clever trick that came in from <A class=commentPermalinkStyle href=\"http:\/\/sqlservercode.blogspot.com\/\" rel=nofollow>Denis Gobo<\/A>&nbsp;is related to the performance of repeatedly doing case-sensitive searches on a case-insensitive column. I suggested that creating an additional column (preferably a computed column that uses the case sensitive collation) would be an easy and optimal solution. This is still definitely true when the case-insensitive values are NOT selective enough to warrant using an index and the case-sensitive values are&#8230; However, if both the case-sensitive AND the case-insensitive values are reasonably selective then the trick that helps is from his comment. Here is a direct cut\/paste of his comment:<\/P><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P><FONT face=\"Times New Roman\" size=3><EM>Kimberly, the way to force an index seek is to do this <BR><BR>SELECT * <BR>FROM MyTestContacts <BR>WHERE Lastname = N&#8217;adams&#8217; <BR>AND Lastname COLLATE Latin1_General_CS_AS_KS_WS = N&#8217;Adams&#8217; <BR><BR>The WHERE might return more than one row but the AND will return only the case sensitive one <BR><BR>I wrote about that a while back here: <BR><\/EM><\/FONT><A href=\"http:\/\/sqlservercode.blogspot.com\/2007\/05\/make-your-case-sensitive-searches-1000.html\"><FONT face=\"Times New Roman\" size=3><EM>http:\/\/sqlservercode.blogspot.com\/2007\/05\/make-your-case-sensitive-searches-1000.html<\/EM><\/FONT><\/A><FONT face=\"Times New Roman\" size=3><EM>&nbsp;<\/EM><\/FONT><\/P><br \/>\n<P>And, you can check out more from Denis on his blog: <A href=\"http:\/\/sqlservercode.blogspot.com\/\">http:\/\/sqlservercode.blogspot.com\/<\/A><\/P><\/BLOCKQUOTE><br \/>\n<P dir=ltr>Now, as for the issues related to creating a view in a database that has a different collation from the server&#8217;s collation&#8230; Here, I&#8217;m fairly certain that there&#8217;s still a bug. However, I&#8217;m happy to say that I don&#8217;t think that it&#8217;s the most likely situation that exists for collations. I think the two most likely situations are:<\/P><br \/>\n<OL dir=ltr><br \/>\n<LI><br \/>\n<DIV>The server has one collation. The database inherits that collation. The database developer makes column level collation changes throughout the db. This seems to work well. <STRONG><EM>OR<\/EM><\/STRONG><\/DIV><br \/>\n<LI><br \/>\n<DIV>The server has one collation. The database has a different collation. The database developer consistently uses that collation throughout their app. A good example of this is where people have case-sensitive databases on case-insensitive servers. This works fairly well (although there are some issues wrt to temp tables, etc. and <a href=\"https:\/\/www.sqlskills.com\/blogs\/kimberly\/2006\/05\/30\/changingdatabasecollationanddealingwithtempdbobjects.aspx\">default_collation<\/a> is a good thing to know).<\/DIV><\/LI><\/OL><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P>I guess there&#8217;s even a third one where column level changes are made in a database whose collation is different from the server but where there aren&#8217;t any views that also change the collation to yet a different collation (and this is where there seems to be a bug).<\/P><\/BLOCKQUOTE><br \/>\n<P>So, this was an excellent (and <EM>reasonably<\/EM> fun :) :) exercise to go through wrt collations. And, this is how I (<EM>we?<\/EM>) learn! I really want to thank everyone for reading &#8211; and commenting\/sharing! &#8211; the things they learned\/knew. That&#8217;s part of why I love the SQL Server community. And, speaking of which, I thought I&#8217;d end this entry with a few community links &#8211; as a reminder to everything that&#8217;s out there:<\/P><br \/>\n<UL><br \/>\n<LI><a href=\"http:\/\/technet.microsoft.com\/en-us\/sqlserver\/bb671052\" class=\"broken_link\">SQL Server &#8220;Community&#8221; page on TechNet<\/a><\/LI><br \/>\n<LI><a href=\"https:\/\/mvp.support.microsoft.com\/default.aspx?scid=gp;[ln];mvpnosuchproduct&amp;style=error\" class=\"broken_link\">SQL Server MVPs<\/a><\/LI><br \/>\n<LI><a href=\"http:\/\/www.microsoftregionaldirectors.com\/\" class=\"broken_link\">Microsoft Regional Directors<\/a><\/LI><br \/>\n<LI><a href=\"http:\/\/blogs.msdn.com\/b\/sqlserverstorageengine\/archive\/2007\/02\/14\/wow-lots-of-blogs-from-the-sql-product-team.aspx\" class=\"broken_link\">Blogs from the SQL Server team<\/a> (and, it&#8217;s <a href=\"http:\/\/www.SQLskills.com\/blogs\/paul)\" class=\"broken_link\">Paul<\/a> who originally blogged this when he was still with the SQL Server Storage Engine team)<\/LI><\/UL><br \/>\n<P>Thanks for reading! Thanks for commenting! <BR>kt<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>OK, so&nbsp;thought I&#8217;d do a follow up to the post I did a couple of days ago titled: The perils of case-insensitive data (and our life in tangent-land). The reason I&#8217;d like to followup on it is that I received some excellent comments and I want to make sure that you&#8217;re all aware of the [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[65,78],"tags":[],"class_list":["post-595","post","type-post","status-publish","format-standard","hentry","category-sql-server-2005","category-tips"],"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/posts\/595","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/comments?post=595"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/posts\/595\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/media?parent=595"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/categories?post=595"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/tags?post=595"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}