How can I make SQL case sensitive string comparison on MySQL?

前端 未结 11 2184
温柔的废话
温柔的废话 2020-11-22 02:45

I have a function that returns five characters with mixed case. If I do a query on this string it will return the value regardless of case.

How can I make MySQL stri

相关标签:
11条回答
  • 2020-11-22 03:16

    No need to changes anything on DB level, just you have to changes in SQL Query it will work.

    Example -

    "SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";

    Binary keyword will make case sensitive.

    0 讨论(0)
  • 2020-11-22 03:19

    The good news is that if you need to make a case-sensitive query, it is very easy to do:

    SELECT *  FROM `table` WHERE BINARY `column` = 'value'
    
    0 讨论(0)
  • 2020-11-22 03:19

    The most correct way to perform a case sensitive string comparison without changing the collation of the column being queried is to explicitly specify a character set and collation for the value that the column is being compared to.

    select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;
    

    Why not use binary?

    Using the binary operator is inadvisable because it compares the actual bytes of the encoded strings. If you compare the actual bytes of two strings encoded using the different character sets two strings that should be considered the same they may not be equal. For example if you have a column that uses the latin1 character set, and your server/session character set is utf8mb4, then when you compare the column with a string containing an accent such as 'café' it will not match rows containing that same string! This is because in latin1 é is encoded as the byte 0xE9 but in utf8 it is two bytes: 0xC3A9.

    Why use convert as well as collate?

    Collations must match the character set. So if your server or session is set to use the latin1 character set you must use collate latin1_bin but if your character set is utf8mb4 you must use collate utf8mb4_bin. Therefore the most robust solution is to always convert the value into the most flexible character set, and use the binary collation for that character set.

    Why apply the convert and collate to the value and not the column?

    When you apply any transforming function to a column before making a comparison it prevents the query engine from using an index if one exists for the column, which could dramatically slow down your query. Therefore it is always better to transform the value instead where possible. When a comparison is performed between two string values and one of them has an explicitly specified collation, the query engine will use the explicit collation, regardless of which value it is applied to.

    Accent Sensitivity

    It is important to note that MySql is not only case insensitive for columns using an _ci collation (which is typically the default), but also accent insensitive. This means that 'é' = 'e'. Using a binary collation (or the binary operator) will make string comparisons accent sensitive as well as case sensitive.

    What is utf8mb4?

    The utf8 character set in MySql is an alias for utf8mb3 which has been deprecated in recent versions because it does not support 4 byte characters (which is important for encoding strings like

    0 讨论(0)
  • 2020-11-22 03:19

    Following is for MySQL versions equal to or higher than 5.5.

    Add to /etc/mysql/my.cnf

      [mysqld]
      ...
      character-set-server=utf8
      collation-server=utf8_bin
      ...
    

    All other collations I tried seemed to be case-insensitive, only "utf8_bin" worked.

    Do not forget to restart mysql after this:

       sudo service mysql restart
    

    According to http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html there is also a "latin1_bin".

    The "utf8_general_cs" was not accepted by mysql startup. (I read "_cs" as "case-sensitive" - ???).

    0 讨论(0)
  • 2020-11-22 03:21

    Instead of using the = operator, you may want to use LIKE or LIKE BINARY

    // this returns 1 (true)
    select 'A' like 'a'
    
    // this returns 0 (false)
    select 'A' like binary 'a'
    
    
    select * from user where username like binary 'a'
    

    It will take 'a' and not 'A' in its condition

    0 讨论(0)
提交回复
热议问题