Mysql数据库的api介绍

来源:互联网 发布:什么相机软件最好 编辑:程序博客网 时间:2024/06/14 08:44

链接的流程图

这里写图片描述

一,API介绍

1,初始化函数

MYSQL *mysql_init(MYSQL *mysql)

mysql 可以传 NULL

返回 分配的句柄 MYSQL*指针

2,连接到mysql数据库

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 long client_flag)

参数介绍

  1. mysql 初始化的句柄指针
  2. host 主机地址
  3. user 用户名 – mysql数据库 root
  4. passwd 用户的密码
  5. db 要连接的数据库
  6. port 端口 一般填0,mysql默认端口 3306
  7. unix_socket 本地套接字 ,一般填NULL
  8. client_flag 连接标志 一般填0

返回值: 成功返回 连接句柄,失败返回 NULL

3,设定登陆的字符集 – 登陆之后

int mysql_set_character_set(MYSQL *mysql, char *csname)

参数:

  1. mysql 连接句柄
  2. csname 字符集的名称 utf8

4,query功能非常强大 增删改查都可以

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

参数介绍:

  1. mysql 连接句柄
  2. query 执行的sql

返回值:

成功 返回 0失败 返回 非0

5,获得结果集的函数

MYSQL_RES *mysql_store_result(MYSQL *mysql)

返回值: 如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()是否返回非空字符串,mysql_errno()是否返回非0值,或mysql_field_count()是否返回0,可以检查是否出现了错误。

6,释放结果集

void mysql_free_result(MYSQL_RES *result)

7,获取查询的显示列的长度

unsigned int mysql_num_fields(MYSQL_RES *result)

描述

返回结果集中的行数。

注意,你可以从指向结果集的指针或指向连接句柄的指针获得行数。如果mysql_store_result()或mysql_use_result()返回NULL,应使用连接句柄(因而没有结果集指针)。在该情况下,可调用mysql_field_count()来判断mysql_store_result()是否生成了非空结果。这样,客户端程序就能采取恰当的行动,而不需要知道查询是否是SELECT语句(或类似SELECT的语句)。在下面的示例中,介绍了执行该操作的方式。

8,获取列信息

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

描述

返回采用MYSQL_FIELD结构的结果集的列。重复调用该函数,以检索关于结果集中所有列的信息。未剩余字段时,mysql_fetch_field()返回NULL。

每次执行新的SELECT查询时,将复位mysql_fetch_field(),以返回关于第1个字段的信息。调用mysql_field_seek()也会影响mysql_fetch_field()返回的字段。

如果调用了mysql_query()以在表上执行SELECT,但未调用mysql_store_result(),如果调用了mysql_fetch_field()以请求BLOB字段的长度,MySQL将返回默认的Blob长度(8KB)。之所以选择8KB是因为MySQL不知道BLOB的最大长度。应在日后使其成为可配置的。一旦检索了结果集,field->max_length将包含特定查询中该列的最大值的长度。

返回值

当前列的MYSQL_FIELD结构。如果未剩余任何列,返回NULL。

9,取出一行信息

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

描述

检索结果集的下一行。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。

行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],访问这些值的指针。行中的NULL值由NULL指针指明。

可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,字段为NULL,否则字段为空。

返回值

下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。

10,显示受影响的行数

my_ulonglong mysql_affected_rows(MYSQL *mysql)

描述

返回上次UPDATE更改的行数,上次DELETE删除的行数,或上次INSERT语句插入的行数。对于UPDATE、DELETE或INSERT语句,可在mysql_query()后立刻调用。对于SELECT语句,mysql_affected_rows()的工作方式与mysql_num_rows()类似。

返回值

