zoukankan      html  css  js  c++  java
  • mysql c api (总结)

    MySQL_C_API编程实践

    1MySQL C API helloWorld

    1.1有关mysqlclient

    C APIs包含在mysqlclient库文件当中,与MySQL的源代码一块发行,用于连接到数据库和执行数据库查询

    1.2helloworld应用程序编写

    int main()

    {

    int ret = NULL;

    MYSQL mysql;

    MYSQL *connect;

    //MYSQL_RES *res;

    //MYSQL_ROW row;

    //char *query;

    //int t, r;

    /*

    if (mysql_library_init(0, NULL, NULL)) {

         fprintf(stderr, "could not initialize MySQL library ");

         exit(1);

       }

       */

    mysql_init(&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)

    */

    /*

    unsigned int mysql_errno(MYSQL *mysql);

    const char *mysql_error(MYSQL *mysql);

    */

    connect = mysql_real_connect(&mysql, "localhost", "root", "123456", "mydb2", 0, NULL, 0 );

    if (connect == NULL)

    {

    ret = mysql_errno(connect);

    printf("func mysql_real_connect() err ");

    return ret;

    }

    else

    {

    printf(" ok...... ");

    }

    printf("connect:%d &mysql:%d ",connect, &mysql );

    mysql_close(connect);

    //mysql_library_end();

    }

    1.3helloworld应用程序调试

    MySQL开发环境熟悉

    q mysq的开发头文件目录为  /usr/include/mysql

    q mysq的开发 动态库

    q gcc -o  dm01_hello dm01_hello.c -I/usr/include/mysql -L/usr/lib64/mysql –lmysqlclient

    q 典型错误1

    /*

    /usr/lib64/mysql/libmysqlclient.a(dso_dlfcn.o): In function `dlfcn_globallookup':

    dso_dlfcn.c:(.text+0x31): undefined reference to `dlopen'

    dso_dlfcn.c:(.text+0x44): undefined reference to `dlsym'

    dso_dlfcn.c:(.text+0x4f): undefined reference to `dlclose'

    //libmysqlclient.a dlfcn_globallookup undefined reference to `dlopen'

    */

    q 典型错误2

    /*

    dm01_hello.c:49: 警告:初始化将指针赋给整数,未作类型转换

    /usr/lib64/mysql/libmysqlclient.a(net_serv.cc.o):(.data.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'

    /usr/lib64/mysql/libmysqlclient.a(password.c.o): In function `scramble_323':

    /pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: undefined reference to `floor'

    /pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: undefined reference to `floor'

    /pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: undefined reference to `floor'

    /pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: undefined reference to `floor'

    /pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: undefined reference to `floor'

    /usr/lib64/mysql/libmysqlclient.a(password.c.o):/pb2/build/sb_0-12734909-1406113305.48/rpm/BUILD/mysqlcom-pro-5.6.20/mysqlcom-pro-5.6.20/sql/password.c:184: more undefined references to `floor' follow

    /usr/lib64/mysql/libmysqlclient.a(my_getsystime.c.o): In function `my_getsystime':

    */

    q 典型错误3

    dm01_hello.c:70: 警告:初始化将指针赋给整数,未作类型转换

    //导致没有链接 libstdc++.so

    /usr/lib64/mysql/libmysqlclient.a(net_serv.cc.o):(.data.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'

    MySQL开发环境GCC写法

    q gcc -o  dm01_hello dm01_hello.c -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -ldl -lpthread -lm -lrt  -lstdc++

    MySQL开发环境makefile写法

    .PHONY:clean all

    CC=gcc

    CFLAGS=-Wall -g

    LFLAGS=-L/usr/lib64/mysql -lmysqlclient -ldl -lpthread -lm -lrt -lstdc++

    BIN=dm01_hello dm02_query

    all:$(BIN)

    %.o:%.c

    $(CC) $(CFLAGS)  -c $<  -o   $@

    dm01_hello:dm01_hello.o

    $(CC) $(CFLAGS) $^  $(LFLAGS) -o  $@

    dm02_query:dm02_query.o

    $(CC) $(CFLAGS) $^  $(LFLAGS) -o  $@

    clean:

    rm -f *.o $(BIN)

     

    2MySQL C API CRUD

    2.1MYSQL C API的常用函数

    数据类型

    n MYSQL

    ü 该结构代表1个数据库连接的句柄。几乎所有的MYSQL函数均使用它。

    n MYSQL_RES

    ü 该结构代表返回行的查询结果

    n MYSQL_ROW

    ü 这是1行数据的”类型安全”表示。

    n MYSQL_FIELD

    ü 该结构包含关于字段的信息,如字段名、类型和大小等

    n MYSQL_FIELD_OFFSET

    ü 这时MYSQL字段列表偏移量的”类型安全”表示

    n my_ulonglong

    ü 用于行数以及mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()的类型

    编程步骤

    n 1  通过调用mysql_library_init(),初始化MYSQL库

    n 2  通过调用mysql_init()初始化连接处理程序,并通过调用mysql_real_connect()连接到服务器

    n 3  发出SQL语句并处理其结果

    n 4  通过调用mysql_close(),关闭与MYSQL服务器的连接

    n 5  通过调用mysql_library_end(),结束MYSQL库的使用

    数据库连接

    n 初始化一个连接句柄结构

       #include <mysql.h>

       MYSQL *mysql_init(MYSQL *);

    n 和数据库建立物理连接

       MYSQL *mysql_real_connect(MYSQL *connection,

      const char *server_host,const char *sql_user_name,

      const char *sql_password,const char *db_name,

      unsigned int port_number,const char   

      *unix_socket_name,unsigned int flags);

    连接参数

    Int mysql_options(MYSQL *connection,enum

      option_to_set,const char *argument)

    错误处理

    n unsigned int mysql_errno(MYSQL *connection);

       对于由mysql指定的连接,该函数返回最近调用的API函数的错误代码,该函数调用可能成功也可能失败。”0”返回值表示未出现错误

    n char *mysql_error(MYSQL *connection)

       如果想获得错误的文本信息,可以调用该函数

    执行SQL语句

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

    n 功能描述:

    ü 执行由”Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号或”g”

    ü 不能用于包含二进制数据的查询,应使用mysql_real_query来完成

    对于操纵语句

    n My_ulonglong mysql_affected_rows(MYSQL *mysql)

       返回上次操纵语句所涉及到记录的行数

    n 对于UPDATE、DELETE或INSERT语句,可在mysql_query()后立刻调用。对于SELECT语句,该函数的工作方式与mysql_num_rows()类似

     

    对于查询语言

    n MYSQL_RES *mysql_store_result(MYSQL *mysql)

    n 功能说明:

    ü 对于成功检索了数据的每个查询,必须调用mysql_store_result()或mysql_use_result()

    ü 该函数将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中

    ü 可以通过mysql_num_rows来找出结果集中的行数

    事务处理

    n my_bool mysql_autocommit(MYSQL *mysql,my_bool mode)

    ü 函数说明:如果模式为1,启动autocommit模式;如果模式为0,禁止autocommit模式

    n my_bool mysql_commit(MYSQL *mysql)

    ü 提交当前事务

    n my_bool mysql_rollback(MYSQL *mysql) 

    ü 回滚当前事务

    处理结果集

    n MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

    n 功能描述

    ü 检索结果集的下一行

    ü 行内值的数目由mysql_num_fields(result)给出

    ü 可以调用mysql_fetch_lengths()来获得行中字段值的长度

    n void mysql_data_seek(MYSQL_RES *result,my_ulonglong offset)

    n 功能描述:

    ü 在查询结果集中寻找任意行。偏移值为行号。

    ü 该函数要求结果集结构包含查询的所有结果

    n MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)

    ü 返回光标的当前位置

    n MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,MYSQL_ROW_OFFSET offset)

    ü 将行光标置于查询结果集中的任意行

    每次接收一行数据

    n MYSQL_RES *mysql_use_result(MYSQL *mysql)

    n 功能说明:

    ü 不像mysql_store_result()那样把结果集实际读取到客户端。它必须通过对mysql_fetch_row()的调用,对每一行分别进行检索。

    ü Mysql_store_result()相比,速度更快而且使用的内存更少

     

    多查询执行的C API处理

    n 支持在单个字符串中指定的多语句的执行。要想与给定的连接一起使用该功能,打开连接时,必须将标志参数中的CLIENT_MULTI_STATEMENTS选项指定给mysql_real_connect()。也可以通过调用mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON),为已有的连接设置它

    详细api列表

    MYSQL *mysql_init(MYSQL *mysql)

    q  分配或初始化与mysql_real_connect()相适应的MYSQL对象。

    q 如果mysqlNULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。

    q 如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时。将释放该对象。

    void mysql_close(MYSQL *mysql) 

    q 关闭前面打开的连接。

    q 如果句柄是由mysql_init()mysql_connect()自动分配的,mysql_close()还将解除分配由mysql指向的连接句柄。

    mysql_real_connect函数

    q 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)

    q 函数功能:尝试与运行在主机上的MySQL数据库引擎建立连接

    q connect = mysql_real_connect(&mysql, "localhost", "root", "123456", "mydb2", 0, NULL, 0 );

    查询api

    mysql_query()函数和mysql_real_query()函数

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

    q int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)

    q 对于包含二进制数据的查询,必须使用mysql_real_query()而不是mysql_query()

    q mysql_real_query()mysql_query()快,这是因为它不会在查询字符串上调用strlen()

    获取结果集api

    mysql_store_result()函数和mysql_use_result

    q MYSQL_RES *mysql_store_result(MYSQL *mysql)

    q mysql_store_result()将查询的全部结果读取到客户端,分配1MYSQL_RES结构,并将结果置于该结构中

    q 可调用mysql_num_rows()来找出结果集中的行数。可以调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()mysql_row_tell()来获取或设置结果集中的当前行位置。

    q 一旦完成了对结果集的操作,必须调用mysql_free_result()

    MYSQL_RES *mysql_use_result(MYSQL *mysql) 每次接收一行数据

    q 功能说明:

    q 不像mysql_store_result()那样把结果集实际读取到客户端。它必须通过对mysql_fetch_row()的调用,对每一行分别进行检索。

    q Mysql_store_result()相比,速度更快而且使用的内存更少

    2.2调用思路分析

    1 简介

    访问MySQL服务器,这需要使用mysqlclient库,MySQL的大多数客户端API(除了

    Java和.NET)都是通过这个库来和MySQL服务器通讯的,而这个库正是用C编写的。

    2代码编写和编译

    3连接MySQL服务器

    初始化一个MYSQL结构,该结构在几乎所有的MySQL C API函数(除了预处理语句相关的函数)中都会用到。MYSQL *mysql_init(MYSQL *mysql)

    连接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);

    也可另一种方式来进行连接。先用MYSQL_READ_DEFAULT_FILE作为选项名来调用mysql_options(), 再调用mysql_real_connect()来连接服务器;

    mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my.cnf")

    mysql_real_connect(*mysql, NULL, NULL, NULL, NULL, 0, NULL, 0)

    说明:my.cnf文件中记录了连接MySQL服务器所需的各项参数(地址,端口,用户名,密

    码,数据库,字符集,Unix Socket等)。这样可以灵活的修改连接参数而不必重新编译程序。

    要关闭连接,则调用mysql_close()

    void mysql_close(MYSQL *mysql)

    4执行查询

    1)调用mysql_query()来执行SQL语句,如果语句中包含二进制数据,则需要调用

    mysql_real_query()

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

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

    2)若执行的是UPDATE, DELETE或INSERT语句,则可通过mysql_affected_rows()获知

    受影响的记录数。my_ulonglong mysql_affected_rows(MYSQL *mysql) 

    还可以通过mysql_insert_id()来获取由最近的UPDATE或INSERT语句生成的自增值。

    my_ulonglong mysql_insert_id(MYSQL *mysql)

    3)若执行的是SELECT语句,则有两种方式来获取结果集。

    3-1)一种方式是通过mysql_store_result()将整个结果集全部取回来。

    MYSQL_RES *mysql_store_result(MYSQL *mysql)

    3-2)另一种方式则是调用mysql_use_result()初始化获取操作,但暂时不取回任何记录。 MYSQL_RES *mysql_use_result(MYSQL *mysql)  

    3-3两种方法均通过mysql_fetch_row()来访问每一条记录。

    MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

    注意:若先前调用的是mysql_store_result(), 则直接在本地访问记录;若先前调用的是mysql_use_result(), 则此时才到服务器上去获取记录。

    4)当处理完结果集后,调用mysql_free_result()来释放它所占的内存。void mysql_free_result(MYSQL_RES *result)。

    5)可调用mysql_errno()和mysql_error()来获知最近执行的API函数的错误代码和错误信息。

    unsigned int mysql_errno(MYSQL *mysql)

    const char *mysql_error(MYSQL *mysql)

    5. 预处理语句(Prepared Statements)

    MySQL C API还提供了另一种方式来执行SQL语句,即先预处理(prepare)再执行

    (execute). 对于多次执行的SQL语句,该方式可以提高其执行效率。具体步骤如下:

    1. 调用mysql_stmt_init()创建语句句柄,该句柄在随后的函数调用中都要用到。

    MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)

    2. 调用mysql_stmt_prepare()对SQL语句进行预处理

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

    3. 如果SQL语句中有参数,则需要调用mysql_stmt_bind_param()进行参数绑定。

    my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)

    如果参数的类型为TEXT或BLOB, 并且数据量很大,可以调用

    mysql_stmt_send_long_data()来向服务器发送数据。

    my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number, const char *data, unsigned long length)

    4. 调用mysql_stmt_execute()来执行查询。

    int mysql_stmt_execute(MYSQL_STMT *stmt)

    5. 若查询不产生结果集,可以调用

    mysql_stmt_affected_rows()和

    my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)来获得被改变的记录数和生成的自增值。

    my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)

    my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)

    否则,执行mysql_stmt_bind_result()对结果集中的字段进行绑定。

    my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)

    6. 调用mysql_stmt_fetch()来逐行获取结果集中的记录。

    int mysql_stmt_fetch(MYSQL_STMT *stmt)

    在调用mysql_stmt_fetch()之前,还可以执行mysql_stmt_store_result()将结果

    集预先缓存到本地。

    int mysql_stmt_store_result(MYSQL_STMT *stmt)

    7. 重复步骤3-6, 每次使用不同的实参来执行查询。

    8. 调用mysql_stmt_close()关闭句柄,释放资源

    my_bool mysql_stmt_close(MYSQL_STMT *)

    此外,可以调用mysql_stmt_errno()和mysql_stmt_error()来获知最近执行的预处

    理语句API函数的错误代码和错误信息。

    unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)

    const char *mysql_stmt_error(MYSQL_STMT *stmt)

    9.其他说明:

    mysql_stmt_execute()中有调用案例

    http://dev.mysql.com/doc/refman/5.1/zh/apis.html#c-api-multiple-queries

    25.2.7.11. mysql_stmt_fetch() 

    2.3 MYSQL C API预处理语句

    参考 2.2节,调用思路分析:5预处理语句(Prepared Statements)

    MySQL客户端/服务器协议提供了预处理语句。该功能采用了由mysql_stmt_init()初始化函数返回的MYSQL_STMT语句处理程序数据结构。对于多次执行的语句,预处理执行是一种有效的方式。首先对语句进行解析,为执行作好准备。接下来,在以后使用初始化函数返回的语句句柄执行一次或多次。

    对于多次执行的语句,预处理执行比直接执行快,主要原因在于,仅对查询执行一次解析操作。在直接执行的情况下,每次执行语句时,均将进行查询。此外,由于每次执行预处理语句时仅需发送参数的数据,从而减少了网络通信量。

    预处理语句的另一个优点是,它采用了二进制协议,从而使得客户端和服务器之间的数据传输更有效率。

    编程步骤

    n 1.  用mysql_stmt_init()创建预处理语句句柄。要想在服务器上准备预处理语句,可调用mysql_stmt_prepare(),并为其传递包含SQL语句的字符串

    n 3.  使用mysql_stmt_bind_param()设置任何参数的值。必须设置所有参数。否则,语句执行将返回错误,或生成无法预料的结果。

    n 4.  调用mysql_stmt_execute()执行语句。

    n 5.  如果语句生成了结果集,捆绑数据缓冲,通过调用mysql_stmt_bind_result(),检索行值。

    n 6.  通过重复调用mysql_stmt_fetch(),按行将数据提取到缓冲区,直至未发现更多行为止。

    n 7.  通过更改参数值并再次执行语句,重复步骤3到步骤6。

    2.4多查询执行的C API处理

    n 支持在单个字符串中指定的多语句的执行。要想与给定的连接一起使用该功能,打开连接时,必须将标志参数中的CLIENT_MULTI_STATEMENTS选项指定给mysql_real_connect()。也可以通过调用mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON),为已有的连接设置它

    /* Connect to server with option CLIENT_MULTI_STATEMENTS */

    mysql_real_connect(..., CLIENT_MULTI_STATEMENTS);

    /* Now execute multiple queries */

    mysql_query(mysql,"DROP TABLE IF EXISTS test_table;

                       CREATE TABLE test_table(id INT);

                       INSERT INTO test_table VALUES(10);

                       UPDATE test_table SET id=20 WHERE id=10;

                       SELECT * FROM test_table;

                       DROP TABLE test_table");

    do

    {

      /* Process all results */

      ...

      printf("total affected rows: %lld", mysql_affected_rows(mysql));

      ...

      if (!(result= mysql_store_result(mysql)))

      {

         printf(stderr, "Got fatal error processing query ");

         exit(1);

      }

      process_result_set(result); /* client function */

      mysql_free_result(result);

    } while (!mysql_next_result(mysql));

    2.5

    二进制协议允许你使用MYSQL_TIME结构发送和接受日期和时间值(DATETIMEDATETIMETIMESTAMP)。在25.2.5节,“C API预处理语句的数据类型”中,介绍了该结构的成员。

    int main()

    {

    int ret = 0, status = 0;

    MYSQL *mysql;

    MYSQL_RES *result;

    mysql =mysql_init(NULL);

    mysql =mysql_real_connect(mysql, "localhost", "root", "123456", "mydb2", 0, NULL, CLIENT_MULTI_STATEMENTS );

    if (mysql == NULL)

    {

    ret = mysql_errno(mysql);

    printf("%s", mysql_error(mysql));

    printf("func mysql_real_connect() err :%d ", ret);

    return ret;

    }

    else

    {

    printf(" ok...... ");

    }

    MYSQL_TIME  ts;

    MYSQL_BIND  bind[3];

    MYSQL_STMT  *stmt;

     //注意:

     // 创建的表语句

     // create table test_table (date_field date,  time_field time,  timestamp_field timestamp );

    char query[1024] = "INSERT INTO test_table(date_field, time_field, timestamp_field) VALUES(?,?,?)";

    stmt = mysql_stmt_init(mysql);

    if (!stmt)

    {

    fprintf(stderr, " mysql_stmt_init(), out of memory ");

    exit(0);

    }

    if (mysql_stmt_prepare(stmt, query, strlen(query)))

    {

    fprintf(stderr, " mysql_stmt_prepare(), INSERT failed");

    fprintf(stderr, " %s", mysql_stmt_error(stmt));

    exit(0);

    }

    /* set up input buffers for all 3 parameters */

    bind[0].buffer_type= MYSQL_TYPE_DATE;

    bind[0].buffer= (char *)&ts;

    bind[0].is_null= 0;

    bind[0].length= 0;

    //

    bind[1]= bind[2]= bind[0];

    //...

    mysql_stmt_bind_param(stmt, bind);

    /* supply the data to be sent in the ts structure */

    ts.year= 2002;

    ts.month= 02;

    ts.day= 03;

    ts.hour= 10;

    ts.minute= 45;

    ts.second= 20;

    mysql_stmt_execute(stmt);

    // Close the statement //

    if (mysql_stmt_close(stmt))

    {

      fprintf(stderr, " failed while closing the statement ");

      fprintf(stderr, " %s ", mysql_stmt_error(stmt));

      exit(0);

    }

      

    mysql_close(mysql);

    }

    2.5事务概念

    /*

    MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过

         set autocommit=0  禁止自动提交

         set autocommit=1 开启自动提交

    mysqlINNODB引擎才支持事务处理,默认是自动提交的;

    另外一种常用的MYISAM引擎是不支持事务的,本身就没有事务的概念

    */

    #define BEGIN_TRAN "START TRANSACTION"

    #define SET_TRAN "SET AUTOCOMMIT=0"  

    #define UNSET_TRAN "SET AUTOCOMMIT=1"

    #define COMMIT_TRAN "COMMIT"

    #define ROLLBACK_TRAN "ROLLBACK"

    int mysql_BeginTran(MYSQL *mysql)

    {

    int ret = 0;

    //--执行事务开始SQL

    ret = mysql_query(mysql, BEGIN_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    //--设置事务手动提交

    ret = mysql_query(mysql, SET_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    return ret;

    }

    int mysql_Rollback(MYSQL *mysql)

    {

    int ret = 0;

    //--事务回滚操作

    ret = mysql_query(mysql, ROLLBACK_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    //--恢复事务自动提交标志

    ret = mysql_query(mysql, UNSET_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    return ret;

    }

    int mysql_Commit(MYSQL *mysql)

    {

    int ret = 0;

    //--执行事务提交SQL

    ret = mysql_query(mysql, COMMIT_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    //--恢复自动提交设置

    ret = mysql_query(mysql, UNSET_TRAN);

    if (ret != 0)

    {

    printf("func mysql_query() err: %d ", ret);

    return ret;

    }

    return ret;

    }

    #define sql01 "INSERT INTO test_table(col1,col2,col3) VALUES(10, '10', '1')"

    #define sql02 "INSERT INTO test_table(col1,col2,col3) VALUES(20, '20', '2')"

    #define sql03 "INSERT INTO test_table(col1,col2,col3) VALUES(30, '30', '3')"

    #define sql04 "INSERT INTO test_table(col1,col2,col3) VALUES(40, '40', '4')"

    int main(void)

    {

    int ret = NULL;

    MYSQL *mysql;

    MYSQL_RES *res;

    MYSQL_ROW row;

    char *query;

    mysql = mysql_init(NULL);

    mysql =mysql_real_connect(mysql, "localhost", "root", "123456", "mydb2", 0, NULL, 0 );

    if (mysql == NULL)

    {

    ret = mysql_errno(mysql);

    printf("func mysql_real_connect() err ");

    return ret;

    }

    else

    {

    printf(" ok...... ");

    }

    ret = mysql_BeginTran(mysql);

    if (ret != 0)

    {

    printf("mysql_BeginTran() err:%d ", ret);

    return ret;

    }

    ret = mysql_query(mysql, sql01);

    if (ret != 0)

    {

    printf("mysql_query() err:%d ", ret);

    return ret;

    }

    ret = mysql_query(mysql, sql02);

    if (ret != 0)

    {

    printf("mysql_query() err:%d ", ret);

    return ret;

    }

    ret = mysql_Commit(mysql);

    if (ret != 0)

    {

    printf("mysql_Commit() err:%d ", ret);

    return ret;

    }

    ret = mysql_BeginTran(mysql);

    if (ret != 0)

    {

    printf("mysql_BeginTran() err:%d ", ret);

    return ret;

    }

    ret = mysql_query(mysql, sql03);

    if (ret != 0)

    {

    printf("mysql_query() err:%d ", ret);

    return ret;

    }

    ret = mysql_query(mysql, sql04);

    if (ret != 0)

    {

    printf("mysql_query() err:%d ", ret);

    return ret;

    }

    ret = mysql_Rollback(mysql);

    if (ret != 0)

    {

    printf("mysql_Rollback() err:%d ", ret);

    return ret;

    }

    mysql_close(mysql);

    }

  • 相关阅读:
    C语言:链表实现的一个实例
    第二次作业——C++学习
    第二次作业———“A+B Format”思路与总结
    hdu 2962 Trucking (二分+最短路Spfa)
    hdu 2680 Choose the best route (dijkstra算法 最短路问题)
    hdu 1233 还是畅通工程 (最小生成树)
    poj 2253 Frogger (dijkstra最短路)
    poj 1062 昂贵的聘礼 (dijkstra最短路)
    hdu 2066 一个人的旅行
    poj 2387 Til the Cows Come Home(dijkstra算法)
  • 原文地址:https://www.cnblogs.com/bwbfight/p/11057607.html
Copyright © 2011-2022 走看看