API C API Command Line Field

When you use Prepared Expressions in the MySQL C API to process the result of a TEXT field, you need to specify the string length to bind out:

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) 

In this example, STRING_SIZE is a known constant, but what about TEXT fields, where the data length can vary from small sizes to megabytes?

Are there standard approaches for this?

+4
source share
2 answers

The mysql_stmt_fetch page says:

In some cases, you may need to determine the length of the column value before retrieving it with mysql_stmt_fetch () .... To do this, you can use the following strategies:

  • Before calling mysql_stmt_fetch() to extract individual rows, go STMT_ATTR_UPDATE_MAX_LENGTH to mysql_stmt_attr_set() , then call mysql_stmt_store_result() to buffer the entire result on the client side. Setting the STMT_ATTR_UPDATE_MAX_LENGTH attribute causes the maximum length of the column values ​​to be indicated by the max_length element of the result set metadata returned by mysql_stmt_result_metadata() .

  • Call mysql_stmt_fetch() with a zero-length buffer for the column in question and a pointer where you can save the actual length. Then use the real length with mysql_stmt_fetch_column() .

You may also like the manual page for mysql_stmt_bind_result

+2
source

I had the same problem. I solved this problem, as PMG said in the first paragraph, using the STMT_ATTR_UPDATE_MAX_LENGTH settings, here is my code:

 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); } 

Hope this helps!

+2
source

Source: https://habr.com/ru/post/892243/


All Articles