大于0的整数表明受影响或检索的行数。“0”表示UPDATE语句未更新记录,在查询中没有与WHERE匹配的行,或未执行查询。“-1”表示查询返回错误,或者,对于SELECT查询,在调用mysql_store_result()之前调用了mysql_affected_rows()。由于mysql_affected_rows()返回无符号值,通过比较返回值和“(my_ulonglong)-1”或等效的“(my_ulonglong)~0”,检查是否为“-1”。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <mysql.h>#include <unistd.h>#define _USER_ "root" //用户名#define _HOST_ "127.0.0.1" //host#define _PASSWD_ "123"   //root 用户名密码#define _DB_ "scott" //库名#define _PORT_ 3306  //port//打印信息   结果集void show_information(MYSQL_RES * res, MYSQL *mysql){    int i;    MYSQL_ROW row; //    //unsigned long *lengths;    unsigned int num_fields;    MYSQL_FIELD *field; //字段名    // 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result)     num_fields = mysql_num_fields(res);    //返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result)     //lengths  = mysql_fetch_lengths(res);    printf("num_fields = [%d]\n", num_fields);    //字段名    for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {                 printf(" %s\t", field->name);    }    printf("\n");    printf("--------------------------------------------------------------\n");    while ((row = mysql_fetch_row(res))) {            for (i = 0; i < num_fields; i++) {                        printf("%s \t", row[i] ? row[i] : NULL);            }            printf("\n");    }    //释放结果集    mysql_free_result(res);    printf("--------------------------------------------------------------\n");    //显示受影响的行数    printf("  %ld rows in set\n", (long) mysql_affected_rows(mysql));   }int main(int argc, char *argv[]){    int ret, i;    MYSQL *mysql;    MYSQL_RES * res;    char strsql[512] = { 0};    //1,mysql_init 初始化    mysql = mysql_init(NULL);    if (mysql == NULL) {        printf("mysql_init error\n");        return -1;    }    //2,mysql_real_connect链接    mysql = mysql_real_connect(mysql,     _HOST_,     _USER_,     _PASSWD_,     _DB_,     0,     NULL,     0);    if (mysql == NULL) {        printf("mysql_real_connect error\n");        return -1;    }    printf("connect mysql ok\n");    //处理字符问题的函数    if ( mysql_set_character_set(mysql, "utf8") != 0) {        printf(" mysql_set_character_set error\n");        mysql_close(mysql);        exit(1);    }     //===========================输入sql语句======================    while (1) {            memset(strsql, 0x00, sizeof(strsql));            write(STDOUT_FILENO, "yoursql>", 8);            //读取client输入的sql字符串            read(STDIN_FILENO, strsql, sizeof(strsql));            //退出的处理            if (strncasecmp(strsql, "quit", 4) == 0) {                    printf("client 退出处理\n");                    break;              }           //输入sql的        ret = mysql_query(mysql, strsql);        if (ret) {            printf("mysql_query error\n");            continue;        }        res = mysql_store_result(mysql);            //有结果集的处理        if (res != NULL) {            show_information(res, mysql);        }        else {            //显示受影响的行数            printf(" Query OK, %ld row affected\n",(long) mysql_affected_rows(mysql));          }    }//  char sqlstr[] = "select *from emp";//  //查询语句int mysql_query(MYSQL *mysql, const char *query) //  ret = mysql_query(mysql, sqlstr);//  if (ret) {//      printf("mysql_query error\n");//      return -1;  //  }//  //  //查询的结果集MYSQL_RES *mysql_store_result(MYSQL *mysql) //  res = mysql_store_result(mysql);    //MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) //  if ( res != NULL) {//      show_information(res);//          // 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result) //          num_fields = mysql_num_fields(res);//          //返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result) //          //lengths  = mysql_fetch_lengths(res);//          printf("num_fields = [%d]\n", num_fields);//          //字段名//          for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {//                       printf(" %s\t", field->name);//          }//          printf("\n");//          while (row = mysql_fetch_row(res)) {//              //              for (i = 0; i < num_fields; i++) {//                          printf("%s \t", row[i]);//              }//              printf("\n");//          }//              //释放结果集//       mysql_free_result(res);//  }    //关闭mysql    mysql_close(mysql);         return 0;}

这里写图片描述

二,SQL预处理 防止注入和增加效率

1,插入预处理

流程图

这里写图片描述

这里写图片描述

原理
这里写图片描述

①api介绍
1,预处理初始化

MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)

描述

创建MYSQL_STMT句柄。对于该句柄,应使用mysql_stmt_close(MYSQL_STMT *)释放。

返回值

成功时,返回指向MYSQL_STMT结构的指针。如果内存溢出,返回NULL。

2,插入预处理语句

int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length)

描述

给定mysql_stmt_init()返回的语句句柄,准备字符串查询指向的SQL语句,并返回状态值。字符串长度应由“length”参量给出。字符串必须包含1条SQL语句。不应为语句添加终结用分号(‘;’)或\g。

通过将问号字符“?”嵌入到SQL字符串的恰当位置,应用程序可包含SQL语句中的一个或多个参数标记符。

