【问题标题】:Troubleshoot MYSQL truncation with C api使用 C api 解决 MYSQL 截断问题
【发布时间】:2015-12-22 18:54:01
【问题描述】:

我在 MYSQL C API 中使用准备好的语句,但遇到截断问题。 mysql_stmt_fetch() 总是返回 MYSQL_DATA_TRUNCATED 我不明白为什么。有人可以告诉我为什么会截断数据以帮助我解决此问题吗?我能想到的唯一原因是我的缓冲区变量的类型不正确,但我认为它们是正确的类型。如果您有兴趣,我正在使用的代码如下。我还展示了我的表及其结构的副本,我直接从 MYSQL 客户端中的命令获取。

关于代码的一些注意事项:

我已经修改它以打印出值,即使它返回截断的数据。当我这样做时,第一个字段似乎打印正确,但浮点字段和日期时间字段是乱码。此外,它似乎读取了正确的行数。

大部分代码是检查各种函数调用的错误。这些错误检查都不会被触发 - 或者至少它们都不会像您期望的那样打印出消息。唯一的错误指示是 fetch 调用返回的 MYSQL_DATA_TRUNCATED 值。

描述测量表:

+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| nodeId     | int(11)  | NO   | PRI | NULL    |       |
| recordtime | datetime | NO   | PRI | NULL    |       |
| slevel     | float    | YES  |     | NULL    |       |
+------------+----------+------+-----+---------+-------+

测量表的当前内容:

+--------+---------------------+--------+
| nodeId | recordtime          | slevel |
+--------+---------------------+--------+
|      1 | 2015-09-22 19:33:50 |      2 |
|      1 | 2015-09-24 21:10:20 |      2 |
|      2 | 2015-09-22 19:33:53 |      5 |
|      3 | 2015-09-22 19:33:55 |      2 |
|      3 | 2015-09-22 19:45:42 |      4 |
|      3 | 2015-09-24 21:12:12 |      2 |
|      3 | 2015-09-24 21:13:30 |    3.4 |
|      4 | 2015-09-22 19:33:57 |      7 |
|      4 | 2015-09-24 21:05:53 |      5 |
|      4 | 2015-09-24 21:07:27 |      3 |
|      4 | 2015-09-24 21:22:52 |    9.9 |
|      4 | 2015-09-24 21:35:53 |      5 |
|      6 | 2015-09-24 21:26:01 |    2.2 |
|      6 | 2015-09-24 21:28:15 |    5.4 |
+--------+---------------------+--------+
14 rows in set (0.00 sec)

我的代码:

static void select_rows (MYSQL_STMT *stmt){
char          *stmt_str = "SELECT nodeId, recordtime, slevel FROM Measurements";
MYSQL_BIND    param[3];
int           my_int;
float         my_float;
MYSQL_TIME    my_datetime;
my_bool       is_null[3];

  if (mysql_stmt_prepare (stmt, stmt_str, strlen (stmt_str)) != 0){
    print_stmt_error (stmt, "Could not prepare SELECT statement");
    return;}

  if (mysql_stmt_field_count (stmt) != 3){
    print_stmt_error (stmt, "Unexpected column count from SELECT");
    return;}

  memset ((void *) param, 0, sizeof (param)); /* zero the structures */

  /* set up INT parameter */

  param[0].buffer_type = MYSQL_TYPE_LONG;
  param[0].buffer = (void *) &my_int;
  param[0].is_unsigned = 0;
  param[0].is_null = &is_null[0];

  /* set up FLOAT parameter */

  param[1].buffer_type = MYSQL_TYPE_FLOAT;
  param[1].buffer = (void *) &my_float;
  param[1].buffer = (void *) &my_float;
  param[1].is_null = &is_null[1];

  /* set up DATETIME parameter */

  param[2].buffer_type = MYSQL_TYPE_DATETIME;
  param[2].buffer = (void *) &my_datetime;
  param[2].is_null = &is_null[2];

  if (mysql_stmt_bind_result (stmt, param) != 0){
    print_stmt_error (stmt, "Could not bind parameters for SELECT");
    return;}

  if (mysql_stmt_execute (stmt) != 0){
    print_stmt_error (stmt, "Could not execute SELECT");
    return;}

  if (mysql_stmt_store_result (stmt) != 0){
    print_stmt_error (stmt, "Could not buffer result set");
    return;}
  else{
    printf ("Number of rows retrieved: %lu\n",
            (unsigned long) mysql_stmt_num_rows (stmt));}

  int ii = mysql_stmt_fetch (stmt);
  while (ii == 0 || ii==MYSQL_DATA_TRUNCATED)  /* fetch each row */
{
    /* display row values */
    printf ("%d  ", my_int);
    printf ("%.2f  ", my_float);
    printf ("%04d-%02d-%02d %02d:%02d:%02d\n",
            my_datetime.year,
            my_datetime.month,
            my_datetime.day,
            my_datetime.hour,
            my_datetime.minute,
            my_datetime.second);
  ii=mysql_stmt_fetch (stmt);
  }
  mysql_stmt_free_result (stmt);      /* deallocate result set */
}

【问题讨论】:

    标签: mysql c api truncation


    【解决方案1】:

    结果证明这是一个令人沮丧的简单错误。我的MYSQL_BIND 结构的顺序不正确,mysql_stmt_bind_param() 没有返回错误以指示数据类型不匹配。您可以看到浮点数在我的数据库中的字段 3 中,但在我的 param[] 数组中的第二位。切换MYSQL_BIND 结构的顺序解决了我的问题。

    我发布这个解决方案而不是删除这个问题,因为在网上其他地方几乎没有关于 MYSQL 截断错误的信息,其他人可能会犯这个微妙的错误,尽管是简单的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 2019-06-20
      • 2011-05-16
      相关资源
      最近更新 更多