我试图找出与数据截断相关的一些警告消息之间的区别。考虑下表:
CREATE TABLE `txttest` (
`mycol` text NOT NULL )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
几乎预期的行为:
mysql > insert into txttest (mycol) values (repeat('a',65535));
Query OK, 1 row affected (0.17 sec)
mysql > insert into txttest (mycol) values (repeat('a',65536));
Query OK, 1 row affected, 1 warning (0.16 sec)
mysql > show warnings;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1265 | Data truncated for column 'mycol' at row 1 |
+---------+------+--------------------------------------------+
1 row in set (0.00 sec)
但是,当我使用多字节字符时,会出现预期的警告状态,但消息不同:
mysql > insert into txttest (mycol) values (repeat('é',65536/2-1));
Query OK, 1 row affected (0.17 sec)
mysql > insert into txttest (mycol) values (repeat('é',65536/2));
Query OK, 1 row affected, 1 warning (0.16 sec)
mysql > show warnings;
+---------+------+----------------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xC3\xA9' for column 'mycol' at row 1 |
+---------+------+----------------------------------------------------------------+
1 row in set (0.00 sec)
谷歌的尝试并不是很有用,因为我主要是针对不同的上下文运行此消息的粘贴。
基本上我想知道的是:这只是Mysql在截断多字节字符序列时使用的措辞/错误代码,还是有更多的东西告诉我应该从这条消息中收集信息?
我最初认为这意味着字节序列被分割得如此之远,导致字符格式错误。试图让它做到这一点的尝试并没有奏效(例如mysql似乎很好地识别字符编码的正确字节边界)。
编辑:
在重新审视之后,它看起来确实是我最初驳回的字符分裂。最初看它时,我大吃一惊。
尝试将 2 字节字符串存储到一个字节中
由于 TEXT 的最大长度为 65535,因此它可以安全地保存 32767 (65536/2 - 1) 个 2 字节字符而不会出现错误消息。
任何添加 32768 个 2 字节字符的尝试都将导致
Incorrect string value: '\xC3\xA9' for column 'mycol' at row 1
因为第 32768 个字符没有空间插入 mycol。实际上,您不会得到格式错误的字符。您确实可以使用 2 字节字符数和长度为 32767 的 TEXT 字段。最后一个字符只是丢失并且不考虑。
为了确保,运行这个
最后一个 INSERT 的长度不会是 65536 x 65534。