标记符仅在SQL语句中的特定位置时才是合法的。例如,它可以在INSERT语句的VALUES()列表中(为行指定列值),或与WHERE子句中某列的比较部分(用以指定比较值)。但是,对于ID(例如表名或列名),不允许使用它们,不允许指定二进制操作符(如等于号“=”)的操作数。后一个限制是有必要的,原因在于,无法确定参数类型。一般而言,参数仅在DML(数据操作语言)语句中才是合法的,在DDL(数据定义语言)语句中不合法。

执行语句之前,必须使用mysql_stmt_bind_param(),将参数标记符与应用程序变量绑定在一起。

返回值

如果成功处理了语句,返回0。如果出现错误,返回非0值。

3,获取参数

unsigned long mysql_stmt_param_count(MYSQL_STMT *stmt)

描述

返回预处理语句中参数标记符的数目。

返回值

表示语句中参数数目的无符号长整数。

4,参数的绑定

my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

描述

mysql_stmt_bind_param()用于为SQL语句中的参数标记符绑定数据,以传递给mysql_stmt_prepare()。它使用MYSQL_BIND结构来提供数据。“bind”是MYSQL_BIND结构的某一数组的地址。按照客户端库的预期,对于查询中出现的每个“?”参数标记符,数组中均包含1个元素。

假定你准备了下述语句:

INSERT INTO mytbl VALUES(?,?,?)
绑定参数时,MYSQL_BIND结构的数组包含3个元素,并能声明如下:

MYSQL_BIND bind[3];

5,预处理执行

int mysql_stmt_execute(MYSQL_STMT *stmt)

描述

mysql_stmt_execute()执行与语句句柄相关的预处理查询。在该调用期间,将当前绑定的参数标记符的值发送到服务器,服务器用新提供的数据替换标记符。

如果语句是UPDATE、DELETE或INSERT,通过调用mysql_stmt_affected_rows(),可发现更改、删除或插入的总行数。如果这是诸如SELECT等能生成结果集的语句,调用任何其他能导致查询处理的函数之前,必须调用mysql_stmt_fetch()来获取数据。关于如何获取结果的更多信息,请参见25.2.7.11节,“mysql_stmt_fetch()”。

对于生成结果集的语句,执行语句之前,可通过调用mysql_stmt_attr_set(),请求mysql_stmt_execute()为语句打开光标。如果多次执行某一语句,在打开新的光标前,mysql_stmt_execute()将关闭任何已打开的光标。

返回值

如果执行成功,返回0。如果出现错误,返回非0值。

6,返回预处理的行数

my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)

描述

返回上次执行语句更改、删除或插入的总行数。对于UPDATE、DELETE或INSERT语句,可在mysql_stmt_execute()之后立刻调用它们。对于SELECT语句,mysql_stmt_affected_rows()的工作方式类似于mysql_num_rows()。

返回值

大于0的整数指明了受影响或检索的行数。对于UPDATE语句,“0”表明未更新任何记录,在查询中没有与WHERE子句匹配的行,或尚未执行任何查询。“-1”表明返回了错误,或对SELECT查询,在调用mysql_stmt_store_result()之前调用了mysql_stmt_affected_rows()。由于mysql_stmt_affected_rows()返回无符号值,可通过比较返回值和“(my_ulonglong)-1”(或等效的“(my_ulonglong)~0”),检查“-1”。

