The top 2 answers (from Adam Robinson and Andrei Kainikov ) are quite correct, as they technically work, but their explanations are incorrect and in many cases can be misleading. For example, although the SQL_Latin1_General_CP1_CI_AS will work in many cases, it should not be considered a suitable collation without the SQL_Latin1_General_CP1_CI_AS register. In fact, given that OP operates in a case-sensitive sorted database (or possibly binary), we know that OP does not use the sorting that is used by default for so many installations (especially any installed on the OS). using American English as the language): SQL_Latin1_General_CP1_CI_AS . Of course, the OP can use SQL_Latin1_General_CP1_CS_AS , but when working with VARCHAR data, it is important not to change the code page, as this can lead to data loss, and this is controlled by the language / culture of matching (i.e. Latin1_General vs French against Hebrew, etc. ) Please see item No. 9 below.
The remaining four answers are incorrect to varying degrees.
I will clear up all the misunderstandings so that readers can make the most appropriate / effective choice.
Do not use UPPER() . This is completely unnecessary extra work. Use the COLLATE . String comparisons need to be done anyway, but using UPPER() should also check, character by character, to see if there is a mapping in uppercase, and then change it. And you need to do this on both sides. Adding COLLATE simply directs the processing to generate sort keys using a different set of rules than the default one. Using COLLATE definitely more efficient (or "productive" if you like the word :) than using UPPER() , as proven in this test script (in PasteBin) .
There is also a problem noted by @Ceisc in @Danny's answer:
In some languages, conversions are done the wrong way. i.e. LOWER (x)! = LOWER (UPPER (x)).
Turkish uppercase "İ" is a common example.
No, sorting is not an entire database setup, at least not in this context. There is a default mapping at the database level, and it is used as the default for modified and newly created columns that do not specify a COLLATE (which is probably due to this common misconception), but it does not directly affect queries. unless you are comparing string literals and variables with other string literals and variables, or referencing database level metadata.
No, matching is not on demand.
Mappings are made by predicate (that is, something operand) or expression, and not by request. And this is true for the whole query, and not just for WHERE . This includes CONNECTIONS, GROUP BY, ORDER BY, PARTITION BY, etc.
No, do not convert to VARBINARY (for example, convert(varbinary, myField) = convert(varbinary, 'sOmeVal') ) for the following reasons:
- this is a binary comparison that is not case sensitive (this is what this question asks)
- if you want binary comparison use binary matching. Use the one that ends with
_BIN2 if you are using SQL Server 2008 or later, otherwise you have no choice but to use the one that ends with _BIN . If the data is NVARCHAR then it does not matter which locale you use, since they are all the same in this case, therefore Latin1_General_100_BIN2 always works. If the data is VARCHAR , you must use the same locale in which the data is located (e.g. Latin1_General , French , Japanese_XJIS , etc.), because the locale defines the codepage used, and changing the code pages can change the data (i.e. data loss). - using a variable length data type without specifying a size will depend on the default size, and there are two different default values depending on the context in which the data type is used. This is either 1 or 30 for string types. When used with
CONVERT() it will use the default value of 30. The danger is that if the string length can exceed 30 bytes, it will be silently truncated, and you will probably get incorrect results from this predicate. - Even if you want case-sensitive comparisons, binary comparisons are not case-sensitive (another very common misconception).
No, LIKE not always case sensitive. It uses the collation of the referenced column, or the collation of the database if the variable is compared to a string literal, or the collation specified in the optional COLLATE .
LCASE not a SQL Server feature. It looks like it's either Oracle or MySQL. Or perhaps Visual Basic?
Since the context of the question compares a column with a string literal, neither instance matching (often called a "server") nor database matching has any direct effect here. Sorting options are stored for each column, and each column may have different sorting options, and these sorting options do not have to match the default database sorting options or instance sorting options. Of course, instance matching is the default for what the newly created database will use as the default matching if the COLLATE was not specified when creating the database. Similarly, the default collation for the database is what the modified or just created column will use if the COLLATE was not specified.
Case-insensitive matching should be used, which otherwise matches the column mapping. Use the following query to find the column sort options (change the table name and schema name):
SELECT col.* FROM sys.columns col WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName') AND col.[collation_name] IS NOT NULL;
Then just change _CS to _CI . Thus, Latin1_General_100_CS_AS will become Latin1_General_100_CI_AS .
If the column uses a binary mapping (ending in _BIN or _BIN2 ), find a similar mapping using the following query:
SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
For example, assuming the column uses Japanese_XJIS_100_BIN2 , do this:
SELECT * FROM sys.fn_helpcollations() col WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
For more information about collation, encoding, etc., please visit: Collations information
Solomon Rutzky Jan 29 '19 at 23:40 2019-01-29 23:40
source share