SQLERROR:1267

菜雞03號發表於2016-09-28
最近在使用MySQL5.x時,用到了兩個表的組合查詢,類似下面簡單的語句: 
Java程式碼  收藏程式碼
  1. select pa.userId as userId,pa.userName as userName,pb.orgId as orgId,pb.orgName as orgName from tbl_user pa,tbl_org pb where pa.userId = pb.userId  

結果卻出現了下面的錯誤: 
Java程式碼  收藏程式碼
  1. SQL Error: 1267, SQLState: HY000  
  2. [@APPNAME@] ERROR [http-8080-2] JDBCExceptionReporter.error(104) | Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='  
  3. org.hibernate.exception.GenericJDBCException: could not execute query using iterate at org.hibernate.exception.SQLStateConverter.handledNonSpecificException  
  4. (SQLStateConverter.java:103)  
  5.     at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)  
  6.     at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)  
  7.     at org.hibernate.loader.hql.QueryLoader.iterate(QueryLoader.java:427)  
  8.     at org.hibernate.hql.ast.QueryTranslatorImpl.iterate(QueryTranslatorImpl.java:380)  
  9. ... ...  

這個問題僅僅在自己家裡的機器上的MySQL本地資料庫中出現,在公司的伺服器資料庫上則不會出現。因為之前一直在用oracle資料庫,MySQL相對接觸較少,連續幾天這個問題都沒有解決,只是覺得這個問題太過莫名其妙了,百思不得其解。 
大概到了第3天吧,突然明白了錯誤提示的意思,這意思是在說utf8_general_ci和utf8_unicode_ci由於隱含的字符集不同,不能用'='進行判斷。 
立即用客戶端軟體SQLyog連線到資料庫,檢查建立資料庫表的語句,果然發現下面的小小區別 
Java程式碼  收藏程式碼
  1. CREATE TABLE `tbl_user` (  
  2.   `userid` bigint(20) NOT NULL AUTO_INCREMENT,  
  3.   `version` bigint(20) DEFAULT '0',  
  4. ... ...  
  5. ) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;  
  6.   
  7. CREATE TABLE `tbl_org` (  
  8.   `orgid` bigint(20) NOT NULL AUTO_INCREMENT,  
  9.   `version` bigint(20) DEFAULT '0',  
  10. ... ...  
  11. ) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;  

注意兩條語句最後的COLLATE後面的那一點,一個是utf8_unicode_ci,而另一個是utf8_general_ci,這裡描述的是資料庫校對規則,由於兩個表這裡的差異,造成了上面的錯誤。 
刪除其中的一個表,重新建立之,使二者資料庫校對規則一致後,問題解決。