操作'='的排序规则(utf8mb4_unicode_ci,IMPLICIT)和(utf8mb4_general_ci,IMPLICIT)的错误混合
Posted
技术标签:
【中文标题】操作\'=\'的排序规则(utf8mb4_unicode_ci,IMPLICIT)和(utf8mb4_general_ci,IMPLICIT)的错误混合【英文标题】:Getting error Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='操作'='的排序规则(utf8mb4_unicode_ci,IMPLICIT)和(utf8mb4_general_ci,IMPLICIT)的错误混合 【发布时间】:2016-08-18 08:49:03 【问题描述】:尝试通过 mysql 中的存储过程进行选择时出现以下错误
用于操作“=”的排序规则 (utf8mb4_unicode_ci,IMPLICIT) 和 (utf8mb4_general_ci,IMPLICIT) 的非法混合。
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' or Variable_name LIKE 'collation%';
'character_set_client', 'utf8'
'character_set_connection', 'utf8'
'character_set_database', 'utf8mb4'
'character_set_filesystem', 'binary'
'character_set_results', 'utf8'
'character_set_server', 'utf8mb4'
'character_set_system', 'utf8'
'collation_connection', 'utf8_general_ci'
'collation_database', 'utf8mb4_unicode_ci'
'collation_server', 'utf8mb4_unicode_ci'
所有表都在utf8mb4_unicode_ci中,字符集为utf8mb4。
存储过程代码:
CREATE DEFINER=`dev_user`@`%` PROCEDURE `UPLOAD_ROSTER_FOR_DISTRICT`(IN JOBID INT, IN CHUNKID INT, IN DISTRICTID INT, IN DISTRICTYEARID INT)
BEGIN
DECLARE STUDENTSADDED INT DEFAULT 0;
DECLARE CLASSESADDED INT DEFAULT 0;
DECLARE TEACHERSADDED INT DEFAULT 0;
DECLARE STUDENTSEDITED INT DEFAULT 0;
DECLARE CLASSESSEDITED INT DEFAULT 0;
DECLARE TEACHERSEDITED INT DEFAULT 0;
SET @JOBID = JOBID;
SET @DISTRICTID = DISTRICTID;
SET @DISTRICTYEARID = DISTRICTYEARID;
SET @CHUNKID = CHUNKID;
DROP TEMPORARY TABLE IF EXISTS ROSTER_UPLOAD_SCHOOLS;
DROP TEMPORARY TABLE IF EXISTS ROSTER_UPLOAD_GRADES;
CREATE TEMPORARY TABLE ROSTER_UPLOAD_SCHOOLS (
SCHOOLID INT NOT NULL,
SCHOOLCODE VARCHAR(50) NOT NULL,
PRIMARY KEY (SCHOOLID)
);
CREATE TEMPORARY TABLE ROSTER_UPLOAD_GRADES (
GRADEID INT NOT NULL,
GRADENAME VARCHAR(50) NOT NULL,
PRIMARY KEY (GRADEID)
);
INSERT INTO ROSTER_UPLOAD_SCHOOLS (
SELECT DISTINCT SCH.SchoolId, SCH.SchoolCode FROM school SCH
WHERE SCH.DistrictId = @DISTRICTID AND SCH.IsDeleted = 0
);
INSERT INTO ROSTER_UPLOAD_GRADES (
SELECT DISTINCT GRD.GRADEID, GRD.GRADENAME FROM grade GRD
);
insert ignore into rosterstatistic (RosterId,ClassesAdded,ClassesModified,TeachersAdded,TeachersModified,StudentsAdded,StudentsModified,
TotalProcessedRows,TotalRows,CreatedUser,UpdatedUser) values (
@JOBID, 0,0,0,0,0,0,0,0,null,null
);
UPDATE CLASS CLS
INNER JOIN ROSTERUPLOAD_CLASS_DETAILS RCD ON CLS.CLASSCODE = RCD.CLASSCODE AND CLS.DISTRICTYEARID = @DISTRICTYEARID
INNER JOIN ROSTER_UPLOAD_SCHOOLS RUS ON CLS.SCHOOLID = RUS.SCHOOLID AND RCD.SCHOOLCODE = RUS.SCHOOLCODE
INNER JOIN rosterupload RU ON RU.ROSTERID = RCD.ROSTERID AND RU.ROSTERID = @JOBID AND RU.DISTRICTID = @DISTRICTID
SET CLS.ClassName = RCD.classname, CLS.ISDELETED = 0, CLS.UpdatedUser = RU.CreatedUser
WHERE RCD.CHUNKID = @CHUNKID;
SET CLASSESSEDITED = ROW_COUNT();
INSERT IGNORE INTO CLASS (SchoolId, DistrictYearId, ClassCode, ClassName, IsDeleted, CreatedUser) (
SELECT distinct RUS.SCHOOLID, @DISTRICTYEARID, RCD.ClassCode, RCD.CLASSNAME, 0, RU.CreatedUser
FROM ROSTERUPLOAD_CLASS_DETAILS RCD, ROSTER_UPLOAD_SCHOOLS RUS, rosterupload RU
WHERE (RCD.RosterId = @JOBID AND RCD.SchoolCode = RUS.SCHOOLCODE AND RCD.RosterId = RU.RosterId AND RCD.CHUNKID = @CHUNKID)
);
SET CLASSESADDED = ROW_COUNT();
UPDATE STUDENT STUD
INNER JOIN rosterupload_student_details RSD ON RSD.STUDENTCODE = STUD.STUDENTCODE AND STUD.DISTRICTID = @DISTRICTID
INNER JOIN rosterupload RU ON RU.ROSTERID = RSD.ROSTERID AND RU.ROSTERID = @JOBID
SET STUD.FirstName = RSD.FirstName , STUD.MiddleName = RSD.MiddleName, STUD.LastName = RSD.LastName, STUD.Gender = RSD.Gender,
STUD.HomeRoom = RSD.HomeRoom, STUD.BirthDate = RSD.BirthDate, STUD.IEPStatus = RSD.IEPStatus, STUD.LEPStatus = RSD.LEPStatus,
STUD.LEPYear = RSD.LEPYear, STUD.Race = RSD.Race, STUD.Language = RSD.Language, STUD.Accommodation = RSD.Accomodation, STUD.ReservedField = RSD.Reserved,
STUD.IsDeleted = 0, STUD.UpdatedUser = RU.CreatedUser
WHERE RSD.STUDENTCODE = STUD.STUDENTCODE AND STUD.DISTRICTID = RU.DISTRICTID AND RU.DISTRICTID = @DISTRICTID
AND RSD.CHUNKID = @CHUNKID
AND RSD.STUDENTCODE NOT IN (SELECT RSD2.STUDENTCODE FROM rosterupload_student_details RSD2
WHERE RSD2.ROSTERID = @JOBID AND RSD2.CHUNKID < @CHUNKID);
SET STUDENTSEDITED = ROW_COUNT();
INSERT IGNORE INTO STUDENT ( DistrictId, StudentCode, FirstName, MiddleName, LastName, Gender, HomeRoom,
BirthDate, IEPStatus, LEPStatus, LEPYear, Race, Language, Accommodation, ReservedField,
MD5Hash, IsDeleted, CreatedUser) (
SELECT distinct @DISTRICTID, STUDENTCODE, FirstName, MiddleName, LastName, Gender, HomeRoom,
BirthDate, IEPStatus, LEPStatus, LEPYear, Race, Language, Accomodation, Reserved, '', 0, RU.CreatedUser
FROM rosterupload_student_details RSD, rosterupload RU
WHERE RSD.RosterId = RU.RosterId AND RU.RosterId = @JOBID AND RSD.CHUNKID = @CHUNKID
);
SET STUDENTSADDED = ROW_COUNT();
INSERT INTO student_class_grade (StudentId, ClassId, DistrictYearId, GradeId, IsDeleted, CreatedUser) (
SELECT distinct STUD.StudentId, CLS.ClassId, @DISTRICTYEARID, RUG.GRADEID, 0, RU.CreatedUser
FROM rosterupload RU, rosterupload_student_details RSD, ROSTER_UPLOAD_SCHOOLS RUS, ROSTER_UPLOAD_GRADES RUG, STUDENT STUD, CLASS CLS
WHERE RU.ROSTERID = RSD.ROSTERID AND RSD.SCHOOLCODE = RUS.SCHOOLCODE AND RSD.GRADE = RUG.GRADENAME AND RSD.StudentCode = STUD.StudentCode
AND STUD.DistrictId = @DISTRICTID AND CLS.ClassCode = RSD.Classcode AND CLS.SchoolId = RUS.SCHOOLID AND CLS.DistrictYearId = @DISTRICTYEARID
AND RU.RosterId = @JOBID
)
ON DUPLICATE KEY UPDATE GradeId = RUG.GRADEID, IsDeleted = 0, UpdatedUser = RU.CreatedUser;
UPDATE `USER` USR
INNER JOIN rosterupload_teacher_details RTD ON RTD.EMPLOYEECODE = USR.TEACHEREMPLOYEECODE
SET USR.TITLE = RTD.TITLE, USR.FIRSTNAME = RTD.FIRSTNAME, USR.LASTNAME = RTD.LASTNAME, USR.MIDDLENAME = RTD.MIDDLENAME
WHERE RTD.ROSTERID = @JOBID AND USR.DISTRICTID = @DISTRICTID AND USR.ROLEID = 5 AND RTD.CHUNKID = @CHUNKID;
SET TEACHERSEDITED = ROW_COUNT();
INSERT INTO `USER` (TeacherEmployeeCode, DistrictId, RoleId, FirstName, MiddleName, LastName, EmailAddress, Title, CreatedUser, `uuid`, ActivationEmailPending ) (
SELECT distinct RTD.EmployeeCode, @DISTRICTID, 5, RTD.FirstName, RTD.MiddleName, RTD.LastName, RTD.EmailAddress, RTD.Title, RU.CreatedUser, RTD.`uuid`, true
FROM rosterupload_teacher_details RTD
join ROSTER_UPLOAD_SCHOOLS RUS on RUS.SCHOOLCODE = RTD.schoolCode
join rosterupload RU on ru.rosterid = RTD.rosterid
WHERE NOT EXISTS (SELECT * FROM `USER` US
WHERE US.TeacherEmployeeCode = RTD.EmployeeCode AND US.DistrictId = @DISTRICTID AND US.ROLEID = 5)
AND RU.ROSTERID = @JOBID AND RU.DistrictId = @DISTRICTID AND RTD.CHUNKID = @CHUNKID
);
SET TEACHERSADDED = ROW_COUNT();
UPDATE rosterstatistic STAT
SET STAT.ClassesAdded = STAT.ClassesAdded + CLASSESADDED,
STAT.ClassesModified = STAT.ClassesModified + CLASSESSEDITED,
STAT.TeachersAdded = STAT.TeachersAdded + TEACHERSADDED,
STAT.TeachersModified = STAT.TeachersModified + TEACHERSEDITED,
STAT.StudentsAdded = STAT.StudentsAdded + STUDENTSADDED,
STAT.StudentsModified = STAT.StudentsModified + STUDENTSEDITED
WHERE STAT.rosterid = @JOBID;
INSERT INTO teacher_school (UserId, SchoolId, DistrictYearId, StaffCode, IsDeleted, CreatedUser, UpdatedUser) (
SELECT distinct USR.USERID, RUS.SCHOOLID, @DISTRICTYEARID, RTD.StaffCode, 0, RU.CreatedUser, RU.CreatedUser
FROM rosterupload_teacher_details RTD
JOIN ROSTER_UPLOAD_SCHOOLS RUS ON RUS.SCHOOLCODE = RTD.SCHOOLCODE
JOIN rosterupload RU ON RU.ROSTERID = RTD.ROSTERID
JOIN `USER` USR ON USR.TeacherEmployeeCode = RTD.EmployeeCode
WHERE RU.ROSTERID = @JOBID
AND USR.DistrictId = @DISTRICTID
AND USR.RoleId = 5
AND RTD.CHUNKID = @CHUNKID
) ON DUPLICATE KEY UPDATE STAFFCODE = RTD.StaffCode, IsDeleted = 0, UpdatedUser = RU.CreatedUser;
INSERT INTO teacher_school_class (TeacherSchoolId,ClassId,IsDeleted,CreatedUser,UpdatedUser) (
SELECT distinct TS.TeacherSchoolId, CLS.ClassId, 0, RU.CreatedUser, RU.CreatedUser
FROM rosterupload_teacher_details RTD, ROSTER_UPLOAD_SCHOOLS RUS, `USER` USR, class CLS, teacher_school TS, rosterupload RU
WHERE RTD.ClassCode = CLS.ClassCode AND RTD.SchoolCode = RUS.SCHOOLCODE AND CLS.DistrictYearId = @DISTRICTYEARID
AND TS.UserId = USR.UserId AND TS.DistrictYearId = CLS.DistrictYearId AND TS.SchoolId = RUS.SchoolId
AND RTD.EmployeeCode = USR.TeacherEmployeeCode AND USR.RoleId = 5 AND USR.DistrictId = @DISTRICTID
AND RTD.RosterId = RU.RosterId AND RU.RosterId = @JOBID
) ON DUPLICATE KEY UPDATE IsDeleted = 0, UpdatedUser = RU.CreatedUser;
END
【问题讨论】:
【参考方案1】:我看到您也在使用临时表。请也为临时表定义相同的排序规则和字符集。在 SELECT 查询本身中使用列级排序规则(也可以在您放置连接的地方)
select * from some_table
where some_column collate
utf8_general_ci = 'Name of the City';
这应该适合你。
【讨论】:
用户整理什么 utf8bm4_general_ci ??当在连接中使用 where 子句时,我应该这样做吗? 我应该使用 utf8bm4_unicode_ci 还是 utf8bm4_general_ci 取决于您的用例。 utf8bm4_unicode_ci 应该覆盖它。它支持表情符号。 我很困惑是在两个操作数上还是在单个操作数上进行排序,例如在两个操作数上使用 -- RSD.STUDENTCODE collate utf8mb4_unicode_ci = STUD.STUDENTCODE collate utf8mb4_unicode_ci 是的,它解决了我的问题,非常感谢@MontyPython【参考方案2】:尽量使数据库和表具有相同的结构。
在我的例子中,我等于两个具有相同结构 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
的 db,但其中一个具有 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
的表,另一个具有 CHARSET=utf8mb4
的表。
如果您无法更改结构,请尝试使用
some_column1 collate utf8_general_ci = some_column2
【讨论】:
以上是关于操作'='的排序规则(utf8mb4_unicode_ci,IMPLICIT)和(utf8mb4_general_ci,IMPLICIT)的错误混合的主要内容,如果未能解决你的问题,请参考以下文章
utf8mb4_unicode_ci 在 PhpMyAdmin 中选择,但 WordPress 表使用 utf8mb4_unicode_520_ci 排序规则
排序规则将 utf8mb4_unicode_ci 更改为 utf8mb4_general_ci
MySql Unicode 排序规则 utf8mb4_german2_ci 未找到 *** 德语变音符号排序规则 ***
MySQL 数据库 - 将字符集和排序规则转换为 utf8mb4 和 utf8mb4_unicode_ci?