//预处理方式api处理 -- insert #include <stdio.h>#include "mysql.h"#include <stdlib.h>#include <string.h>#define _HOST_ "localhost"  //主机#define _USER_ "root"       //mysql用户,非主机#define _PASSWD_ "123"   //密码#define _DBNAME_ "scott"    //库名#define STRING_SIZE 50#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"  // if EXISTS 好处 是如果表不存在,执行不会报错#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\                                                 col2 VARCHAR(40),\                                                 col3 SMALLINT,\                                                 col4 TIMESTAMP)"#define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"void prepare_insert(MYSQL *mysql);int main(){    //1.初始化    MYSQL * mysql = NULL;    mysql = mysql_init(NULL) ;    if(mysql == NULL )    {        printf("mysql init err\n");        exit(1);    }    //2.连接    mysql = mysql_real_connect(mysql, _HOST_,_USER_, _PASSWD_,_DBNAME_, 0, NULL,0);    if(mysql == NULL)    {        printf("mysql_real_connect connect err\n");        exit(1);    }    printf("welcome to mysql \n");    prepare_insert(mysql);    //3.关闭    mysql_close(mysql);    return 0;}void prepare_insert(MYSQL *mysql){    MYSQL_STMT    *stmt;//预处理的句柄 -- 标识进程内唯一的一个预处理的sql    MYSQL_BIND    bind[3];//绑定变量     my_ulonglong  affected_rows;    int           param_count;    short         small_data;    int           int_data;    char          str_data[STRING_SIZE];    unsigned long str_length;    my_bool       is_null;    if (mysql_query(mysql, DROP_SAMPLE_TABLE))//删除表    {      fprintf(stderr, " DROP TABLE failed\n");      fprintf(stderr, " %s\n", mysql_error(mysql));      exit(0);    }    if (mysql_query(mysql, CREATE_SAMPLE_TABLE))//创建表    {      fprintf(stderr, " CREATE TABLE failed\n");      fprintf(stderr, " %s\n", mysql_error(mysql));      exit(0);    }    /* Prepare an INSERT query with 3 parameters */    /* (the TIMESTAMP column is not named; the server */    /*  sets it to the current date and time) */    stmt = mysql_stmt_init(mysql); //预处理的初始化    if (!stmt)    {      fprintf(stderr, " mysql_stmt_init(), out of memory\n");      exit(0);    }    if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE))) //insert 语句 的预处理     {      fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));      exit(0);    }    fprintf(stdout, " prepare, INSERT successful\n");    /* Get the parameter count from the statement */    param_count= mysql_stmt_param_count(stmt);//获得参数个数     fprintf(stdout, " total parameters in INSERT: %d\n", param_count);    if (param_count != 3) /* validate parameter count */    {      fprintf(stderr, " invalid parameter count returned by MySQL\n");      exit(0);    }    /* Bind the data for all 3 parameters */    memset(bind, 0, sizeof(bind));    /* INTEGER PARAM */    /* This is a number type, so there is no need to specify buffer_length */    bind[0].buffer_type= MYSQL_TYPE_LONG;//对应int类型    bind[0].buffer= (char *)&int_data;//内存地址的映射     bind[0].is_null= 0;    bind[0].length= 0;    /* STRING PARAM */    bind[1].buffer_type= MYSQL_TYPE_STRING;    bind[1].buffer= (char *)str_data;//char 100     bind[1].buffer_length= STRING_SIZE;    bind[1].is_null= 0;    bind[1].length= &str_length;    /* SMALLINT PARAM */    bind[2].buffer_type= MYSQL_TYPE_SHORT;    bind[2].buffer= (char *)&small_data;    bind[2].is_null= &is_null;//是否为null的指示器     bind[2].length= 0;    /* Bind the buffers */    if (mysql_stmt_bind_param(stmt, bind)) //绑定变量 参数绑定    {      fprintf(stderr, " mysql_stmt_bind_param() failed\n");      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));      exit(0);    }    //第一波赋值     int_data= 10;             /* integer */    strncpy(str_data, "MySQL", STRING_SIZE); /* string  */    str_length= strlen(str_data);    //INSERT INTO test_table(col1,col2,col3) VALUES(10,'MySQL',null)    /* INSERT SMALLINT data as NULL */    is_null= 1;//指示插入的第三个字段是否为null     //insert into test_table(col1,col2,col3) values(10,'MySQL',null);    /* Execute the INSERT statement - 1*/    if (mysql_stmt_execute(stmt)) //预处理的执行,第一次执行     {      fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));      exit(0);    }    /* Get the total number of affected rows */    affected_rows= mysql_stmt_affected_rows(stmt);//预处理的影响条数    fprintf(stdout, " total affected rows(insert 1): %lu\n",                    (unsigned long) affected_rows);    if (affected_rows != 1) /* validate affected rows */    {      fprintf(stderr, " invalid affected rows by MySQL\n");      exit(0);    }    //第二波赋值     int_data= 1000;    strncpy(str_data, "The most popular Open Source database", STRING_SIZE);    str_length= strlen(str_data);    small_data= 1000;         /* smallint */    is_null= 1;               /* reset */    //INSERT INTO test_table(col1,col2,col3) VALUES(1000,'The most popular Open Source database',1000)    //insert into test_table(col1,col2,col3) values(1000,'The most popular Open Source database',1000);    /* Execute the INSERT statement - 2*/    if (mysql_stmt_execute(stmt))//第二次执行    {      fprintf(stderr, " mysql_stmt_execute, 2 failed\n");      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));      exit(0);    }    /* Get the total rows affected */    affected_rows= mysql_stmt_affected_rows(stmt);    fprintf(stdout, " total affected rows(insert 2): %lu\n",                    (unsigned long) affected_rows);    if (affected_rows != 1) /* validate affected rows */    {      fprintf(stderr, " invalid affected rows by MySQL\n");      exit(0);    }    /* Close the statement */    if (mysql_stmt_close(stmt))    {      fprintf(stderr, " failed while closing the statement\n");      fprintf(stderr, " %s\n", mysql_stmt_error(stmt));      exit(0);    }}

