昨天在测试MySQL的C-API的时候,调用mysql_stmt_fetch遇到一个错误:MYSQL_DATA_TRUNCATED (返回值101) 。
字段定义如下:
+---------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------+------+-----+---------+-------+
... ...
| CONTENT | varchar(4000) | YES | | NULL | |
检查一下代码, “bind[1].buffer_length = 4000”。
然后直接查询DB:
mysql 5.1.45-community-log> SELECT ID, CHAR_LENGTH(content), CHARACTER_LENGTH(content), LENGTH(content) FROM TEST_A WHERE ID = 1;
+--------------------------------------+----------------------+---------------------------+-----------------+
| ID | CHAR_LENGTH(content) | CHARACTER_LENGTH(content) | LENGTH(content) |
+--------------------------------------+----------------------+---------------------------+-----------------+
| 1 | 3998 | 3998 | 4002 |
+--------------------------------------+----------------------+---------------------------+-----------------+
1 row in set (0.00 sec)
mysql 5.1.45-community-log>
问题找到了。是因为length()返回的是字节数,而varchar(4000)定义的时候,4000是字符数。DB是utf8的,所以里面有几个非ascii的字符,造成了这个现象。
修改绑定变量的长度,重新执行,正常。
附定义, 从官方文档摘录:
CHAR和VARCHAR类型声明的长度表示你想要保存的最大字符数。例如,CHAR(30)可以占用30个字符。
返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。
CHARACTER_LENGTH()是CHAR_LENGTH()的同义词。
返回值为字符串str 的长度,单位为字节。一个多字节字符算作多字节。这意味着 对于一个包含5个2字节字符的字符串, LENGTH() 的返回值为 10, 而 CHAR_LENGTH()的返回值则为5。