服务器 频道

在MySQL数据库中使用C执行SQL语句(下)

  【IT168 服务器学院】全部立即数据检索的函数

  可以从SELECT语句(或其他返回数据的语句)中检索完所有数据,在单一调用中,使用mysql_store_result:

  

MYSQL_RES *mysql_store_result(MYSQL *connection);

必须在mysql_query检索数据后才能调用这个函数,以在结果集中存储该数据。这个函数从服务器中检索所有数据并立即将它存储在客户机中。它返回一个指向以前我们从未遇到过的结构(结果集结构)的指针。如果语句失败,则返回NULL。

  使用等价的PostgreSQL时,应该知道返回NULL意味着已经发生了错误,并且这与未检索到数据的情况不同。即使,返回值不是NULL,也不意味着当前有数据要处理。

  如果未返回NULL,则可以调用mysql_num_rows并且检索实际返回的行数,它当然可能是0。

  

my_ulonglong mysql_num_rows(MYSQL_RES *result);

  它从mysql_store_result取得返回的结果结构,并且在该结果集中返回行数,行数可能为0。如果mysql_store_result成功,则mysql_num_rows也总是成功的。

  这种mysql_store_result和mysql_num_rows的组合是检索数据的一种简便并且直接的方法。一旦 mysql_store_result成功返回,则所有查询数据都已经存储在客户机上并且我们知道可以从结果结构中检索它,而不用担心会发生数据库或网络错误,因为对于程序所有数据都是本地的。还可以立即发现返回的行数,它可以使编码更简便。如前所述,它将所有结果立即地发送回客户机。对于大结果集,它可能耗费大量的服务器、网络和客户机资源。由于这些原因,使用更大的数据集时,最好仅检索需要的数据。不久,我们将讨论如何使用 mysql_use_result函数来完成该操作。

  一旦检索了数据,则可以使用mysql_fetch_row来检索它,并且使用mysql_data_seek、mysql_row_seek、mysql_row_tell操作结果集。在开始检索数据阶段之前,让我们先讨论一下这些函数。

  

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

  这个函数采用从存储结果中获取的结果结构,并且从中检索单一行,在行结构中返回分配给您的数据。当没有更多数据或者发生错误时,返回NULL。稍后,我们将回来处理这一行中的数据。

  

void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);

  这个函数允许您进入结果集,设置将由下一个获取操作返回的行。offset是行号,它必须在从0到结果集中的行数减 1 的范围内。传递0将导致在下一次调用mysql_fetch_row时返回第一行。

  

MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *result);

这个函数返回一个偏移值,它表示结果集中的当前位置。它不是行号,不能将它用于mysql_data_seek。但是,可将它用于:

  

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);

  它移动结果集中的当前位置,并返回以前的位置。

  有时,这一对函数对于在结果集中的已知点之间跳转很有用。请注意,不要将row tell和row seek使用的偏移值与data_seek使用的行号混淆。这些是不可交换的,结果将是您所希望看到的。

  

void mysql_free_result(MYSQL_RES *result);

  完成结果集时, 必须总是调用这个函数,以允许MySQL库整理分配给它的对象。

   检索数据

  现在开始编写从数据库中检索数据的第一个程序。我们将选择所有年龄大于5的行的内容。不幸的是我们还不知道如何处理这个数据,所以我们能做的只有循环检索它。这便是 select1.c:

      #include 

#include
#include "mysql.h"
MYSQL my_connection;

MYSQL_RES *res_ptr; MYSQL_ROW sqlrow;
int main(int argc, char *argv[]) { int res;
mysql_init(&my_connection);
if (mysql_real_connect(&my_connection, "localhost", "rick",

"bar", "rick", 0, NULL, 0)) { printf("Connection success\n");
res = mysql_query(&my_connection, "SELECT childno,

fname, age FROM children WHERE age > 5");
if (res) {
printf("SELECT error: %s\n", mysql_error(&my_connection));
} else { res_ptr = mysql_store_result(&my_connection);
if (res_ptr) {
printf("Retrieved %luows\n",(unsignedlong)mysql_num_rows(res_ptr));

while ((sqlrow = mysql_fetch_row(res_ptr)))

{ printf("Fetched data...\n");
} if (mysql_errno(&my_connection))

{ fprintf(stderr,

"Retrive error: s\n",mysql_error

&my_connection)); }
} mysql_free_result(res_ptr);
} mysql_close(&my_connection);
} else { fprintf(stderr, "Connection failed\n");
if (mysql_errno(&my_connection))

{ fprintf(stderr, "Connection error %d: %s\n",

mysql_errno(&my_connection),mysql_error(&my_connection));
} } return EXIT_SUCCESS; }

  检索结果集并循环通过已检索的数据的重要部分都已突出显示。

  一次检索一行数据

  要按需要逐行检索数据,而不是立即获取全部数据并将它存储在客户机中,可以将mysql_store_result调用替换成 mysql_use_result:

MYSQL_RES *mysql_use_result(MYSQL *connection);

  这个函数还取得一个连接对象并返回结果结合指针,或者出错时返回NULL。与mysql_store_result相似,它返回指向结果集对象的指针;关键的不同点在于返回时,实际上没有将任何数据检索到结果集,只是初始化结果集以准备好检索数据。

0
相关文章