2015-09-25 5 views
4

Я использую подготовленные операторы с MYSQL C API, и у меня возникают проблемы с усечением. mysql_stmt_fetch() всегда возвращает MYSQL_DATA_TRUNCATED, и я не понимаю, почему. Может ли кто-нибудь объяснить мне причины, по которым данные будут усечены, чтобы помочь мне устранить эту проблему? Единственная причина, по которой я могу думать, это то, что мои буферные переменные не имеют нужного типа, но я думаю, что они правильные. Если вас это интересует, код, который я использую, приведен ниже. Я также показал копию моей таблицы и ее структуры, которую я взял непосредственно из команд в MYSQL-клиенте.Устранение усечения MYSQL с помощью C api

Заметки о коде:

Я изменил его, чтобы распечатать значения, даже если она возвращает усеченные данные. Когда я это делаю, первое поле, кажется, печатает правильно, но поле float и поле datetime искажены. Кроме того, он, кажется, читает правильное количество строк.

Большая часть кода является ошибкой при проверке различных вызовов функций. Ни одна из этих проверок ошибок не срабатывает - или, по крайней мере, ни один из них не распечатывает сообщения, как вы ожидали. Единственным признаком ошибки является значение 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 */ 
} 

ответ

5

Это оказалось разочаровывающе легкой ошибкой. Порядок моих структур MYSQL_BIND был неправильным и нет ошибки, возвращаемой mysql_stmt_bind_param(), чтобы указать несоответствие типа данных. Вы можете видеть, что float находится в поле 3 в моей базе данных, но второй в моем массиве param[]. Переключение порядка структур MYSQL_BIND решает мою проблему.

Я размещаю это решение вместо того, чтобы удалять этот вопрос, потому что очень мало информации можно найти на ошибках обрезания MYSQL в другом месте в Интернете, а другие могут сделать эту тонкую, хотя и простую ошибку.