3

我想让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

4 回答 4

7

表达式整理中所述

MySQL 分配强制值如下:

[ deletia ]

  • 列或存储的例程参数或局部变量的排序规则具有 2 的强制力。

[ deletia ]

MySQL 使用具有以下规则的强制值来解决歧义:

[ deletia ]

  • 如果双方具有相同的强制力,则:

    • 如果两边都是 Unicode,或者两边都不是 Unicode,那就是错误。

可以在表达式中添加显式COLLATE子句以强制其中一个操作数具有具有较低强制力值的显式排序规则:

USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs'

在这种情况下,您甚至可能要考虑latin1_bin

无论如何,您都不应该以纯文本形式存储密码。相反,存储用户密码的加盐哈希并简单地验证哈希是否与存储的哈希匹配。

于 2012-11-08T09:01:28.980 回答
2

我在遇到同样的错误后来到这里。经过提供的解决方案后,很明显 COLLATION 是我的错误的触发器。我的代码与原始问题类似,但我的错误是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,但由于某种原因,在过程调用中它并不一致。

请记住在完成后对您的密码进行加盐/哈希处理,我的代码仍在进行中。

于 2021-03-27T08:56:32.187 回答
1

我知道这有点晚了,但是如果这可以节省某人半天的时间,那么它仍然值得放下。

所以,我的设置是这样的:10.1.22-MariaDB, utf8mb4_general_ci. 一切都好,我恢复了我的数据库转储,一切正常。

该数据库原本是在utf8_general_ci,但由于某些原因被恢复为utf8_unicode_ci. 将其更改回utf8_general_ci并检查数据库中没有工件,例如列或表定义整理为utf8_unicode_ci而不是utf8_general_ci

尝试更新特定表会导致非法的排序规则混合,而没有任何明显的原因。

归结为实际上不是表本身,而是关联的触发器。

事实上,触发器调用了一个过程,该过程在我的数据库中没有排序规则信息,但utf8_unicode_ciinformation_schema.ROUTINES.DATABASE_COLLATION.

在新数据库排序规则的上下文中重新创建过程解决了我的问题。

于 2017-07-19T13:40:02.327 回答
1

所以在努力解决这个错误之后:

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 整理=utf8mb4_general_ci;

我真的希望这对某人有所帮助。我知道以上内容很有帮助,但我仍然花了几个小时才将其转化为解决方案。谢谢

于 2017-11-28T01:33:56.557 回答