【问题标题】:Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'case'用于操作“案例”的排序规则(utf8_general_ci,COERCIBLE)和(latin1_swedish_ci,IMPLICIT)的非法混合
【发布时间】:2015-06-03 13:17:13
【问题描述】:

我在 MySQL SERVER 5.5 和 MySQL SERVER 5.0 版本中使用了两台 MySQL 服务器。我尝试在两台服务器中执行查询。这是我的查询:

DELIMITER $$

DROP PROCEDURE IF EXISTS `get_user_permissionlist`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `get_user_permissionlist`(
 pUserId INT,
 pApplicationId INT
)
BEGIN
DECLARE vDefaultManagerPermission VARCHAR(20);
SET vDefaultManagerPermission = (SELECT PermissionName FROM permission_level WHERE userid = pUserId);
IF vDefaultManagerPermission = 'Administrator'
THEN
    SELECT  PermissionId
           ,PermissionName
    FROM    ( SELECT    pl.PermissionId
               ,pl.PermissionName
               ,CASE permissionname
                  WHEN 'administrator' THEN '1'
                  WHEN 'operator' THEN '2'
                  WHEN 'power user' THEN '3'
                  ELSE '4'
                END AS rank
          FROM      permission_level pl
          WHERE     pl.ApplicationId = pApplicationId
        ) d
    ORDER BY CASE WHEN rank <= 3 THEN rank
              ELSE PermissionName
         END;
END IF;

END $$

DELIMITER ;

我尝试使用以下查询执行 PROCEDURE。

CALL st_proc_get_user_permissionlist('5', '1')

当我在 MySQL SERVER 5.0 中执行查询时,没有问题。但是我在 MySQL SERVER 5.5 中尝试了同样的方法,它显示错误:

Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'case'

我不明白为什么它会抛出错误,并且两个服务器中的字符集、排序规则都是相同的。

【问题讨论】:

    标签: mysql character-encoding collation


    【解决方案1】:

    您可能从两台服务器上的不同 default 排序规则开始。让我们从两个方向调试它。

    • 运行查询时,从同一连接执行SHOW VARIABLES LIKE 'char%';。这可能会检查查询中文字的“字符集”。
    • SHOW CREATE TABLE 每个服务器上的每个表。这应该确定字段的字符集,例如PermissionName。

    查看bug 41627 是否适用,尽管它在 5.1.34 中已“修复”。

    不涉及VIEW,对吗?

    这真的很奇怪:

    ORDER BY 
            CASE WHEN rank <= 3 THEN rank
                  ELSE PermissionName
             END;
    

    rank设置为字符串1、2等,然后对比数字“3”,最后用PermissionName排序,貌似是字符串。我不知道这是否是造成麻烦的CASE,但我建议(为了我的理智)不要混合数字和字符串。

    你可以摆脱其他CASE:

    WHERE PermissionName = CASE WHEN ApplicationId = 4
               THEN 'administrator'
               ELSE PermissionName END
    

    重写为

    WHERE ( PermissionName = 'administrator' OR ApplicationId != 4 ) 
    

    编辑

    因为奇怪的值组合,请尝试

    ORDER BY CASE WHEN 0+rank <= 3 THEN CONCAT(_utf8 '', rank)
              ELSE CONVERT(PermissionName USING utf8)
         END;
    

    【讨论】:

    • 感谢您的回复@Rick James。现在我编辑我的问题并给出整个过程。你能给我解决办法吗?
    • 我已经尝试了 SHOW VARIABLES LIKE 'char%';。两个服务器版本中的所有字符集都是相同的。
    • 添加了其他东西来尝试。
    • 在我的答案中查看对 ORDER BY 的更改(编辑)。
    猜你喜欢
    • 2010-10-30
    • 2010-09-16
    • 2015-09-16
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多