要進行linux下的mysql的C編程,須要安裝mysql及mysql的開發包,ubuntu下直接apt-get install libmysql++安裝開發包。mysql
#include <mysql.h>linux
相關函數:c++
MYSQL *mysql_init(MYSQL *); //這裏稱之爲載入函數吧,返回的MYSQL指針要用到後續的函數中 int mysql_options(MYSQL *connection, enum option_to_set,const char *argument); //設置MYSQL*的一些屬性,好比超時時間等 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,//置0鏈接默認端口,通常爲3306 const char *unix_socket_name,//NULL unsigned int flags);//無另外屬性時置0 //鏈接函數 void mysql_close(MYSQL *connection); //關閉鏈接 unsigned int mysql_errno(MYSQL *connection); //返回錯誤代碼 char *mysql_error(MYSQL *connection); //返回錯誤信息 int mysql_query(MYSQL *connection, const char *query); //執行sql語句 my_ulonglong mysql_affected_rows(MYSQL *connection); //返回執行語句事後受影響的行數 MYSQL_RES *mysql_store_result(MYSQL *connection); //返回執行結果,適用於數據量較小時 my_ulonglong mysql_num_rows(MYSQL_RES *result); //返回上面函數返回結果的行數 MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); //抽取一條記錄,返回NULL時表示抽取完記錄或者錯誤 void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset); //調整數據位置,offset爲0時,下次調用mysql_fetch_row將返回result第一條記錄 MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result); //返回當前的位置 MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset); //移動數據位置,並返回先前的位置,能夠和上一個函數結合使用 void mysql_free_result(MYSQL_RES *result); //釋放result空間 MYSQL_RES *mysql_use_result(MYSQL *connection); //返回執行結果,適用於數據量較大時 unsigned int mysql_field_count(MYSQL *connection); //返回查詢結果中的列數(column數) MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result); //得到查詢結果中的列名等信息(表頭信息)
例子:sql
建立測試數據庫
mysql> create database test;
建立用戶(已經建立)
mysql> grant all on test.* to mymotif@'localhost' identified by 'xxxxx';數據庫
sql文件:編程
-- -- Create the table children -- CREATE TABLE children ( childno int(11) NOT NULL auto_increment, fname varchar(30), age int(11), PRIMARY KEY (childno) ); -- -- Populate the table ‘children’ -- INSERT INTO children(childno,fname,age) VALUES(1,'Jenny',21); INSERT INTO children(childno,fname,age) VALUES(2,'Andrew',17); INSERT INTO children(childno,fname,age) VALUES(3,'Gavin',8); INSERT INTO children(childno,fname,age) VALUES(4,'Duncan',6); INSERT INTO children(childno,fname,age) VALUES(5,'Emma',4); INSERT INTO children(childno,fname,age) VALUES(6,'Alex',15); INSERT INTO children(childno,fname,age) VALUES(7,'Adrian',9);
導入sql文件:ubuntu
mysql -u mymotif --password=xxxx test<mysqlchildren.sql服務器
導入後的狀況:socket
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| children |
+----------------+
1 row in set (0.00 sec)tcp
mysql> select * from children;
+---------+--------+------+
| childno | fname | age |
+---------+--------+------+
| 1 | Jenny | 21 |
| 2 | Andrew | 17 |
| 3 | Gavin | 8 |
| 4 | Duncan | 6 |
| 5 | Emma | 4 |
| 6 | Alex | 15 |
| 7 | Adrian | 9 |
+---------+--------+------+
7 rows in set (0.00 sec)
C代碼:
/* * * gcc mysqltest.c -o mysqltest -I/opt/mysql/include -L/opt/mysql/lib -lmysqlclient -lpthread -lm -lrt -ldl * * gcc mysqltest.c -o mysqltest `mysql_config --cflags --libs` * * */ #include <stdio.h> #include <stdlib.h> #include <mysql.h> MYSQL *mysql_main; MYSQL_RES *res_ptr; MYSQL_ROW sqlrow; void display_header(); void display_row(); int main(int argc,char *argv[]) { int res; int first_row = 1; mysql_main = mysql_init(NULL); if(!mysql_main) { fprintf(stderr,"mysql_init failed\n"); return EXIT_FAILURE; } mysql_main = mysql_real_connect(mysql_main,"localhost","mymotif","wxwpxh","test",0,NULL,0); if(mysql_main) { printf("Connection success:\n"); res = mysql_query(mysql_main,"SELECT childno,fname,age FROM children WHERE age>5"); if(res) { fprintf(stderr,"SELECT error: %s\n",mysql_error(mysql_main)); } else { res_ptr = mysql_use_result(mysql_main); if(res_ptr) { while((sqlrow = mysql_fetch_row(res_ptr))) { if(first_row) { display_header(); first_row = 0; } display_row(); } } } } else { printf("Connection failed\n"); } mysql_close(mysql_main); return EXIT_SUCCESS; } void display_header() { MYSQL_FIELD *field_ptr; printf("Column details:\n"); while((field_ptr = mysql_fetch_field(res_ptr))!=NULL) { printf("\t Name: %s\n",field_ptr->name); printf("\t Type: "); if(IS_NUM(field_ptr->type)) { printf("Numeric filed\n"); } else { switch(field_ptr->type) { case FIELD_TYPE_VAR_STRING: printf("VARCHAR\n"); break; case FIELD_TYPE_LONG: printf("LONG\n"); break; default: printf("Type is %d,check in mysql_com.h\n",field_ptr->type); } } printf("\t MAX width %ld\n",field_ptr->length); if(field_ptr->flags&AUTO_INCREMENT_FLAG) printf("\t Auto increments\n"); printf("\n"); } } void display_row() { unsigned int field_count; field_count = 0; while(field_count<mysql_field_count(mysql_main)) { if(sqlrow[field_count]) printf("%s ",sqlrow[field_count]); else printf("NULL"); field_count++; } printf("\n"); }
$ ./mysqltest
Connection success:
Column details:
Name: childno
Type: Numeric filed
MAX width 11
Auto increments
Name: fname
Type: VARCHAR
MAX width 30
Name: age
Type: Numeric filed
MAX width 11
1 Jenny 21
2 Andrew 17
3 Gavin 8
4 Duncan 6
6 Alex 15
7 Adrian 9
注意事項:
當mysql用編譯源碼或二進制方式安裝時(非apt-get install),而系統又經過apt安裝了mysql客戶端(因爲依賴關係),這時連接mysqlclient 會連到apt安裝的那個庫:
$ ldd mysqltest
linux-vdso.so.1 => (0x00007ffc5a9a0000)
libmysqlclient.so.20 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 (0x00007f9c0d5e6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c0d21c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9c0cfff000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9c0cdfb000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f9c0cbf2000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9c0c86a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9c0c561000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9c0c349000)
/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 -> /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.2
編譯安裝的服務器和客戶端與apt安裝客戶端socket文件不一致:編譯安裝的是/tmp/mysql.sock
apt安裝客戶端會鏈接/var/run/mysqld/mysqld.sock。顯然/var/run/mysqld/mysqld.sock是不存在的。
mysql_real_connect(mysql_main,"localhost","mymotif","wxwpxh","test",0,NULL,0),用localhost(unix socket方式)是連不上服務器,提示:Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)。用127.0.0.1是能夠的(採用tcp方式)。
解決辦法:
把/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20鏈接到服務器的那個庫。
sudo ln -s /opt/mysql-5.7.14-linux-glibc2.5-x86_64/lib/libmysqlclient.so.20.3.1 /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20