MySQL报错:Incorrect string value

前言

工作时有一个需求需要拉取Amazon生成的报告,一开始拉取看似是正常的,查看日志发现有一些文件拉取成功但是插入数据库失败,报错:Incorrect string value 网上搜出来的解决方法都是将 utf8 变为utf8mb4 原因是utf8字符集只占三个字节,而utf8mb4 占四个字节,说白了就是字节导致的无法正常表示字符。

但是设计数据库之初就使用了 utf8mb4 所以肯定不是这个原因,查了一圈也没找到个办法。最后把那个报错的字符找出来发现根本不在ascii码表里,进一步发现这个字符的编码方式并不是平时常用的编码方式,但是可以知道这个字符的一个单字节的字符,如果想让他正常显示和插入数据库,那么我们只需要按照utf8 的标准强行转为符合规范的 双字节即可。

UTF8 规定

UTF 8规定当字符占的位数为n,n > 1时,高位的字节前n位都为1,第n+1位为0,然后后面的字节的前两位都是10.然后剩余的位用Unicode值来填充,高位补0。格式就是下面这样:

一个字节: 0xxxxxxx

两个字节: 110xxxxx 10xxxxxx

三个字节: 1110xxxx 10xxxxxx 10xxxxxx

四个字节: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

单字节有8位,那么我们只需要构造一个 110 xxxxx 10 xxxxxx ,将八位从低到高填充即可。

func asciiFmtUtf8(c uint8) []byte {
 return []byte{0xC0 | (c >> 6), 0x80 | (c & 0x3f)}
}

注意: 这里只能转化128 ~ 255 的字符集单字节变为双字节,因为127 以内的只需要7位即可表示 转为 utf8 的话应该一个字节就可以表示了,不需要两个字节。

func repairInvalidUtf8(s string) string {
 res := make([]byte, 0, len([]byte(s)))
 for i, r := range s {
  if r == 0xfffd {
   bb := []byte(s[i : i+1])
   if len(bb) == 0 {
    continue
   }
   res = append(res, asciiFmtUtf8(uint8(bb[0]))...)
  } else {
   res = append(res, []byte(string(r))...)
  }
 }

 return string(res)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值