2, 查询预处理

流程图
这里写图片描述

api介绍

MYSQL_RES *mysql_stmt_param_metadata(MYSQL_STMT *stmt)

提前指定结果集的操作

//select *from dept; 查询语句的使用#include <stdio.h>#include <stdlib.h>#include <string.h>#include <mysql.h>#define _USER_ "root" //用户名#define _HOST_ "127.0.0.1" //host#define _PASSWD_ "123"   //root 用户名密码#define _DB_ "scott" //库名#define _PORT_ 3306  //port//============================stmt ======================================#define STRING_SIZE 50//mysql 查询语句#define SELECT_SAMPLE "SELECT deptno, dname, loc FROM dept"void seach_information(MYSQL *mysql){        int                     i, count = 0;;        MYSQL_STMT    *stmt;     //        MYSQL_BIND    bind[3];   //条件变量        MYSQL_RES *prepare_meta_result; //结果集        unsigned long length[3];        int           param_count, column_count, row_count;        int           int_data;  //序号        char            str_name[STRING_SIZE]; //姓名        char          str_loc[STRING_SIZE];        my_bool       is_null[3];     //参数的控制        my_ulonglong  row_unm;        //===========================init start=========================        //初始化sql预处理语句        stmt = mysql_stmt_init(mysql);        if (!stmt)        {          fprintf(stderr, " mysql_stmt_init(), out of memory\n");          exit(0);        }        //绑定参数my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)         //mysql_stmt_bind_param(stmt, bind);        if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))        {          fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");          fprintf(stderr, " %s\n", mysql_stmt_error(stmt));          exit(0);        }        fprintf(stdout, " prepare, SELECT successful\n");        fprintf(stdout, " total parameters in SELECT: %d\n", param_count);        param_count = mysql_stmt_param_count(stmt);        if (param_count != 0) /* validate parameter count */        {          fprintf(stderr, " invalid parameter count returned by MySQL\n");          exit(0);        }        prepare_meta_result = mysql_stmt_result_metadata(stmt);        if (!prepare_meta_result)        {          fprintf(stderr,                 " mysql_stmt_result_metadata(), returned no meta information\n");          fprintf(stderr, " %s\n", mysql_stmt_error(stmt));          exit(0);        }        column_count= mysql_num_fields(prepare_meta_result);        fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);        if (column_count != 3) /* validate column count */        {          fprintf(stderr, " invalid column count returned by MySQL\n");          exit(0);        }        //mysql_stmt_execute(stmt); //发送占位符到mysql数据库上????        if (mysql_stmt_execute(stmt))        {          fprintf(stderr, " mysql_stmt_execute(), failed\n");          fprintf(stderr, " %s\n", mysql_stmt_error(stmt));          exit(0);        }        //初始化参数           memset(bind, 0, sizeof(bind));            /* INTEGER COLUMN */        bind[0].buffer_type= MYSQL_TYPE_LONG;        bind[0].buffer= (char *)&int_data;        bind[0].is_null= &is_null[0];        bind[0].length= &length[0];        //varchar    -- MYSQL_TYPE_VAR_STRING        /* name COLUMN */        bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;        bind[1].buffer= (char *)str_name;        bind[1].buffer_length = STRING_SIZE;        bind[1].is_null = &is_null[1];        bind[1].length = &length[1];        /* loc COLUMN */        bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;        bind[2].buffer= (char *)&str_loc;        bind[2].buffer_length = STRING_SIZE;        bind[2].is_null = &is_null[2];        bind[2].length = &length[2];        //绑定数据        mysql_stmt_bind_result(stmt, bind);        mysql_stmt_store_result(stmt);//        //init row        row_count= 0;        //查询的结果        row_unm = mysql_stmt_num_rows(stmt);             //打印数据        //mysql_stmt_fetch(stmt);        //mysql_stmt_fetch(stmt);        printf("row_unm = %ld\n", row_unm);        for (i = 0; i < row_unm; i++)        {            mysql_stmt_fetch(stmt);          row_count++;          fprintf(stdout, "  row %d\n", row_count);          /* column 1 */          fprintf(stdout, "   column1 (integer)  : ");          if (is_null[0])                    fprintf(stdout, " NULL\n");          else                    fprintf(stdout, " %d(%ld)\n", int_data, length[0]);          /* column 2 */          fprintf(stdout, "   column2 (string)   : ");          if (is_null[1])                    fprintf(stdout, " NULL\n");          else                    fprintf(stdout, " %s(%ld)\n", str_name, length[1]);          /* column 3 */          fprintf(stdout, "   column3 (string) : ");          if (is_null[2])                    fprintf(stdout, " NULL\n");          else                    fprintf(stdout, " %s(%ld)\n", str_loc, length[2]);          fprintf(stdout, "\n");          //break;        }        //释放内存        /* Validate rows fetched */        if (row_count != 10)        {          fprintf(stderr, " MySQL failed to return all rows\n");          exit(0);        }        /* Free the prepared result metadata */        mysql_free_result(prepare_meta_result);        /* Close the statement */        mysql_stmt_close(stmt);}//=====================================================================int main(int argc, char *argv[]){    int ret, i;    MYSQL *mysql;    MYSQL_RES * res;    MYSQL_ROW row; //    //unsigned long *lengths;    unsigned int num_fields;    MYSQL_FIELD *field; //字段名    //1,mysql_init 初始化    mysql = mysql_init(NULL);    if (mysql == NULL) {        printf("mysql_init error\n");        return -1;    }    //2,mysql_real_connect链接    mysql = mysql_real_connect(mysql,     _HOST_,     _USER_,     _PASSWD_,     _DB_,     0,     NULL,     0);    if (mysql == NULL) {        printf("mysql_real_connect error\n");        return -1;    }    printf("connect mysql ok\n");        //设置一下字符编码utf8        if (mysql_set_character_set(mysql, "utf8")) {                printf("    mysql_set_character_set error\n");                return -1;        }        seach_information(mysql);//  char sqlstr[] = "select *from emp";//  //查询语句int mysql_query(MYSQL *mysql, const char *query) //  ret = mysql_query(mysql, sqlstr);//  if (ret) {//      printf("mysql_query error\n");//      return -1;  //  }//  //  //查询的结果集MYSQL_RES *mysql_store_result(MYSQL *mysql) //  res = mysql_store_result(mysql);////  //MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) //  if ( res != NULL) {//          // 数据的长度unsigned int mysql_num_fields(MYSQL_RES *result) //          num_fields = mysql_num_fields(res);//          //返回列长unsigned long *mysql_fetch_lengths(MYSQL_RES *result) //          //lengths  = mysql_fetch_lengths(res);//          printf("num_fields = [%d]\n", num_fields);//          //字段名//          for (i = 0; i < num_fields, field = mysql_fetch_field(res); i++) {//                       printf(" %s\t", field->name);//          }//          printf("\n");//          while (row = mysql_fetch_row(res)) {//              //              for (i = 0; i < num_fields; i++) {//                          printf("%s \t", row[i]);//              }//              printf("\n");//          }//              //释放结果集//       mysql_free_result(res);//  }    //关闭mysql    mysql_close(mysql);         return 0;}

