MySQL C API дескриптор поле TEXT - PullRequest
4 голосов
/ 07 июля 2011

Когда кто-то использует подготовленные операторы в MySQL C API для обработки результата поля TEXT, необходимо указать длину строки для привязки 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)

В данном примере STRING_SIZE - известная константа, но как быть с полями TEXT, где длина данных может варьироваться от небольших размеров до мегабайт?

Есть ли для этого стандартные подходы?

Ответы [ 2 ]

2 голосов
/ 19 марта 2014

У меня была такая же проблема. Я решил эту проблему, как сказал pmg в первом пункте, используя настройку 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);
}

Надеюсь, это поможет!

2 голосов
/ 07 июля 2011

Страница справочника для mysql_stmt_fetch гласит:

В некоторых случаях вам может потребоваться определить длину значения столбца перед его извлечением с помощью mysql_stmt_fetch ().... Для этого вы можете использовать следующие стратегии:

  • Прежде чем вызывать mysql_stmt_fetch() для извлечения отдельных строк, передайте STMT_ATTR_UPDATE_MAX_LENGTH в mysql_stmt_attr_set(), затем вызовите mysql_stmt_store_result() вбуферизировать весь результат на стороне клиента.Установка атрибута STMT_ATTR_UPDATE_MAX_LENGTH приводит к тому, что максимальная длина значений столбца указывается элементом max_length метаданных набора результатов, возвращаемых mysql_stmt_result_metadata().

  • Invoke mysql_stmt_fetch() сбуфер нулевой длины для рассматриваемого столбца и указатель, в котором можно сохранить реальную длину.Затем используйте реальную длину с mysql_stmt_fetch_column().

Вы также можете прочитать страницу руководства для mysql_stmt_bind_result

...