zoukankan      html  css  js  c++  java
  • MySQL中遍历查询结果的常用API(c)

    本中所使用的table:

    MySQL中的错误处理函数

     unsigned int mysql_errno(MYSQL *mysql) 

     const char *mysql_error(MYSQL *mysql) 

    说明:一个函数是返回错误号,一个返回错误信息,两者都以MYSQL*为参数,很直观。

    第一步:进行查询操作

    用到的函数:

    int mysql_query(MYSQL *mysql, const char *stmt_str) 

    int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned longlength) 

    返回值:成功则返回0,失败返回非零,如果失败的话,可以利用错误处理函数来获得错误信息。

    这两个函数的区别:当查询语句使用的是二进制数据时,只能用后者。

    第二步:保存查询结果(仅select语句具有查询结果,update、delete、insert是没有查询结果的)

    用到的函数:

     MYSQL_RES *mysql_store_result(MYSQL *mysql) 

     MYSQL_RES *mysql_use_result(MYSQL *mysql) 

    返回值:如果执行成功,返回一个非空的MYSQL_RES指针,否则,返回NULL。注意,只要执行select语句成功,就算没有与该select语句匹配的表项,该函数的返回值也不应为NULL。

    两个函数的区别:mysql_store_result将整个result set放进client中存储,假若select的查询结果有一百个表项,则调用mysql_store_result会将这一百个表项全都存在了内存中,而mysql_use_result仅仅从result set中取出一个表项存在内存中,使用mysql_fetch_row()函数时才从server中的result set中取出下一个表项。因此mysql_use_result占用的内存更少执行速度也更快。但如果你需要在client端对result set的数据进行一些处理的话,那还是用mysql_store_set吧。

    总结:mysql_store_result将select语句在server中的执行结果全都存到了client的内存中,而mysql_use_result仅当需要用到数据时才从server中取出下一条数据存到client的内存中。

    注意:结果用完之后,要用mysql_free_result()释放内存。该函数的原型为 void mysql_free_result(MYSQL_RES *result) 

     第三步:遍历结果

    遍历结果可分为两个步骤:首先取出result set中的一行数据,然后再遍历该行数据中的每列数据。

    遍历行时用到的函数:

     MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 

    说明:它以上一步中的查询结果为参数,返回一个MYSQL_ROW结构体,这个结构体的内容为result set中的一行数据,可以理解为一个元素为字符指针的数组(char* row[elems]),当result set中的所有数据遍历完毕,该函数返回NULL。那么怎样使用这个结构体呢?首先得通过下面的函数(mysql_num_fields() / mysql_field_count())得到result set中的列数,然后从index从0开始,以(列数 - 1)结束,依此遍历就可以了。以col代指当前列,若当前列的值为NULL,MYSQL_ROW[col]的值也为NULL。

    使用示例:

     1 MYSQL_ROW row;
     2 unsigned int cols = mysql_field_count(conn_ptr);
     3 while ((row = mysql_fetch_row(res_ptr)) != NULL)
     4 {
     5     for (unsigned int i = 0; i < cols; ++i)
     6     {
     7         printf("%s ", row[i]);
     8     }
     9     printf("
    ");
    10 }

    输出结果如下:

    其实正常情况下应该对row[i]是否为NULL进行判断的,这里让我有点疑惑,为何row[i]在为空的情况下,也行正常printf出结果,而不产生段错误。

     1 MYSQL_ROW row;
     2 unsigned int cols = mysql_field_count(conn_ptr);
     3 while((row = mysql_fetch_row(res_ptr)) != NULL)
     4 {      
     5     for(unsigned int i = 0;i < cols;++i)
     6     {  
     7         if(row[i] == NULL)
     8             printf("i am null");
     9         else                                     
    10             printf("%s ",row[i]);
    11     }   
    12     printf("
    ");
    13 }   

    结果:

    遍历列时用到的函数:

     unsigned int mysql_num_fields(MYSQL_RES *result) 

     unsigned int mysql_field_count(MYSQL *mysql) 

     MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result) 

    对于前面两个函数,它们的参数不同,但是效果却是相同的,都是返回当前查询的result set中的列数。

    通过第三个函数可以得到列的属性(包括列的name,列的type等信息),它的用法与mysql_fetch_col()差不多,也需要用while不停地循环。当返回值为空时,就代表没有下一列了。

    使用示例:

     1  MYSQL_RES* res_ptr = mysql_store_result(conn_ptr);
     2  if(res_ptr)
     3  {
     4      printf("use result successful
    ");
     5      
     6      MYSQL_FIELD* field;
     7      while((field = mysql_fetch_field(res_ptr)))
     8      {
     9          printf("%s ",field->name);
    10      }
    11      printf("
    ");
    12 
    13  }

    结果: 

     全部代码

     1 #include <mysql/mysql.h>
     2 
     3 #include <stdlib.h>
     4 #include <stdio.h>
     5 
     6 int main()
     7 {
     8     //MYSQL* mysql_init(MYSQL *mysql)
     9     MYSQL* conn_ptr = mysql_init(NULL);
    10     if(conn_ptr == NULL)
    11     {
    12         fprintf(stderr,"mysql_init() failed
    ");
    13         return -1;
    14     }
    15     //MYSQL* mysql_real_connect(MYSQL *mysql, const char *host,
    16     //const char *user,const char *passwd, const char *db,
    17     //unsigned int port, const char *unix_socket, unsigned long clientflag) 
    18     mysql_real_connect(conn_ptr,"localhost",
    19                                   "rick","secretpassword","rick",
    20                                   0,NULL,0);
    21     if(conn_ptr)
    22     {
    23         printf("connect successfully
    ");
    24         int query_ret = mysql_query(conn_ptr,"SELECT * FROM children;");
    25         if(query_ret == 0)
    26         {
    27             printf("query successful
    ");
    28 
    29             MYSQL_RES* res_ptr = mysql_store_result(conn_ptr);
    30             if(res_ptr)
    31             {
    32                 printf("use result successful
    ");
    33 
    34                 MYSQL_FIELD* field;
    35                 while((field = mysql_fetch_field(res_ptr)))
    36                 {
    37                     printf("%s ",field->name);
    38                 }                                                
    39                 printf("
    ");
    40 
    41                 MYSQL_ROW row;
    42                 unsigned int cols = mysql_field_count(conn_ptr);
    43                 while((row = mysql_fetch_row(res_ptr)) != NULL)
    44                 {
    45                     for(unsigned int i = 0;i < cols;++i)
    46                     {
    47                         printf("%s ",row[i]);
    48                     }
    49                     printf("
    ");
    50                 }
    51             }
    52             else
    53             {
    54                 fprintf(stderr,"use result failed %d : %s
    ",mysql_errno(conn_ptr),mysql_error(conn_ptr));
    55             }
    56             mysql_free_result(res_ptr);
    57         }
    58         else
    59         {
    60             fprintf(stderr,"query failed %d : %s
    ",mysql_errno(conn_ptr),mysql_error(conn_ptr));
    61         }
    62 
    63     }
    64     else
    65     {
    66         printf("connect failed
    ");
    67     }
    68     //void mysql_close(MYSQL *sock)
    69     mysql_close(conn_ptr);
    70     return 0;
    71 }
  • 相关阅读:
    OutputStream 和 Writer
    elasticsearch技术解析与实战(一) 入门和索引
    Kafka Consumer API样例
    关于kafka的新的group无法订阅到topic中历史消息的问题
    apache kafka系列之在zookeeper中存储结构
    KafkaConsumer 长时间地在poll(long )方法中阻塞
    问题记录
    java随笔
    Ubuntu18.10下运行blender2.80bate闪退(问题?)
    linux下简单制作iso,img镜像文件
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/11923311.html
Copyright © 2011-2022 走看看