Как я могу сделать сравнение строк с учетом регистра 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