mysql: код ошибки [1267]; Недопустимое сочетание параметров сортировки (latin1_general_cs,IMPLICIT) и (latin1_swedish_ci,IMPLICIT) для операции '='
Я хочу сделать password
столбец моей таблицы пользователя будет case sensitive
в mysql.
Ниже приводится описание таблицы:
/*Table: mst_user*/
FIELD TYPE COLLATION
------------- ------------ -----------------
user_id VARCHAR(100) latin1_swedish_ci
first_name VARCHAR(25) latin1_swedish_ci
last_name VARCHAR(25) latin1_swedish_ci
USER_PASSWORD VARCHAR(50) latin1_swedish_ci
user_status INT(11) (NULL)
version_id INT(11) (NULL)
active_status INT(11) (NULL)
user_type INT(11) (NULL)
Чтобы сделать USER_PASSWORD
чувствительно к регистру я выполнил следующий запрос:
ALTER TABLE `mst_user` MODIFY `USER_PASSWORD` VARCHAR(50) COLLATE `latin1_general_cs`;
Это сработало, и поле теперь чувствительно к регистру.
Но у меня есть процедура магазина, которая выполняет SELECT
запрос к этой таблице, чтобы проверить, существует ли пользователь для данных учетных данных.
Сохраненный процесс::
CREATE PROCEDURE `usp_password_verify`(ip_login_id VARCHAR(200),
ip_user_password VARCHAR(200),
INOUT success INT(1),
INOUT tbl_usr_password VARCHAR(100),
INOUT pkg_user_password VARCHAR(100))
BEGIN
SELECT COUNT(*)
INTO success
FROM mst_user
WHERE UPPER (user_id) = UPPER (ip_login_id)
AND USER_PASSWORD=ip_user_password;
SET tbl_usr_password = '';
SET pkg_user_password= '';
END$$
Когда я вызываю этот хранимый процесс из моего кода Java, я получаю следующую ошибку:
**error code [1267]; Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='**
Может кто-нибудь помочь, что не так с этим? Что-то, что работает как простой запрос, выдает ошибку при выполнении его в хранимой процедуре!?
4 ответа
Как задокументировано в разделе Сборка выражений:
MySQL назначает значения принудительности следующим образом:
[ deletia ]
- Параметры сортировки столбца, хранимого стандартного параметра или локальной переменной имеют значение 2.
[ deletia ]
MySQL использует значения принудительной совместимости со следующими правилами для устранения неоднозначностей:
[ deletia ]
Если обе стороны имеют одинаковое принуждение, то:
- Если обе стороны Unicode или обе стороны не Unicode, это ошибка.
Вы можете добавить явное COLLATE
предложение в вашем выражении, чтобы заставить один из операндов иметь явное сопоставление с более низким значением принудительности:
USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs'
Вы могли бы даже хотеть рассмотреть latin1_bin
в этом случае?
В любом случае, вы не должны хранить пароли в открытом виде. Вместо этого храните соленые хэши паролей ваших пользователей и просто проверяйте, совпадает ли хеш с тем, который хранится.
Я пришел сюда после того, как столкнулся с той же ошибкой. После рассмотрения предложенных решений стало очевидно, что СБОРКА была причиной моей ошибки. Мой код был похож на исходный вопрос, но моя ошибка была
MySQL said: #1267 - Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='
.
Я тоже пытался собрать пароль и имя пользователя (в настоящее время нет хеширования), и я исправил это, явно добавив COLLATION для обоих параметров.
Первый код (ошибочный код):
WHERE user.username = username
AND user.password = password
Мой текущий код (рабочий код):
WHERE user.username = username COLLATE utf8mb4_0900_ai_ci
AND user.password = password COLLATE utf8mb4_0900_ai_ci
Добавление сопоставления только к паролю для принудительного сопоставления сопоставления с именем пользователя или добавление только к имени пользователя не сработало. Несмотря на то, что для одного параметра уже было правильное сопоставление, по-прежнему была ошибка. Поэтому я добавил одинаковые параметры сортировки к обоим параметрам, и это сработало.
Обратите внимание, что это фактическая COLLATION, которая уже используется в моей базе данных, но по какой-то причине при вызовах процедур она не согласовывалась.
Пожалуйста, не забудьте солить / хешировать свои пароли, когда вы закончите, мой код все еще находится в стадии разработки.
Я знаю, что уже немного поздно, но если это может сэкономить кому-то полдня клятвы, все равно стоит от него отказаться.
Итак, моя установка была такой: 10.1.22-MariaDB, utf8mb4_general_ci
, Все хорошо, я восстановил дамп своей базы данных, все прошло нормально.
База данных изначально была в utf8_general_ci
, но по ряду причин был восстановлен как utf8_unicode_ci
, Изменил это обратно utf8_general_ci
и проверил, что в базе данных нет артефактов, таких как столбцы или определения таблиц, сопоставленные как utf8_unicode_ci
вместо utf8_general_ci
Попытка обновить конкретную таблицу привела к недопустимому сочетанию параметров сортировки без видимых причин.
Это сводилось к тому, чтобы быть фактически не самой таблицей, а связанным триггером.
На самом деле триггер вызвал процедуру, которая не имела информации о сопоставлении в моей базе данных, но имела utf8_unicode_ci
сопоставление в information_schema.ROUTINES.DATABASE_COLLATION
,
Воссоздание процедуры в контексте новой базы данных сопоставления решило мою проблему.
Итак, после борьбы с этой ошибкой:
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE) and (utf8mb4_general_ci,COERCIBLE) for operation '='
Мне удалось решить эту проблему, изменив файл базы данных импорта с:
CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci NO SQL
Это если вы импортируете функции / процедуры / триггеры, у которых в моей базе данных было множество этих функций... Я изменил это на:
CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
Я действительно надеюсь, что это кому-то поможет. Я знаю, что вышеупомянутое было полезно, но мне все еще потребовалось несколько часов, чтобы превратить это в решение. Спасибо