我想使我的用户表的password
列在mysql中case sensitive
。
以下是该表的说明:
/*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 '='**
谁能帮忙这有什么问题? 作为简单查询工作的东西在存储的进程中执行时出错!?
如表达式排序规则中所述:
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
仅将排序规则添加到密码以强制排序规则与用户名匹配或仅添加到用户名不起作用。即使一个参数已经具有正确的排序规则,它仍然有一个错误。所以我在两个参数中添加了相同的排序规则,它奏效了。
请注意,这是我的数据库中已经使用的实际排序规则,但由于某种原因,在过程调用中它并不一致。
完成后,请记住对您的密码进行盐/哈希处理,我的代码仍在进行中。
我知道有点晚了,但如果这可以节省某人半天的咒骂时间,那么仍然值得放下它。
所以,我的设置是这样的:10.1.22-MariaDB,utf8mb4_general_ci
。 一切都很好,我恢复了数据库的转储,一切正常。
该数据库最初在utf8_general_ci
,但由于某些原因被恢复为utf8_unicode_ci
。将其更改回utf8_general_ci
并检查数据库中没有项目,例如列为utf8_unicode_ci
而不是utf8_general_ci
的列或表定义
尝试更新特定表会导致没有任何明显原因的非法排序规则混合。
它归结为实际上不是表本身,而是相关的触发器。
实际上,触发器调用了一个过程,该过程在我的数据库中没有排序规则信息,但在information_schema.ROUTINES.DATABASE_COLLATION
中具有utf8_unicode_ci
排序规则。
在新数据库排序规则的上下文中重新创建该过程解决了我的问题。
所以在与此错误作斗争之后:
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
这是如果您正在导入函数/过程/触发器,我的数据库拥有大量所有这些功能......我将其更改为:
字符集=utf8MB4 COLLATE=utf8mb4_general_ci;
我真的希望这对某人有所帮助。 我知道以上内容很有帮助,但我仍然花了几个小时才将其转化为解决方案。 谢谢