这里写图片描述

事物的介绍

//mysql中的事务#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mysql.h"#define SET_TRAN    "SET AUTOCOMMIT=0"          //手动commit  ————手动commit#define UNSET_TRAN  "SET AUTOCOMMIT=1"          //自动commit#define _HOST_ "127.0.0.1"#define _USER_ "root"#define _PASSWD_ "123"#define _DBNAME_ "scott"//设置事务为手动提交int mysql_OperationTran(MYSQL *mysql)           {    //--开启事务    int ret = mysql_query(mysql, "start transaction");  //开启一次事务 start transaction    if (ret != 0) {        printf("mysql_OperationTran query start err: %s\n", mysql_error(mysql));        return ret;    }    //--设置事务为手动提交    ret = mysql_query(mysql, SET_TRAN);         //set autocommmit = 0    if (ret != 0) {        printf("mysql_OperationTran query set err: %s\n", mysql_error(mysql));        return ret;    }    return ret;}//设置事务为自动提交int mysql_AutoTran(MYSQL *mysql){    //--开启事务    int ret = mysql_query(mysql, "start transaction");      if (ret != 0) {        printf("mysql_AutoTran query start err: %s\n", mysql_error(mysql));        return ret;    }    //--设置事务为自动提交    ret = mysql_query(mysql, UNSET_TRAN);  //"set autocommit = 1"    if (ret != 0) {        printf("mysql_AutoTran query set err: %s\n", mysql_error(mysql));        return ret;    }    return ret;     }//执行commit,手动提交事务int mysql_Commit(MYSQL *mysql){    int ret = mysql_query(mysql, "COMMIT"); //提交    if (ret != 0) {        printf("commit err: %s\n", mysql_error(mysql));        return ret;    }    return ret;}//执行rollback,回滚事务       int mysql_Rollback(MYSQL *mysql){    int ret = mysql_query(mysql, "ROLLBACK");    if (ret != 0) {        printf("rollback err: %s\n", mysql_error(mysql));        return ret;    }    return ret;}#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\                                                 col2 VARCHAR(10),\                                                 col3 VARCHAR(10))"#define sql01 "INSERT INTO test_table(col1,col2,col3) VALUES(10, 'AAA', 'A1')"#define sql02 "INSERT INTO test_table(col1,col2,col3) VALUES(20, 'BBB', 'B2')"#define sql03 "INSERT INTO test_table(col1,col2,col3) VALUES(30, 'CCC', 'C3')"#define sql04 "INSERT INTO test_table(col1,col2,col3) VALUES(40, 'DDD', 'D4')"int main(void){    int ret = 0;    MYSQL *mysql = mysql_init(NULL);    mysql = mysql_real_connect(mysql, _HOST_, _USER_, _PASSWD_, _DBNAME_, 0, NULL, 0);    if (mysql == NULL) {        ret = mysql_errno(mysql);        printf("func mysql_real_connect() err:%d\n", ret);        return ret;    }       printf(" --- connect ok......\n");      //执行删除表    if (mysql_query(mysql, DROP_SAMPLE_TABLE)) {      fprintf(stderr, " DROP TABLE failed\n");      fprintf(stderr, " %s\n", mysql_error(mysql));      exit(0);    }    //执行创建表    if (mysql_query(mysql, CREATE_SAMPLE_TABLE)) {      fprintf(stderr, " CREATE TABLE failed\n");      fprintf(stderr, " %s\n", mysql_error(mysql));      exit(0);    }       ret = mysql_OperationTran(mysql);   //开启事务,并修改事务属性为手动commit     if (ret != 0) {        printf("mysql_OperationTran() err:%d\n", ret);        return ret;    }    ret = mysql_query(mysql, sql01);    //向表中插入第一行数据 ‘AAA’    if (ret != 0) {        printf("mysql_query() err:%d\n", ret);        return ret;    }    ret = mysql_query(mysql, sql02);    //向表中插入第二行数据 ‘BBB’    if (ret != 0) {        printf("mysql_query() err:%d\n", ret);        return ret;    }    ret = mysql_Commit(mysql);          //手动提交事务    if (ret != 0) {        printf("mysql_Commit() err:%d\n", ret);        return ret;    }    //////////AAA BBB  进去了。#if 1    ret = mysql_AutoTran(mysql);        // =再次= 修改事务属性为【自动】commit    if (ret != 0) {        printf("mysql_OperationTran() err:%d\n", ret);        return ret;    }#else     ret = mysql_OperationTran(mysql);   // =再次= 修改事务属性为【手动】commit    if (ret != 0) {        printf("mysql_OperationTran() err:%d\n", ret);        return ret;    }#endif    ret = mysql_query(mysql, sql03);    //向表中插入第三行数据 ‘CCC’    if (ret != 0) {        printf("mysql_query() err:%d\n", ret);        return ret;    }    ret = mysql_query(mysql, sql04);    //向表中插入第四行数据 ‘DDD’    if (ret != 0) {        printf("mysql_query() err:%d\n", ret);        return ret;    }    ret = mysql_Rollback(mysql);        //直接rollback操作    if (ret != 0) {        printf("mysql_Rollback() err:%d\n", ret);        return ret;    }    //rollback操作是否能回退掉CCC、DDD的值,取决于事务属性。    mysql_close(mysql);    return 0;   }