Как я могу сделать сравнение строк с учетом регистра SQL на MySQL?

У меня есть функция, которая возвращает пять символов с смешанный случай. Если я сделаю запрос по этой строке, он вернет значение независимо от случая.

Как я могу сделать строковые запросы MySQL чувствительными к регистру?

10 ответов


http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

набор символов и параметры сортировки по умолчанию-latin1 и latin1_swedish_ci, поэтому по умолчанию сравнения строк без учета регистра. Это означает, что при поиске с col_name, например " a%", вы получаете все значения столбцов, начинающиеся с A или a. Чтобы сделать этот поиск чувствительным к регистру, убедитесь, что один из операндов имеет регистр или двоичные параметры сортировки. Например, если вы сравнивая столбец и строку, которые имеют набор символов latin1, вы можете использовать оператор COLLATE, чтобы заставить операнд иметь параметры сортировки latin1_general_cs или latin1_bin:

col_name COLLATE latin1_general_cs LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_general_cs
col_name COLLATE latin1_bin LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_bin

Если вы хотите, чтобы столбец всегда обрабатывался с учетом регистра, объявите его с учетом регистра или двоичной сортировки.


хорошая новость заключается в том, что если вам нужно сделать запрос с учетом регистра, это очень легко сделать:

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

вместо использования оператора = вы можете использовать Like или 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'

он будет принимать "a", а не " A " в его состоянии


ответ опубликовал Крейг Уайт, имеет большой штраф за производительность

SELECT *  FROM `table` WHERE BINARY `column` = 'value'

потому что он не использует индексы. Итак, либо вам нужно изменить параметры сортировки таблицы, как здесьhttps://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html.

или

простое исправление, вы должны использовать двоичный файл значения.

SELECT *  FROM `table` WHERE `column` = BINARY 'value'

например.

mysql> EXPLAIN SELECT * FROM temp1 WHERE BINARY col1 = "ABC" AND col2 = "DEF" ;
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | temp1  | ALL  | NULL          | NULL | NULL    | NULL | 190543 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+

VS

mysql> EXPLAIN SELECT * FROM temp1 WHERE col1 = BINARY "ABC" AND col2 = "DEF" ;
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows | Extra                              |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
|  1 | SIMPLE      | temp1 | range | col1_2e9e898e | col1_2e9e898e | 93      | NULL |    2 | Using index condition; Using where |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
enter code here

1 строка в наборе (0.00 сек)


чтобы использовать индекс перед использованием двоичного файла, вы можете сделать что-то вроде этого, если у вас есть большие таблицы.

SELECT
   *
FROM
   (SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
   BINARY `column` = 'value'

подзапрос приведет к действительно небольшому подмножеству без учета регистра, из которого вы затем выберете единственное совпадение с учетом регистра.


ниже Для версий MySQL, равных или выше 5.5.

добавить в /etc/mysql / my.cnf

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

все другие сортировки, которые я пробовал, казались нечувствительными к регистру, работал только "utf8_bin".

Не забудьте перезапустить MySQL после этого:

   sudo service mysql restart

согласно http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html существует также "latin1_bin".

" utf8_general_cs " не был принят mysql запуск. (Я читал "_cs" как "регистр" - ???).


вы можете использовать двоичный файл с учетом регистра, как это

select * from tb_app where BINARY android_package='com.Mtime';

к сожалению, этот sql не может использовать индекс, вы будете страдать от снижения производительности запросов, зависящих от этого индекса

mysql> explain select * from tb_app where BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
|  1 | SIMPLE      | tb_app | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1590351 |   100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+

к счастью, у меня есть несколько трюков, чтобы решить эту проблему

mysql> explain select * from tb_app where android_package='com.Mtime' and BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table  | partitions | type | possible_keys             | key                       | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tb_app | NULL       | ref  | idx_android_pkg           | idx_android_pkg           | 771     | const |    1 |   100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+  

отлично!

я делюсь с вами кодом из функции, которая сравнивает пароли:

SET pSignal =
(SELECT DECODE(r.usignal,'YOURSTRINGKEY') FROM rsw_uds r WHERE r.uname =
in_usdname AND r.uvige = 1);

SET pSuccess =(SELECT in_usdsignal LIKE BINARY pSignal);

IF pSuccess = 1 THEN
      /*Your code if match*/
ELSE
      /*Your code if don't match*/

END IF;

Не нужно ничего менять на уровне БД, просто вам нужно изменить SQL-запрос, он будет работать.

пример

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

ключевое слово Binary сделает регистр чувствительным.


mysql не чувствителен к регистру по умолчанию, попробуйте изменить языковые параметры сортировки на latin1_general_cs