2011-07-07 64 views
4

當人們使用準備語句在MySQL C API來處理TEXT域結果,一個具有以指定字符串的長度是否超出結合:MySQL的C API處理文本字段

MYSQL_BIND out_bind; 
char   str_data[STRING_SIZE]; 
my_bool  is_null; 
my_bool  error; 

.... 
/* STRING COLUMN */ 
out_bind.buffer_type = MYSQL_TYPE_STRING; 
out_bind.buffer = str_data; 
out_bind.buffer_length = STRING_SIZE; 
out_bind.is_null= &is_null; 
out_bind.length= &length; 
out_bind.error= &error; 

mysql_stmt_bind_result(statement, out_bind) 

在給定示例STRING_SIZE是已知的常量,但如何使用TEXT字段,其中數據長度可以從小尺寸變爲兆字節?

有沒有標準的方法呢?

+0

呃! 'str_data'本身(衰減後)是一個'char *'。你爲什麼要轉換成char *'? :) – pmg

+0

你說得對。從真正的代碼轉到這個簡化的例子之後,它只是一個呆在這裏的雛形。沒關係。 – MajesticRa

+0

我不記得確切,但你得到這個返回結構 – Ulterior

回答

2

的說:

在您可能希望確定與獲取了mysql_stmt_fetch前一列值的長度某些情況下()。 ......要做到這一點,你可以使用這些策略:

  • 之前調用mysql_stmt_fetch()檢索各行,傳遞到STMT_ATTR_UPDATE_MAX_LENGTHmysql_stmt_attr_set(),然後調用mysql_stmt_store_result()緩衝在客戶端的整個結果。設置STMT_ATTR_UPDATE_MAX_LENGTH屬性會導致由mysql_stmt_result_metadata()返回的結果集元數據的max_length成員指示列值的最大長度。

  • 調用mysql_stmt_fetch()與所討論的列和在其實際長度可被存儲在指針零長度緩衝器中。然後使用mysql_stmt_fetch_column()的實際長度。

您也可能會喜歡閱讀manual page for mysql_stmt_bind_result

2

我有同樣的問題。我在第一點解決了這個問題像PMG SAIDS,使用STMT_ATTR_UPDATE_MAX_LENGTH設置,這裏是我的代碼:

MYSQL_STMT *stmt; 
MYSQL_BIND bind[1]; 
MYSQL_BIND bind_result[1]; 

// _con your mysql connection 
stmt = mysql_stmt_init(_con); 
if (!stmt) 
{ 
    fprintf(stderr, " mysql_stmt_init(), out of memory\n"); 
    exit(0); 
} 

char* aQuery = (char*) "'your query'"; 
if (mysql_stmt_prepare(stmt, aQuery, strlen(aQuery))) 
{ 
    fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n"); 
    fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); 
    exit(0); 
} 

    // Here fill binded parameters (here a string) 
memset(bind, 0, sizeof(bind)); 

const char* aStr = ioType.c_str(); 
long unsigned int aSize = ioType.size(); 

bind[0].buffer_type= MYSQL_TYPE_STRING; 
bind[0].buffer= (char *) aStr; 
bind[0].buffer_length= 2048; 
bind[0].is_null= 0; 
bind[0].length= &aSize; 

/* Bind the buffers */ 
if (mysql_stmt_bind_param(stmt, bind)) 
{ 
    fprintf(stderr, " mysql_stmt_bind_param() failed\n"); 
    fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); 
    exit(0); 
} 

    // Reauest meta data information 
MYSQL_RES* aRes = mysql_stmt_result_metadata(stmt); 

    // Set STMT_ATTR_UPDATE_MAX_LENGTH attribute 
my_bool aBool = 1; 
mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &aBool); 

/* Execute the select statement - 1*/ 
if (mysql_stmt_execute(stmt)) 
{ 
    fprintf(stderr, " mysql_stmt_execute(), 1 failed\n"); 
    fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); 
    exit(0); 
} 

if (mysql_stmt_store_result(stmt)) { 
    fprintf(stderr, " mysql_stmt_execute(), 1 failed\n"); 
    fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); 
    exit(0); 
}  

// Retrieving meta data information 
MYSQL_FIELD* aField = &aRes->fields[0]; 

fprintf(stdout, " field %s \n",aField->name); 
fprintf(stdout, " field length %d \n",(int) aField->length); 
fprintf(stdout, " field max length %d \n", (int) aField->max_length); 


int totalrows = mysql_stmt_num_rows(stmt); 
fprintf(stdout, " fetched %d description\n",totalrows); 
fprintf(stdout, " field count %d \n",(int) aRes->field_count); 

long unsigned int aMaxSize; 
char* aBuffer = (char*) malloc(aField->max_length); 

memset (bind_result, 0, sizeof (bind_result)); 
bind_result[0].buffer_type= MYSQL_TYPE_BLOB; 
bind_result[0].is_null= 0; 
bind_result[0].buffer= (char *) aBuffer; 
bind_result[0].buffer_length= aField->max_length; 
bind_result[0].length= &aMaxSize; 

mysql_stmt_bind_result(stmt, bind_result); 

std::string aStrData; 
while(!mysql_stmt_fetch(stmt)) 
{ 
    fprintf(stdout, " size %d\n", (int) aMaxSize); 
    aStrData = std::string(aBuffer,aMaxSize); 
    fprintf(stdout, " data %s\n", aStrData.c_str()); 
} 

free(aBuffer); 

mysql_free_result(aRes); 

if (mysql_stmt_close(stmt)) 
{ 
    fprintf(stderr, " failed while closing the statement\n"); 
    fprintf(stderr, " %s\n", mysql_stmt_error(stmt)); 
    exit(0); 
} 

希望這有助於!