MySQL插入數(shù)據(jù)異常分析 SQL state [HY000]; error code [1366];

關(guān)鍵詞: java mysql 插入異常 1366 HY000

今天分享一個(gè)mysql數(shù)據(jù)插入異常的問題,由于工作排期問題,沒有時(shí)間去深入研究這個(gè)問題,也因此困擾了我很久,問題大概是這樣的,當(dāng)我們把4個(gè)字節(jié)的字符插入到數(shù)據(jù)表列字符集為3個(gè)字節(jié)的表中時(shí),會(huì)拋出以下異常,在沒有異常捕獲的情況下,導(dǎo)致程序崩潰以及事務(wù)持續(xù)性不健全

環(huán)境

mysql version: 5.6.35
JDK : 1.6.0_38

異常拋出:

nested exception is java.sql.SQLException: Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
     at org.springframework.orm.hibernate3.HibernateAccessor.convertJdbcAccessException(HibernateAccessor.java:424) 
     at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:410) 
     at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424) 
     at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
     at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:748) 
     at com.cargosmart.sime.core.persistence.dao.BaseDao.saveOrUpdate(BaseDao.java:39) 
     at ....
    Caused by: java.sql.SQLException: Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1 
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) 

問題分析:
我們可以看到上面異常中:Incorrect string value: '\xF4\x80\x80\x8062...' for column 'ERROR' at row 1,大致意思就是說對(duì)某數(shù)據(jù)庫表列ERROR 插入了不正確的字符串值\xF4\x80\x80\x8062...,那到底為什么是錯(cuò)誤的呢,首先我們可以看到那個(gè)不正確的字符串的特征,是一個(gè)4字節(jié)的十六進(jìn)制的字符\xF4\x80\x80\x80,再查查表字符集發(fā)現(xiàn)為UTF-8,到這里還沒發(fā)現(xiàn)根本問題,再仔細(xì)翻看了mysql官方version release notes,發(fā)現(xiàn)在version 5.5.3中發(fā)現(xiàn)有如下發(fā)布改進(jìn)記錄:

  • Changes in MySQL 5.5.3 (2010-03-24, Milestone 3)
Incompatible Change: The Unicode implementation has been extended to provide support for 
supplementary characters that lie outside the Basic Multilingual Plane (BMP). Noteworthy features:

utf16 and utf32 character sets have been added. These correspond to the UTF-16 and UTF-32 
encodings of the Unicode character set, and they both support supplementary characters.

The utf8mb4 character set has been added. This is similar to utf8, but its encoding allows up to 
four bytes per character to enable support for supplementary characters.

可以發(fā)現(xiàn)在version 5.5.3之后,增加了一種和utf-8類似的字符集utf8mb4,并且它的編碼支持4個(gè)字節(jié)每個(gè)字符,再看看mysql的字符集所支持的字節(jié)范圍:

mysql> SHOW CHARACTER SET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
...
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
...
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  |      4 |
...

可以發(fā)現(xiàn)utf8最大支持3個(gè)字節(jié)的字符,到這里就基本確定是因?yàn)檫@個(gè)字符集設(shè)定所引起的異常,于是我試著修改對(duì)應(yīng)列的字符集,這里的字符集分為表級(jí)字符集以及列級(jí)字符集,如果沒有特別設(shè)定,列級(jí)字符集默認(rèn)繼承表級(jí)字符集,于是為了降低產(chǎn)品的影響面,我試著將發(fā)生異常的列的字符集改成utf8mb4,

ALTER TABLE `<db name>`.`<table name>` CHANGE COLUMN `ERROR` `ERROR` 
VARCHAR(500) CHARACTER SET 'utf8mb4' NULL DEFAULT NULL  ;

然后再重現(xiàn)了一下上面的異常,發(fā)現(xiàn)數(shù)據(jù)插入成功。至此,問題解決。

總結(jié),這個(gè)異常的發(fā)生是由于4字節(jié)的字符插入到字符集為3字節(jié)的列中,在插入數(shù)據(jù)之前,字符集驗(yàn)證失敗,字節(jié)溢出導(dǎo)致插入失敗異常。
解決方法: 將對(duì)應(yīng)列的字符集改成utf8mb4

——END——
作者 : Eason,專注各種技術(shù)、平臺(tái)、集成,不滿現(xiàn)狀,喜歡改改改
文章、技術(shù)合作,大膽的掃一掃,害羞的請(qǐng)郵件
Email : eason.lau02@hotmail.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、問題:mysql 遇到某些中文插入異常最近有同學(xué)反饋了這樣一個(gè)問題: 上述語句在腳本中 load 入庫的時(shí)候會(huì)...
    kanasu閱讀 3,196評(píng)論 1 4
  • MySQL技術(shù)內(nèi)幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創(chuàng)始人之一Monty分支的一個(gè)版...
    沉默劍士閱讀 2,649評(píng)論 0 3
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    草里有只羊閱讀 18,562評(píng)論 0 85
  • 人生是一個(gè)選擇的過程,人生最重要的選擇,就是選擇和誰在一起。選擇和誰共事,選擇和誰交朋友,選擇和誰結(jié)婚,選擇向誰學(xué)...
    luffydreaman閱讀 176評(píng)論 0 0
  • 原諒,似乎是對(duì)成人的最高褒獎(jiǎng)。漢代陸賈曰:“圣人貴寬,而世人賤眾?!笔ト酥允?,大抵是因?yàn)閷W(xué)會(huì)了原諒。 ...
    江桐閱讀 432評(píng)論 0 0

友情鏈接更多精彩內(nèi)容