我想在mysql中将我的User表的password
列设为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 '='**
任何人都可以帮助解决这个问题吗? 作为简单查询工作的东西在存储过程中执行时会出错!?
答案 0 :(得分:7)
MySQL按如下方式分配强制性值:
[ deletia ]
- 列或存储的例程参数或局部变量的排序规则具有2的强制性。
[ deletia ]
MySQL使用具有以下规则的强制性值来解决歧义:
[ deletia ]
如果双方具有相同的强制性,那么:
- 如果双方都是Unicode,或双方都不是Unicode,那就是错误。
你可以在你的表达式中添加一个显式的COLLATE
子句,以强制其中一个操作数具有一个具有较低强制性值的显式排序规则:
USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs'
在这种情况下,你甚至可能想考虑latin1_bin
?
无论如何,不应该以明文存储密码。而是存储用户密码的 salted 哈希值,并简单地验证哈希值与存储的哈希值匹配。
答案 1 :(得分:1)
我在遇到同样的错误后来到这里。在通过提供的解决方案之后,很明显 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,但由于某些原因,它在过程调用中不一致。
请记住在完成后对密码进行加盐/散列,我的代码仍在进行中。
答案 2 :(得分:0)
我知道它有点迟了但是如果这可以挽救有人半天的咒骂,那还是值得把它放下来。
所以,我的设置是这样的: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
排序规则。
在新数据库排序规则的上下文中重新创建过程解决了我的问题。