c++操作数据库

  1. 使用mysql_init()初始化连接
  2. 使用mysql_real_connect()建立一个到mysql数据库的连接
  3. 使用mysql_query()执行查询语句
  4. result = mysql_store_result(mysql)获取结果集
  5. mysql_num_fields(result)获取查询的列数,mysql_num_rows(result)获取结果集的行数
  6. 通过mysql_fetch_row(result)不断获取下一行,然后循环输出
  7. 释放结果集所占内存mysql_free_result(result)
  8. mysql_close(conn)关闭连接

以下代码块是用来连接数据库的通讯过程,要连接MYSQL,必须建立MYSQL实例,通过mysql_init初始化方能开始进行连接.

 

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;

 

这个结构代表返回行的一个查询的(SELECT, SHOW, DESCRIBE, EXPLAIN)的结果。返回的数据称为“数据集”,在C的API里对应的就是MYSQL_RES了,从数据库读取数据,最后就是从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_init

#include <mysql/mysql.h>
MYSQL *mysql_init(MYSQL *mysql)

功能:  获得或初始化一个MYSQL结构

函数返回值: 一个被始化的MYSQL*句柄

备注:  在内存不足的情况下,返回NULL

mysql_close(MYSQL *mysql)

 #include <mysql/mysql.h>
void mysql_close(MYSQL *mysql);

函数功能: 关闭一个服务器连接,并释放与连接相关的内存 

函数传入值: MYSQL:类型的指针

函数返回值: 无

mysql_connect

 #include <mysql/mysql.h>
MYSQL * mysql_connect(MYSQL *mysql,const char *host,const char *user,const char *passwd);

函数功能: 连接一个MySQL服务器

函数传入值: mysql表示一个现存mysql结构的地址   host表示MYSQL服务器的主机名或IP   user表示登录的用户名   passwd表示登录的密码

函数返回值: 如果连接成功,一个MYSQL *连接句柄:如果连接失败,NULL

备注:  该函数不推荐,使用mysql_real_connect()代替

mysql_real_connect

#include <mysql/mysql.h> 
MYSQL  *mysql_real_connect(MYSQL *mysql,const char *host,const char *user,const  char *passwd,const char *db,unsigned int port,const char  *unix_socket,unsigned int client_flag);

函数传入值: mysql表示一个现存mysql结构的地址   host表示MYSQL服务器的主机名或IP   user表示登录的用户名   passwd表示登录的密码   db表示要连接的数据库   port表示MySQL服务器的TCP/IP端口   unix_socket表示连接类型   client_flag表示MySQL运行ODBC数据库的标记

函数返回值: 如果连接成功,一个MYSQL*连接句柄:

如果连接失败,NULL

mysql_affected_rows

 函数功能: 返回最新的UPDATE,DELETE或INSERT查询影响的行数

函数传入值: MYSQL:类型指针

函数返回值: 大于零的一个整数表示受到影响或检索出来的行数。零表示没有区配查序中WHERE子句的记录或目前还没有查询被执行;-1表示查询返回一个错误,或对于一个SELECT查询

mysql_query

 #include <mysql/mysql.h>
int mysql_query(MYSQL *mysql,const char *query);

函数功能: 对指定的连接执行查询

函数传入值: query表示执行的SQL语句

函数返回值: 如果查询成功,为零,出错为非零

相关函数: mysql_real_query

mysql_use_result

 #include <mysql/mysql.h>
MYSQL_RES *mysql_use_result(MYSQL *mysql);

函数功能: 为无缓冲的结果集获得结果标识符 

函数传入值: MYSQL:类型的指针

函数返回值: 一个MYSQL_RES结果结构,如果发生一个错误发NULL

详细参考https://www.cnblogs.com/tianzeng/p/10016943.html

mysql_fetch_row

#incluee <mysql/mysql.h>
mysql_fetch_row(MYSQL_RES *result);

检索一个结果集合的下一行 MYSQL_ROW 

MYSQL_RES:结构的指针 下一行的一个MYSQL_ROW结构。如果没有更多的行可检索或如果出现一个错误,NULL

mysql_num_fields

#include <mysql/mysql.h>
unsigned int mysql_num_fields(MYSQL_RES *res);

返回指定结果集中列的数量MYSQL_RES 结构的指针

结果集合中字段数量的一个无符号整数

mysql_create_db

#include <mysql/mysql.h>
int mysql_create_db(MYSQL *mysql,const char *db);

创建一个数据库

MYSQL:类型的指针 db:要创建的数据库名 如果数据库成功地被创建,返回零,如果发生错误,为非零。

mysql_select_db

#include <mysql/mysql.h>
int mysql_select_db(MYSQL *mysql,const char *db);

选择一个数据库

db:要创建的数据库名 如果数据库成功地被创建,返回零,如果发生错误,为非零。

