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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM