6.4.11 mysql_stmt_fetch()
int
mysql_stmt_fetch(MYSQL_STMT *stmt)
Описание
mysql_stmt_fetch() возвращает следующую строку в наборе результатов. Она может быть вызвана только пока набор результатов существует; то есть, после вызова mysql_stmt_execute() для оператора, который возвращает набор результатов.
mysql_stmt_fetch() возвращает данные строки, используя буферы, связанные с помощью mysql_stmt_bind_result(). Она возвращает данные в этих буферах для всех столбцов текущей строки и длины возвращаются в указатель length. Все столбцы должны быть связаны приложением перед вызовом mysql_stmt_fetch().
mysql_stmt_fetch() обычно используется внутри цикла, чтобы гарантировать, что все строки набора результатов будут извлечены. Например:
int status;
while (1)
{
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA)
break;
/* handle current row here */
}
/* if desired, handle status == 1 case and display error here */
По умолчанию, наборы результатов извлекаются небуферизованно, по строке за раз, с сервера. Для буферизации всего набора результатов на стороне клиента, вызовите mysql_stmt_store_result() после связывания буферов данных и перед вызовом mysql_stmt_fetch().
Если извлечённое значение данных является значением NULL, значение *is_null соответствующей структуры MYSQL_BIND содержит TRUE (1). В противном случае, данные и их длина возвращаются в элементы *buffer и *length, в зависимости от типа буфера, указанного приложением. Каждый числовой и временной тип имеет фиксированную длину, как указано в следующей таблице. Длина строковых типов зависит от длины фактического значения данных, как указано data_length.
| Тип | Длина |
|---|---|
MYSQL_TYPE_TINY | 1 |
MYSQL_TYPE_SHORT | 2 |
MYSQL_TYPE_LONG | 4 |
MYSQL_TYPE_LONGLONG | 8 |
MYSQL_TYPE_FLOAT | 4 |
MYSQL_TYPE_DOUBLE | 8 |
MYSQL_TYPE_TIME | sizeof(MYSQL_TIME) |
MYSQL_TYPE_DATE | sizeof(MYSQL_TIME) |
MYSQL_TYPE_DATETIME | sizeof(MYSQL_TIME) |
MYSQL_TYPE_STRING | data length |
MYSQL_TYPE_BLOB | data_length |
В некоторых случаях вам может потребоваться определить длину значения столбца перед его извлечением с помощью 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().-
Вызовите
mysql_stmt_fetch()с буфером нулевой длины для рассматриваемого столбца и указателем, в котором можно сохранить фактическую длину. Затем используйте фактическую длину сmysql_stmt_fetch_column().real_length= 0; bind[0].buffer= 0; bind[0].buffer_length= 0; bind[0].length= &real_length mysql_stmt_bind_result(stmt, bind); mysql_stmt_fetch(stmt); if (real_length > 0) { data= malloc(real_length); bind[0].buffer= data; bind[0].buffer_length= real_length; mysql_stmt_fetch_column(stmt, bind, 0, 0); }
Значения возврата
| Возвращаемое значение | Описание |
|---|---|
| 0 | Успех, данные извлечены в буферы данных приложения. |
| 1 | Произошла ошибка. Код и сообщение об ошибке можно получить, вызвав mysql_stmt_errno() и mysql_stmt_error(). |
MYSQL_NO_DATA | Успех, больше данных нет |
MYSQL_DATA_TRUNCATED | Произошло усечение данных |
MYSQL_DATA_TRUNCATED возвращается, когда включено отслеживание усечения. Чтобы определить, какие значения столбцов были усечены, когда возвращается это значение, проверьте члены error структур MYSQL_BIND, используемых для извлечения значений. Отслеживание усечения включено по умолчанию, но может управляться с помощью вызова mysql_options() с параметром MYSQL_REPORT_DATA_TRUNCATION.
Ошибки
-
Команды были выполнены в неправильном порядке.
Хотя
mysql_stmt_fetch()может вызывать эту ошибку, она с большей вероятностью возникнет при последующем вызове API C, еслиmysql_stmt_fetch()не вызывался достаточно много раз для чтения всего набора результатов (то есть, достаточно много раз, чтобы вернутьMYSQL_NO_DATA). -
Отсутствие памяти.
-
Сервер MySQL вышел из строя.
-
Соединение с сервером было потеряно во время запроса.
-
Произошла неизвестная ошибка.
-
Тип буфера является
MYSQL_TYPE_DATE,MYSQL_TYPE_TIME,MYSQL_TYPE_DATETIMEилиMYSQL_TYPE_TIMESTAMP, но тип данных не является , , , или . Все остальные неподдерживаемые ошибки преобразования возвращаются из
mysql_stmt_bind_result().
Пример
В следующем примере показано, как извлечь данные из таблицы с помощью mysql_stmt_result_metadata(), mysql_stmt_bind_result() и mysql_stmt_fetch(). (В этом примере ожидается извлечение двух строк, вставленных в примере, показанном в разделе 6.4.10, «mysql_stmt_execute()».) Переменная mysql предполагается как действительный обработчик подключения.
#define STRING_SIZE 50
#define SELECT_SAMPLE "SELECT col1, col2, col3, col4 \
FROM test_table"
MYSQL_STMT *stmt;
MYSQL_BIND bind[4];
MYSQL_RES *prepare_meta_result;
MYSQL_TIME ts;
unsigned long length[4];
int param_count, column_count, row_count;
short small_data;
int int_data;
char str_data[STRING_SIZE];
my_bool is_null[4];
my_bool error[4];
/* Prepare a SELECT query to fetch data from test_table */
stmt = mysql_stmt_init(mysql);
if (!stmt)
{
fprintf(stderr, " mysql_stmt_init(), out of memory\n");
exit(0);
}
if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))
{
fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(0);
}
fprintf(stdout, " prepare, SELECT successful\n");
/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
fprintf(stdout, " total parameters in SELECT: %d\n", param_count);
if (param_count != 0) /* validate parameter count */
{
fprintf(stderr, " invalid parameter count returned by MySQL\n");
exit(0);
}
/* Execute the SELECT query */
if (mysql_stmt_execute(stmt))
{
fprintf(stderr, " mysql_stmt_execute(), failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(0);
}
/* Fetch result set meta information */
prepare_meta_result = mysql_stmt_result_metadata(stmt);
if (!prepare_meta_result)
{
fprintf(stderr,
" mysql_stmt_result_metadata(), \
returned no meta information\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(0);
}
/* Get total columns in the query */
column_count= mysql_num_fields(prepare_meta_result);
fprintf(stdout,
" total columns in SELECT statement: %d\n",
column_count);
if (column_count != 4) /* validate column count */
{
fprintf(stderr, " invalid column count returned by MySQL\n");
exit(0);
}
/* Bind the result buffers for all 4 columns before fetching them */
memset(bind, 0, sizeof(bind));
/* INTEGER COLUMN */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= &is_null[0];
bind[0].length= &length[0];
bind[0].error= &error[0];
/* STRING COLUMN */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= &is_null[1];
bind[1].length= &length[1];
bind[1].error= &error[1];
/* SMALLINT COLUMN */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;
bind[2].is_null= &is_null[2];
bind[2].length= &length[2];
bind[2].error= &error[2];
/* TIMESTAMP COLUMN */
bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
bind[3].buffer= (char *)&ts;
bind[3].is_null= &is_null[3];
bind[3].length= &length[3];
bind[3].error= &error[3];
/* Bind the result buffers */
if (mysql_stmt_bind_result(stmt, bind))
{
fprintf(stderr, " mysql_stmt_bind_result() failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(0);
}
/* Now buffer all results to client (optional step) */
if (mysql_stmt_store_result(stmt))
{
fprintf(stderr, " mysql_stmt_store_result() failed\n");
fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
exit(0);
}
/* Fetch all rows */
row_count= 0;
fprintf(stdout, "Fetching results ...\n");
while (!mysql_stmt_fetch(stmt))
{
row_count++;
fprintf(stdout, " row %d\n", row_count);
/* column 1 */
fprintf(stdout, " column1 (integer) : ");
if (is_null[0])
fprintf(stdout, " NULL\n");
else
fprintf(stdout, " %d(%ld)\n", int_data, length[0]);
/* column 2 */
fprintf(stdout, " column2 (string) : ");
if (is_null[1])
fprintf(stdout, " NULL\n");
else
fprintf(stdout, " %s(%ld)\n", str_data, length[1]);
/* column 3 */
fprintf(stdout, " column3 (smallint) : ");
if (is_null[2])
fprintf(stdout, " NULL\n");
else
fprintf(stdout, " %d(%ld)\n", small_data, length[2]);
/* column 4 */
fprintf(stdout, " column4 (timestamp): ");
if (is_null[3])
fprintf(stdout, " NULL\n");
else
fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
ts.year, ts.month, ts.day,
ts.hour, ts.minute, ts.second,
length[3]);
fprintf(stdout, "\n");
}
/* Validate rows fetched */
fprintf(stdout, " total rows fetched: %d\n", row_count);
if (row_count != 2)
{
fprintf(stderr, " MySQL failed to return all rows\n");
exit(0);
}
/* Free the prepared result metadata */
mysql_free_result(prepare_meta_result);
/* Close the statement */
if (mysql_stmt_close(stmt))
{
/* mysql_stmt_close() invalidates stmt, so call */
/* mysql_error(mysql) rather than mysql_stmt_error(stmt) */
fprintf(stderr, " failed while closing the statement\n");
fprintf(stderr, " %s\n", mysql_error(mysql));
exit(0);
}
© 2025 Oracle
Licensed under the GPLv2 License.