mysql字符集的默认校对规则(GBK编码的故障分析-爱可生)
mysql字符集的默认校对规则(GBK编码的故障分析-爱可生)enum CharClass : byte这里定义了需要转移哪些字符,其中包括全角和半角单引号了。从错误提示来看,有这几个表现:故障分析首先需要查看下 .net 驱动源码,确认以上1、2、3现象确实是驱动行为。
一次MySQL gbk编码的故障分析
最近有用户遇到MySQL GBK字符集的一个坑,我也是第一次遇到,网上也没看此类case,所以整理了故障分析报告分享给大家,供参考。
故障描述
用户描述说:在使用MySQL for .NET Connector的时候,MySQL客户端和服务端的字符集设置都是GBK的情况下,遇到中文输入中夹杂全角字符提示语法错误,不清楚为何被添加了转义符号,怀疑和全角字符有关。
从错误提示来看,有这几个表现:
- 字符串中间的全角单引号字符被加上了反斜杠转义;
- 字符串末尾的半角单引号字符被加上了反斜杠转义;
- 整个字符串被单引号包裹;
- 提示语法错误,而非数据格式相关错误。
故障分析
首先需要查看下 .net 驱动源码,确认以上1、2、3现象确实是驱动行为。
这里定义了需要转移哪些字符,其中包括全角和半角单引号了。
enum CharClass : byte
{
None
Quote
Backslash
}
private static string stringOfBackslashChars ="\u005c\u00a5\u0160\u20a9\u2216\ufe68\uff3c";
private static string stringOfQuoteChars =
"\u0022\u0027\u0060\u00b4\u02b9\u02ba\u02bb\u02bc\u02c8\u02ca\u02cb\u02d9\u0300\u0301\u2018\u2019\u201a\u2032\u2035\u275b\u275c\uff07";
private static CharClass[ ] charClassArray = makeCharClassArray();
为这些字符添加反斜杠转义符
数据写入时最外层会用单引号包裹。
通过这些代码可以验证了上述几个现象。
- 全角半角单引号字符确实会被转义;
- 转义原因是外层使用的单引号。
通过这些现象,我猜测是因为转义失败导致。接下来通过一些方法重现故障场景,验证我的猜想。
首先验证在utf8编码下的表现,无论外层是双引号还是单引号,内部的单引号都能正常转义。
然后验证在gbk编码下的表现,字符串包含汉字的情况下,提示语法错误与用户遇到的错误一致,重现故障场景。
通过查看编码表得知5C代表反斜杠 ,说明单引号没有被正常转义。
mysql> select hex('茅\'');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''茅\'')' at line 1
mysql> select hex("茅\'");
--------------
| hex("茅\'") |
--------------
| E88C855C27 |
--------------
1 row in set (0.00 sec)
无汉字夹杂可以正常转义。
验证是否和全角字符有关,也可以正常转义,说明不是全角字符影响。