【问题标题】:mysql: error code [1267]; Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='mysql:错误代码[1267];非法混合排序规则 (latin1_general_cs,IMPLICIT) 和 (latin1_swedish_ci,IMPLICIT) 用于操作 '='
【发布时间】:2012-11-08 08:29:50
【问题描述】:

我想让我的用户表的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 '='**

任何人都可以帮助解决这个问题吗? 在存储过程中执行时,作为简单查询的东西会出错!?

【问题讨论】:

  • 哇哦... 不要存储明文密码!而是存储一个 salted 散列,以便在您的数据库遭到破坏时,任何人都很难发现您用户的密码。请参阅The definitive guide to forms based website authentication 了解更多信息。
  • 嗯,这将是我的下一步...首先我想解决这个问题..我想进行区分大小写检查并摆脱上述错误。

标签: mysql sql mysql-error-1267


【解决方案1】:

Collation of Expressions 中所述:

MySQL 分配强制值如下:

[ deletia ]

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

[ deletia ]

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

[ deletia ]

  • 如果双方的强制力相同,那么:

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

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

USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs'

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

无论如何,您不应以明文形式存储密码。相反,存储用户密码的 salted 哈希值,并简单地验证哈希值是否与存储的哈希值匹配。

【讨论】:

  • USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs' 为此工作。下一步将加密密码。谢谢大家
【解决方案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,但由于某种原因,在过程调用中它并不一致。

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

【讨论】:

  • 我有一个疑问,我正在尝试使用选择子查询进行更新,并添加了类似的内容 - CASE 标志 WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS flagVal 将其与主查询进行比较具有此 flagVal 值的表的列(varchar),虽然它在我的本地数据库中工作,但在不同的设置中得到了您提到的确切错误,这是我怀疑的导致问题的原因吗? - 因为当我根据您的回答更新 where 子句时错误消失了,如果这是原因,有没有办法让 CASE -then 表达式在设置真/假值时设置正确的字符集?
  • 我对实时 SQL 和复杂查询还比较陌生,我使用 MS Access SQL 已经有一段时间了,从来没有遇到过这个错误。但是到目前为止,如果不时不明确地设置排序规则,它似乎会变得很不稳定,一些查询运行良好,一些查询会出现错误。我的理解是它根据给定的输入自动派生,而不是检查数据库条目并匹配它。我发现处理这个问题的方法是根据我对输入的回答设置排序规则,因此它们与 db 排序规则相匹配。如果它有效,我会说实验,看看是什么破坏了它然后回滚。
【解决方案3】:

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

所以,我的设置是这样的: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 排序规则。

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

【讨论】:

    【解决方案4】:

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

    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;

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

    【讨论】:

      猜你喜欢
      • 2021-04-13
      • 2015-09-16
      • 2016-02-19
      • 1970-01-01
      • 2023-03-21
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多