MySQL_C_API編程實踐html
C APIs包含在mysqlclient庫文件當中,與MySQL的源代碼一塊發行,用於鏈接到數據庫和執行數據庫查詢mysql |
int main()c++ {sql int ret = NULL;數據庫
MYSQL mysql;編程 MYSQL *connect;api //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(); } |
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++ q |
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)
|
數據類型
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 若是mysql是NULL指針,該函數將分配、初始化、並返回新對象。不然,將初始化對象,並返回對象的地址。 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()將查詢的所有結果讀取到客戶端,分配1個MYSQL_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()相比,速度更快並且使用的內存更少 |
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.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。
|
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結構發送和接受日期和時間值(DATE、TIME、DATETIME和TIMESTAMP)。在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); } |
/* MYSQL默認是自動提交的,也就是你提交一個QUERY,它就直接執行!咱們能夠經過 set autocommit=0 禁止自動提交 set autocommit=1 開啓自動提交 mysql中INNODB引擎才支持事務處理,默認是自動提交的; 另一種經常使用的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);
} |