{"id":599,"date":"2007-10-03T09:01:52","date_gmt":"2007-10-03T09:01:52","guid":{"rendered":"\/blogs\/kimberly\/post\/The-perils-of-case-insensitive-data-(and-our-life-in-tangent-land).aspx"},"modified":"2013-01-02T06:57:17","modified_gmt":"2013-01-02T14:57:17","slug":"the-perils-of-case-insensitive-data-and-our-life-in-tangent-land","status":"publish","type":"post","link":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/the-perils-of-case-insensitive-data-and-our-life-in-tangent-land\/","title":{"rendered":"The perils of case-insensitive data (and our life in tangent-land)"},"content":{"rendered":"<p><P>OK, have you ever been working on one thing&#8230;that led you to another (<EM>and another and another<\/EM>) and then you seem to have lost hours? OK, I know. That&#8217;s our life [in the computer industry and I&#8217;m sure others!] &#8211; putting out fires and chasing strange behaviors that we eventually call &#8220;gremlins&#8221; when we really can&#8217;t figure them out (<EM>especially when they don&#8217;t repro<\/EM>). And, I know that we all want to be incredibly prepared but, sometimes bugs happen. And, sometimes bugs lead to serious problems possibly even data corruption\/loss (which I&#8217;ve seen) and NO, I&#8217;m not directly relating this to anything about SQL Server. I&#8217;m just wanting to stress the necessity of a backup strategy (<EM>ah, a <STRONG>*tested*<\/STRONG> backup strategy<\/EM>) but, the bugs I&#8217;ve run into today are really not all that serious (<STRONG>they do NOT corrupt data<\/STRONG>). But, they do lead me to believe that far fewer changes are made to collations than I had thought? Or, that many of you change collations at the most granular level (probably at the column level?) and that database collation changes are done but without additional column level changes later.&nbsp;&nbsp;<\/P><br \/>\n<P>And, that&#8217;s really the point of this blog post&#8230; for now, I&#8217;m going to recommend that you make changes at the column-level OR you don&#8217;t make additional changes AFTER you&#8217;ve changed a particular database&#8217;s collation. In other words, if you have a case insensitive server and a case sensitive database then things will probably work well. You can even leverage things like <a href=\"https:\/\/www.sqlskills.com\/blogs\/kimberly\/2006\/05\/30\/changingdatabasecollationanddealingwithtempdbobjects.aspx\">default_collation<\/a> for temp tables. However, if you try to make addition changes to collations in other objects &#8211; such as views &#8211; it doesn&#8217;t seem to work. Basically, I&#8217;ve run into problems creating views with different collations only when the database&#8217;s collation is different than the server&#8217;s collation. So far, that&#8217;s the only thing that I&#8217;ve found that&#8217;s wrong with what I&#8217;ve been doing. And, I didn&#8217;t even figure this one out on my own &#8211; I did a live search on the error and found this: <a href=\"http:\/\/www.bing.com\/Search?q=72171562874629&amp;mkt=en-US&amp;lang=en-US&amp;w=286a60c3&amp;FORM=CVRE\">http:\/\/cc.msnscache.com\/cache.aspx?q=72171562874629&amp;mkt=en-US&amp;lang=en-US&amp;w=286a60c3&amp;FORM=CVRE<\/a> which seems like the same problem I&#8217;m having (and sorry for the cached page, I couldn&#8217;t seem to get to the live page).<\/P><br \/>\n<P>Regardless of this issue (is it a bug?), the real reason for this blog post is that a great discussion came up on the <a href=\"http:\/\/www.microsoftregionaldirectors.com\/\" class=\"broken_link\">Regional Director<\/a> tech alias (it&#8217;s an internal thing we use to leverage each other&#8217;s skills). The original question led to a few discussions and in the end, I think there are really two questions that I thought I&#8217;d discuss here:<\/P><br \/>\n<P>#1) do you want a ONE-TIME way of checking a bunch of data to find rows that are lower-case (and shouldn&#8217;t be)<BR>#2) do you want to REPEATEDLY find rows based based on a case-sensitive search (where the data is stored case-insensitive).<\/P><br \/>\n<P>In my first response, I answered #2. And, I&#8217;m going to start with that one here too. If you want to query a case-insensitive column with a case-sensitive search then changing the collation on the fly (with a where clause) works (although there are some performance issues related to this). So, I took an old example of mine (which was against pubs) and I decided that it needed a refresh (meaning, I wanted to update this to work against AdventureWorks). And, that&#8217;s where half of my fun today started since this is where I&#8217;ve run into what I think is a bug. Anyway, let&#8217;s start with what works:<\/P><FONT color=#008000 size=2><br \/>\n<P>&#8212; First, I&#8217;ll create a test database. Without a collation specified, <BR>&#8212; it will use the server&#8217;s default collation.<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>CREATE<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>DATABASE<\/FONT><FONT size=2><FONT color=#000000> TestAdventureWorks<BR><\/FONT>go<\/P><\/FONT><FONT color=#008000 size=2><br \/>\n<P>&#8212; Verify the database collation<BR><\/FONT><FONT color=#0000ff size=2>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#ff00ff size=2>DATABASEPROPERTYEX<\/FONT><FONT color=#808080 size=2>(<\/FONT><FONT color=#ff0000 size=2>&#8216;TestAdventureWorks&#8217;<\/FONT><FONT color=#808080 size=2>,<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#ff0000 size=2>&#8216;Collation&#8217;<\/FONT><FONT color=#808080 size=2>)<BR><\/FONT><FONT size=2>go<\/P><\/FONT><FONT color=#008000 size=2><br \/>\n<P>&#8212; database is set to SQL_Latin1_General_CP1_CI_AS as expected<BR>&#8212; this is a case-insensitive database<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>USE<\/FONT><FONT size=2><FONT color=#000000> TestAdventureWorks<BR><\/FONT>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT color=#000000 size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2><FONT color=#000000> LastName<BR><\/FONT><\/FONT><FONT color=#808080 size=2>,<\/FONT><FONT size=2> FirstName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> FirstName<BR><\/FONT><FONT color=#808080 size=2>,<\/FONT><FONT size=2> MiddleName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> MiddleName<BR><\/FONT><FONT color=#0000ff size=2>INTO<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT color=#000000 size=2> Adventureworks<\/FONT><FONT color=#808080 size=2>.<\/FONT><FONT color=#000000 size=2>Person<\/FONT><FONT color=#808080 size=2>.<\/FONT><FONT size=2><FONT color=#000000>Contact<BR><\/FONT>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> Lastname <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (86 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> Lastname <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (86 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> Lastname <\/FONT><FONT color=#0000ff size=2>COLLATE<\/FONT><FONT color=#000000 size=2> Latin1_General_CS_AS_KS_WS <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (86 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> Lastname <\/FONT><FONT color=#0000ff size=2>COLLATE<\/FONT><FONT color=#000000 size=2> Latin1_General_CS_AS_KS_WS <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (0 row(s) affected)<\/P><br \/>\n<P>&#8212; Next, create a view:<BR><\/FONT><FONT color=#0000ff size=2>CREATE<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>VIEW<\/FONT><FONT size=2><FONT color=#000000> ContactLastNameCaseSensitive<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>AS<BR>SELECT<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#0000ff size=2>COLLATE<\/FONT><FONT color=#000000 size=2> Latin1_General_CS_AS_KS_WS <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2><FONT color=#000000> CSName<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts<BR><\/FONT>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> ContactLastNameCaseSensitive<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (86 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> ContactLastNameCaseSensitive<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (0 row(s) affected)<\/P><\/FONT><br \/>\n<P>And, everything works&#8230; in TestAdventureworks. In&nbsp;the *real*&nbsp;AdventureWorks, I get an error when I try to create the view:<BR><FONT color=#ff0000 size=2>Msg 2791, Level 16, State 5, Procedure ContactLastNameCaseSensitive, Line 3<BR>Could not resolve expression for schemabound object or constraint.<\/P><\/FONT><br \/>\n<P>So, this is the first issue. It seems as though you can&#8217;t create the view if your database has a different collation than the server collation. Well, (again), I haven&#8217;t spent all that much time on this one but I did repro what the chain on the forum seemed to have found.<\/P><br \/>\n<P>Now, as for the second issue&#8230; the query can be EXTREMELY painful and slow if you run this against a large set of data. See, changing the collation on the fly will need to perform a row-by-row comparison of the data. So, to minimize that HUGE hit on performance &#8211; you have two options.<\/P><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P>1) actually consider changing the column&#8217;s collation so that it matches your queries AND then create an index (note: the actual use of the index will be determined by the selectivity of the data).<\/P><FONT color=#0000ff size=2><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT color=#000000 size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2><FONT color=#000000> LastName<BR><\/FONT><\/FONT><FONT color=#808080 size=2>,<\/FONT><FONT size=2> FirstName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> FirstName<BR><\/FONT><FONT color=#808080 size=2>,<\/FONT><FONT size=2> MiddleName <\/FONT><FONT color=#0000ff size=2>collate<\/FONT><FONT size=2> database_default <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> MiddleName<BR><\/FONT><FONT color=#0000ff size=2>INTO<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts2<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT color=#000000 size=2> Adventureworks<\/FONT><FONT color=#808080 size=2>.<\/FONT><FONT color=#000000 size=2>Person<\/FONT><FONT color=#808080 size=2>.<\/FONT><FONT size=2><FONT color=#000000>Contact<BR><\/FONT>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>ALTER<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>TABLE<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts2<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>ALTER<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>COLUMN<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#0000ff size=2>nvarchar<\/FONT><FONT color=#808080 size=2>(<\/FONT><FONT color=#000000 size=2>100<\/FONT><FONT color=#808080 size=2>)<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>COLLATE<\/FONT><FONT size=2><FONT color=#000000> Latin1_General_CS_AS_KS_WS<BR><\/FONT>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>CREATE<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>INDEX<\/FONT><FONT color=#000000 size=2> CSNameInd <\/FONT><FONT color=#0000ff size=2>on<\/FONT><FONT color=#000000 size=2> MyTestContacts2 <\/FONT><FONT color=#808080 size=2>(<\/FONT><FONT color=#000000 size=2>LastName<\/FONT><FONT color=#808080 size=2>)<BR><\/FONT><FONT size=2>go<\/P><\/FONT><FONT color=#008000 size=2><br \/>\n<P>&#8212; let&#8217;s use a query that&#8217;s highly selective (selective enough to use the index):<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts2<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Barlow&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (1 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts2 <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> LastName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;barlow&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (0 row(s) affected)<\/P><\/BLOCKQUOTE><\/FONT><br \/>\n<P>2) create an index with a different collation&#8230; but this is harder than it sounds as the CREATE INDEX statement doesn&#8217;t directly allow changing collation (however, it should!). But, you can do this by either creating another column (real or computed) with the case-sensitive collation and then indexing it OR you could do this through an indexed view (but that adds a few complexities as well). I think the computed column that&#8217;s indexed is GREAT if the searches are generally highly selective. If they are not, then it is probably better to create a real column &#8211; as a computed copy of the inserted value &#8211; that is case sensitive. However, at that point, I&#8217;m not entirely sure why you&#8217;re keeping the case-insensitive version around&#8230;unless it&#8217;s to keep the actual inserted value (maybe for printing and\/or display?). Regardless, here&#8217;s how you can create an indexed computed column.<\/P><FONT color=#0000ff size=2><br \/>\n<P>ALTER<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>TABLE<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts<BR><\/FONT><\/FONT><FONT color=#0000ff size=2>ADD<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT>CSName <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> LastName <\/FONT><FONT color=#0000ff size=2>COLLATE<\/FONT><FONT size=2> Latin1_General_CS_AS_KS_WS<BR>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (86 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;adams&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (0 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>CREATE<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#0000ff size=2>INDEX<\/FONT><FONT color=#000000 size=2> CSNameInd <\/FONT><FONT color=#0000ff size=2>ON<\/FONT><FONT color=#000000 size=2> MyTestContacts <\/FONT><FONT color=#808080 size=2>(<\/FONT><FONT color=#000000 size=2>CSName<\/FONT><FONT color=#808080 size=2>)<BR><\/FONT><FONT size=2>go<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#ff0000 size=2>&#8216;Barlow&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (1 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2><FONT color=#000000> <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2><FONT color=#000000> MyTestContacts <BR><\/FONT><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT color=#000000 size=2> CSName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT color=#000000 size=2> <\/FONT><FONT color=#ff0000 size=2>&#8216;barlow&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (0 row(s) affected)<\/FONT><\/P><br \/>\n<P><FONT color=#000000>And, the index will be used if the query is highly selective.<\/FONT><\/P><\/BLOCKQUOTE><br \/>\n<P dir=ltr><FONT color=#000000>OK, so that ends the answer to part 2 of the question (see how tangents can take us a bit off track :)&#8230;. <STRONG><\/STRONG><\/FONT><\/P><br \/>\n<P dir=ltr><FONT color=#000000><STRONG>Now, let&#8217;s get back to question #1.<\/STRONG><\/FONT><\/P><br \/>\n<P dir=ltr><FONT color=#000000>What if you want to do a one-time search through your data to find all of the lower case data? Well, there are a few thoughts here&#8230;. First, let&#8217;s modify the ONE Barlow row to be lowercase barlow so that we have something to find:<\/FONT><\/P><FONT color=#000000><FONT color=#0000ff size=2><br \/>\n<P>UPDATE<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>SET<\/FONT><FONT size=2> LastName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;barlow&#8217;<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> LastName <\/FONT><FONT color=#808080 size=2>=<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;Barlow&#8217;<\/FONT><FONT size=2> <BR>go <FONT color=#008000 size=2>&#8212; (1 row(s) affected)<\/FONT><\/FONT><\/P><br \/>\n<P><FONT size=2>NOTE: This is an ABSOLUTELY horrible quiery as I didn&#8217;t use any key to point to the exact row I wanted to modify. Had there been a lot of Barlow&#8217;s I would have modified them all. This worked here because I knew there was only one row. But, all of your tables should have a primary key, etc. (not even going to begin this tangent :).<\/P><br \/>\n<P dir=ltr><\/FONT>Now, having said that&#8230; let&#8217;s see if we can find this row easily? You <STRONG><EM>should <\/EM><\/STRONG>be able to do this using Transact-SQL and using some type&nbsp;of wildcard pattern matching such as:<\/FONT><\/P><FONT color=#000000><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;b%&#8217;<BR><FONT color=#000000>go<\/FONT> <FONT color=#008000 size=2>&#8212; (1 row(s) affected)<\/FONT><\/FONT><\/P><br \/>\n<P><FONT color=#ff0000 size=2><FONT color=#000000>And, that works without any problems. <\/FONT><\/FONT><\/P><br \/>\n<P><FONT color=#ff0000 size=2><FONT color=#000000>So, what about NOT an upper case B.<\/FONT><\/FONT><\/P><FONT color=#ff0000 size=2><FONT color=#000000><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>NOT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>LIKE<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;B%&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (18768 row(s) affected)<\/P><\/FONT><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>NOT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>LIKE<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%B%&#8217;<BR><\/FONT><FONT size=2>go <\/FONT><FONT color=#008000 size=2>&#8212; (18765 row(s) affected)<\/FONT><\/P><br \/>\n<P><FONT color=#008000 size=2><FONT color=#000000>tangent number 87 &lt;g&gt;: if you&#8217;re wondering what the 3 rows are (<EM>as was I <\/EM>:)&#8230; they are 1 row of O&#8217;Brien and 2 rows of Smith-Bates. Here&#8217;s that query: <FONT color=#0000ff size=2><\/P><br \/>\n<BLOCKQUOTE dir=ltr style=\"MARGIN-RIGHT: 0px\"><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>(<\/FONT><FONT color=#0000ff size=2>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>NOT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>LIKE<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;B%&#8217;<\/FONT><FONT color=#808080 size=2>)<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>AS<\/FONT><FONT size=2> Bs<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> <\/FONT><FONT color=#ff0000 size=2>&#8216;%B%&#8217;<BR><\/FONT><FONT size=2>go<\/FONT><\/P><\/BLOCKQUOTE><br \/>\n<P dir=ltr><FONT size=2>OK, so, I thought we were there&#8230; I thought we could go to what I thought was the next logical step&#8230;..<\/FONT><\/P><FONT size=2><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>NOT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>LIKE<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%[A-B]%&#8217;<BR><FONT color=#000000>go<\/FONT><\/FONT><\/P><br \/>\n<P>And&#8230; well, we lose barlow from the result set. For some reason&#8230;when you do ranges of characters it seems to lose the case??? I remember that [A-Z] and [a-z] were different in some release? Is this a regression? Someone help me out with this one as I&#8217;m without a clue. In the end, the ONLY way I could get this to work is to do this:<\/P><FONT color=#0000ff size=2><br \/>\n<P>SELECT<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>*<\/FONT><FONT size=2> <\/FONT><FONT color=#0000ff size=2>FROM<\/FONT><FONT size=2> MyTestContacts2<BR><\/FONT><FONT color=#0000ff size=2>WHERE<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%A%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%B%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%C%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%D%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%E%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%F%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%G%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%H%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%I%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%J%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%K%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%L%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%M%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%N%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%O%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%P%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%Q%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%R%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%S%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%T%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%U%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%V%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%W%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%X%&#8217;<\/FONT><FONT size=2> <BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%Y%&#8217;<BR><\/FONT><FONT color=#808080 size=2>AND<\/FONT><FONT size=2> Lastname <\/FONT><FONT color=#808080 size=2>not<\/FONT><FONT size=2> <\/FONT><FONT color=#808080 size=2>like<\/FONT><FONT size=2> N<\/FONT><FONT color=#ff0000 size=2>&#8216;%Z%&#8217;<BR><FONT size=2><FONT color=#000000>go<\/FONT><\/FONT><\/FONT><\/P><br \/>\n<P><FONT color=#ff0000 size=2><FONT size=2><FONT color=#000000>And, well, that works. But, it is NOT pretty! The query&#8217;s going to require a table scan anyway AND it is a one-time query. I&#8217;m OK with this as a solution to this problem BUT, am I missing something here? Please tell me there&#8217;s something more clever here? Is this a bug?<\/FONT><\/FONT><\/FONT><\/P><br \/>\n<P><FONT color=#ff0000 size=2><FONT size=2><FONT color=#000000>I&#8217;m definitely interested in feedback on this one!<BR>kt<\/FONT><\/FONT><\/FONT><\/FONT><\/FONT><\/FONT><\/FONT><\/FONT><\/FONT><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>OK, have you ever been working on one thing&#8230;that led you to another (and another and another) and then you seem to have lost hours? OK, I know. That&#8217;s our life [in the computer industry and I&#8217;m sure others!] &#8211; putting out fires and chasing strange behaviors that we eventually call &#8220;gremlins&#8221; when we really [&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],"tags":[],"class_list":["post-599","post","type-post","status-publish","format-standard","hentry","category-sql-server-2005"],"_links":{"self":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/posts\/599","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=599"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/posts\/599\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/media?parent=599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/categories?post=599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlskills.com\/blogs\/kimberly\/wp-json\/wp\/v2\/tags?post=599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}