/*************************************************************************
    > File Name: db.h
    > Author: Chen Tianzeng
    > Mail: 971859774@qq.com 
    > Created Time: 2018年11月25日 星期日 17时21分37秒
 ************************************************************************/

#ifndef DB_H
#define DB_H
#include <iostream>
#include <mysql/mysql.h>
#include <string>
using namespace std;

class Db
{
    private:
        MYSQL *con;
        MYSQL_RES *res;
        MYSQL_ROW row;

    public:
        Db();
        ~Db();
        bool init_db(string host,string user,string pwd,string db_name);
        bool exec(string sql);
};

#endif
/*************************************************************************
    > File Name: db.cpp
    > Author: Chen Tianzeng
    > Mail: 971859774@qq.com 
    > Created Time: 2018年11月25日 星期日 17时25分04秒
 ************************************************************************/

#include "db.h"
using namespace std;

Db::Db()
{
    con=mysql_init(NULL);//初始化链接变量
    if(con==NULL)
    {
        cerr<<"error: "<<mysql_error(con)<<endl;
        exit(1);
    }
}

Db::~Db()
{
    if(con)
        mysql_close(con);
}

bool Db::init_db(string host,string user,string pwd,string db_name)
{
    //用mysql_real_connect建立一个连接
    con=mysql_real_connect(con,host.c_str(),user.c_str(),pwd.c_str(),
                                db_name.c_str(),0,NULL,0);
    if(con==NULL)
    {
        cerr<<"error: "<<mysql_error(con)<<endl;
        exit(1);
    }
    return true;
}

bool Db::exec(string sql)
{
    //执行sql查询语句,成功返回0,失败返回非0
    if(mysql_query(con,sql.c_str()))
    {
        cerr<<"query error: "<<mysql_error(con)<<endl;
        exit(1);
    }
    else
    {
        //获取查询的结果
        res=mysql_store_result(con);
        if(res)
        {
            //返回查询的行数
            for(int i=0;i<mysql_num_rows(res);++i)
            {
                row=mysql_fetch_row(res);
                if(row<0)
                    break;

                //结果集中的字段数
                for(int j=0;j<mysql_num_fields(res);++j)
                    cout<<row[j]<<" ";
                cout<<endl;
            }
        }
        else//res==NULL
        {
            if(mysql_field_count(con)==0)//返回insert update delete 等影响的列数
                int num_rows=mysql_affected_rows(con);
            else
            {
                cout<<"get result error: "<<mysql_error(con)<<endl;
                return false;
            }
        }
    }
    //释放结果集
    mysql_free_result(res);
    return true;
}
/*************************************************************************
    > File Name: main.cpp
    > Author: Chen Tianzeng
    > Mail: 971859774@qq.com 
    > Created Time: 2018年11月25日 星期日 17时39分06秒
 ************************************************************************/

#include "db.h"
using namespace std;

int main()
{
    Db db;
    db.init_db("localhost","root","root","stu");
    db.exec("select * from stu_info");
    //db.exec("insert into stu_info values('000002','hualian','21','1005',100)");
    return 0;
}

 Makefile

CC=g++
OBJS=main.o db.o
EXEC=main
CPPFLAGS=-std=c++11
LIB=-L/usr/lib64 -lmysqlclient
.PHONY:clean

$(EXEC):$(OBJS)
    $(CC) $(OBJS) -o $(EXEC) $(CPPFLAFS) $(LIB)

clean:
    rm -rf $(OBJS)
    rm -rf $(EXEC)

MySQL官方参考文档  https://dev.mysql.com/doc/refman/8.0/en/c-api-functions.html

 

  在使用mysql_query()进行查询时,只能无法进行多次select查询,记录下解决问题办法:

If your program uses CALL statements to execute stored procedures, 
the CLIENT_MULTI_RESULTS flag must be enabled. This is because each 
CALL returns a result to indicate the call status, 
in addition to any result sets that might be returned by statements executed within the procedure. 
Because CALL can return multiple results, process them using a loop that calls mysql_next_result() 

to determine whether there are more results.

bool exec(string sql)
        {
            if(sql.empty())
            {
                cerr<<"sql is empty"<<endl;
                return false;
            }

            if(mysql_query(con,sql.c_str()))
            {
                cerr<<"mysql_query: "<<mysql_error(con)<<endl;
                exit(1);
            }
            else
            {
                do
                {
                    if(mysql_field_count(con)>0)
                    {
                        res=mysql_store_result(con);
                        mysql_free_result(res);
                    }
                }while(!mysql_next_result(con));
            }
            return true;
        }

链接:https://blog.csdn.net/luoti784600/article/details/21532279

 

posted on 2018-11-25 21:23  tianzeng  阅读(10591)  评论(0编辑  收藏  举报

导航