您的位置:首页 > 数据库 > MySQL

MySql C API查询过程介绍

2005-03-30 23:48 483 查看
MySql C API查询过程介绍
2005-3-28 keep_thinking     

一、概述
MySql的C API的查询主要分成两类,字符串组成的sql语句的查询,包含二进制数据的sql语句的查询。第一类查询只需要传入sql语句给查询函数即可,第二类查询不但需要传递sql语句,还要传入sql语句的长度。显然第一类查询是不需要传递长度的,因为系统知道NULL表示字符串的终结。而第二种查询必须传递sql语句的长度,因为含有二进制的数据的sql语句中有可能会有值为NULL的字节,如果还是按照第一种的策略来取查询语句的长度,显然会存在将其中途截断的危险。
下面分别对第一类查询和第二类查询各举一个例子。
二、传入不含二进制数据的sql语句的查询
首先请粗略的看一遍代码,下面进行详细地分析。
void db_do_query(MYSQL *db, const char *query)
{
         if (mysql_query(db, query) != 0)
                   goto err;
         if (mysql_field_count(db) > 0)
         {
                  MYSQL_RES   *res;
                  MYSQL_ROW    row;
                   int num_fields;
                   if (!(res = mysql_store_result(db)))
                            goto err;
                  num_fields = mysql_num_fields(res);
                   while ((row = mysql_fetch_row(res)))
                   {
                            for (int i=0; i < num_fields; i++)
                                     if(row==NULL)
                                              cout<<"NULL";
                                     else
                                              cout<<row[i]<<' ';
                            cout<<endl;
                   }
                  mysql_free_result(res);
         }
         else
                  (void)printf("Affected rows: %lld/n", mysql_affected_rows(db));
         return;
err:
         die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);

}
对于不包含二进制数据的查询,最核心的就是上面这一段代码
1. mysql_query是MySql的查询函数它需要2个参数,一个是指向MySQL结构类型的指针,另一个是包含sql查询语句的字符串。mysql_query函数本身并不能返查询后的结果,要得到结果需要再调用另一个函数mysql_store_result。
2. 函数mysql_store_result的返回值是一个指向MYSQL_RES结构的指针,该指针指向了查询结果。但是还是不能直接通过MYSQL_RES打印出每一个数据项。
3. 需要调用mysql_fetch_row函数来得到指向每一个查询结果的数据项的指针,该函数需要反复调用,每调用一次就返回一行的指针。在上述代码中,用循环语句反复调用的,直到结果表的末尾。另外你也可以使用mysql_num_rows函数返回查询结果集有多少行数据。
4. mysql_fetch_row函数返回的结果是一个MYSQL_ROW结构的指针,该指针可以看成一个字符串数组,该数组成存放着查询结果的一行的每个域的值,可以通过中括号运算符索引。
5. 这时候还有一个问题,究竟得到的查询结果表有多少个域呢?,这个值可以通过函数mysql_num_fields得到。
三、传入含有二进制数据的sql语句的查询
先看下面的代码,注意与上面列出的传入字符串数据的sql语句的查询的源代码不同的地方。
void db_do_real_query(MYSQL *db, const char *query, unsigned int len)
{
         if (mysql_query(db, query) != 0)
                   goto err;
         if (mysql_field_count(db) > 0)
         {
                  MYSQL_RES   *res;
                  MYSQL_ROW    row;
                   int num_fields;
                   ulong* lengths; //用来存储结果集的列数据的长度
                   if (!(res = mysql_store_result(db)))
                            goto err;
                  num_fields = mysql_num_fields(res);
                   while ((row = mysql_fetch_row(res)))
                   {
                            lengths = mysql_fetch_lengths(res);
                            for (int i=0; i < num_fields; i++)
                                     if(row==NULL)
                                              cout<<"NULL";
                                     else
                                               //得到的数据地址是row[i],长度是lengths[i]
                            cout<<endl;
                   }
                  mysql_free_result(res);
         }
         else
                  (void)printf("Affected rows: %lld/n", mysql_affected_rows(db));
         return;
err:
         die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
}
不同的地方只有两个:
1. 函数需要传入查询的sql语句的长度,原因上文已述。
2. 就是需要一个ulong型的指针来存储结果集数据的宽度。
四、另外两个问题
1.关于mysql_store_result和两个mysql_use_result函数,这两个函数都是得到查询结果集的函数,例子程序中都是用的第一个,可以换成第二个。这两个函数的不同之处在于,第一个函数会返回整个的结果集,第二个是逐个返回结果集的元组,当fetch的时候才返回后面的。
2.由于mysql的C API函数用到许多mysql自定义的类型,直接将其用到MFC的程序中是有问题的。或许是mysql的头文件和stdafx.h不兼容。解决的办法是编写一个dll文件用MFC编写的程序调用。显然dll也是不能用MFC写的,需要用SDK来写。
附录、MySQL C 变量类型
以下变量类型在MySQL的库当中定义。我们需要这些变量是为了使用MySQL的函数。这些变量有详细的解释,但是这些解释对于写代码来说并不重要。
MYSQL结构,一开始要定义一个指向该结构类型的指针,在MySql后继的所有关键函数,包括初始化、查询、结束查询都要用到这个指针作为参数
结构的定义:
typedef struct st_mysql {
 NET           net;            /* Communication parameters */
 gptr          connector_fd;   /* ConnectorFd for SSL */
 char          *host,*user,*passwd,*unix_socket,
  *server_version,*host_info,*info,*db;
 unsigned int  port,client_flag,server_capabilities;
 unsigned int  protocol_version;
 unsigned int  field_count;
 unsigned int  server_status;
 unsigned long thread_id;      /* Id for connection in server */
 my_ulonglong affected_rows;
 my_ulonglong insert_id;       /* id if insert on table with NEXTNR */
 my_ulonglong extra_info;              /* Used by mysqlshow */
 unsigned long packet_length;
 enum mysql_status status;
 MYSQL_FIELD   *fields;
 MEM_ROOT      field_alloc;
 my_bool       free_me;        /* If free in mysql_close */
 my_bool       reconnect;      /* set to 1 if automatic reconnect */
 struct st_mysql_options options;
 char          scramble_buff[9];
 struct charset_info_st *charset;
 unsigned int  server_language;
} MYSQL;
MYSQL_RES用来表示查询结果返回值的结构,
typedef struct st_mysql_res {
 my_ulonglong row_count;
 unsigned int  field_count, current_field;
 MYSQL_FIELD   *fields;
 MYSQL_DATA    *data;
 MYSQL_ROWS    *data_cursor;
 MEM_ROOT      field_alloc;
 MYSQL_ROW     row;            /* If unbuffered read */
 MYSQL_ROW     current_row;    /* buffer to current row */
 unsigned long *lengths;       /* column lengths of current row */
 MYSQL         *handle;        /* for unbuffered reads */
 my_bool       eof;            /* Used my mysql_fetch_row */
} MYSQL_RES;
其他数据类型和函数的说明参考MySQL参考手册。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql api c query sql struct