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\n");

     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\n");

return ret;

}

else

{

printf(" ok......\n");

}

 

printf("connect:%d &mysql:%d \n",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\n");

     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\n", ret);

return ret;

}

else

{

printf(" ok......\n");

}

 

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\n");

exit(0);

}

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

{

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

fprintf(stderr, "\n %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\n");

  fprintf(stderr, " %s\n", 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\n", ret);

return ret;

}

//--設置事務手動提交

ret = mysql_query(mysql, SET_TRAN);

if (ret != 0)

{

printf("func mysql_query() err: %d\n", 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\n", ret);

return ret;

}

 

//--恢復事務自動提交標志

ret = mysql_query(mysql, UNSET_TRAN);

if (ret != 0)

{

printf("func mysql_query() err: %d\n", 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\n", ret);

return ret;

}

 

//--恢復自動提交設置

ret = mysql_query(mysql, UNSET_TRAN);

if (ret != 0)

{

printf("func mysql_query() err: %d\n", 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\n");

return ret;

}

else

{

printf(" ok......\n");

}

 

ret = mysql_BeginTran(mysql);

if (ret != 0)

{

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

return ret;

}

ret = mysql_query(mysql, sql01);

if (ret != 0)

{

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

return ret;

}

ret = mysql_query(mysql, sql02);

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;

}

 

 

ret = mysql_BeginTran(mysql);

if (ret != 0)

{

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

return ret;

}

ret = mysql_query(mysql, sql03);

if (ret != 0)

{

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

return ret;

}

ret = mysql_query(mysql, sql04);

if (ret != 0)

{

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

return ret;

}

ret = mysql_Rollback(mysql);

if (ret != 0)

{

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

return ret;

}

 

mysql_close(mysql);

 

}


免責聲明!

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



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