操作'案例'的非法混合排序(utf8_general_ci,COERCIBLE)和(latin1_swedish_ci,IMPLICIT)

时间:2015-03-30 13:35:13

标签: mysql character-encoding collation

我在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'

我无法理解为什么它会抛出错误,并且Charset,Collat​​ion在两个服务器中都是相同的。任何人都可以帮我解决这个问题。

感谢您的建议。

1 个答案:

答案 0 :(得分:1)

可能您在两台服务器上使用了不同的默认排序规则。我们从两个方向调试它。

  • 运行查询时,请从同一连接执行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设置为字符串12等,然后与数字“3”进行比较,最后按PermissionName排序,这似乎是字符串。我不知道这是否是造成麻烦的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;