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;

Я действительно надеюсь, что это кому-то поможет. Я знаю, что вышеупомянутое было полезно, но мне все еще потребовалось несколько часов, чтобы превратить это в решение. Спасибо

Другие вопросы по тегам