2015-09-25 39 views
4

我正在使用MYSQL C API準備好的語句,並且遇到截斷問題。 mysql_stmt_fetch()總是返回MYSQL_DATA_TRUNCATED,我不明白爲什麼。有人可以告訴我爲什麼數據會被截斷以幫助我解決這個問題嗎?我能想到的唯一原因是如果我的緩衝區變量不是正確的類型,但我認爲它們是正確的類型。如果你有興趣,我使用的代碼如下。我還展示了我的表格及其結構的副本,我直接從MYSQL客戶端的命令中獲取。用C api解決MYSQL截斷問題

關於代碼的一些注意事項:

我已經修改了它打印出來的值,即使它返回截斷數據。當我這樣做時,第一個字段似乎打印正確,但浮動字段和日期時間字段是亂碼。另外,它似乎讀取正確的行數。

大部分代碼錯誤檢查各種函數調用。這些錯誤檢查都不會被觸發 - 或者至少它們中的任何一個都不會像您期望的那樣打印出郵件。唯一的錯誤指示是獲取調用返回的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()沒有返回錯誤,表明數據類型不匹配。您可以看到浮點數在我的數據庫的第3個字段中,但在我的param[]陣列中第二個。切換MYSQL_BIND結構的順序解決了我的問題。

我發佈這個解決方案,而不是刪除這個問題,因爲很少有信息可以找到MYSQL截斷錯誤在別處在線和其他人可能會使這個微妙的,雖然簡單的錯誤。