目錄:html
1、解決小的問題;mysql
其實寫這個程序真的很簡單,十多分鐘的事情,只是之前沒在Linux下用純C連過Mysql,想試一下,居然搞了一成天,並且不是因爲編碼自己,是由於其餘的一些周邊問題,因此頗有必要作一下筆記。api
C語言針對MySql函數的幫助怎麼查找:這些東西在MySql提供的幫助文檔裏都是有的,索引是C API。能夠本身去下載chm格式的幫助文檔,我的以爲這種文檔比較好用,也能夠去官網自行決定下載其餘類型的幫助文檔:http://dev.mysql.com/doc/,或者在線查找:https://dev.mysql.com/doc/refman/5.1/zh/apis.html。用高級語言編程其實就是學會使用幫助文檔並付諸實踐的過程。ide
關於這點,須要作點準備工做:函數
一、安裝mysql:
sudo apt-get install mysql-server
二、安裝庫文件和頭文件:
sudo apt-get install libmysqlclient-devfetch
也能夠本身去官網下載對應mysql的安裝包進行安裝:http://dev.mysql.com/downloads/mysql/,單獨下載connector的rpm或者tar包:http://dev.mysql.com/downloads/connector/。編碼
若是是tar壓縮包,解壓出來,把include文件夾複製(cp命令,需root權限)到/usr/include/mysql/中,而後將lib文件夾複製到/usr/lib/mysql/中。spa
這個問題其實不是什麼大問題,是頭文件引用的時候相對路徑不對,若是編譯器提示你某個頭文件不存在,可是你在那個文件夾裏查看又發現這個頭文件實際上是存在的。
好比說題述問題,咱們在Linux下用C連mysql的時候要包含頭文件:#include<mysql/mysql.h>,編譯的時候編譯器提示錯誤,<mysql/plugin_auth_common.h>不存在?
其實咱們能夠找到的是/usr/include/mysql/mysql/plugin_auth_common.h,而後,把該頭文件複製到父級目錄便可,編譯器就能正確找到這個頭文件。
其實都是相對路徑的問題。
好比寫好的文件爲main.c,轉到文件所在目錄(cd命令),而後進行編譯,並嘗試執行:
gcc -o conn main.c -l mysqlclient
chmod +x conn
./conn
若是不加-lmysqlclient 連接選項的話,通常會提示undefined reference to `mysql_init' ,實際上是由於init是最開始被調用的函數,因此它就最早提示這個而已。
若是想要調試的話能夠用gdb,不過我本身用得都不是很熟,因此就很少說了。
Project->Properties->Settings->Cross GCC Compiler->Includes->Include paths(-I),包含以下兩個路徑:
/usr/include/mysql和/usr/lib/mysql,如圖:
而後在Cross GCC Linker->Libraries中的Libraries(-I)中添加link:mysqlclient,在Library search path(-L)中添加路徑/usr/lib/mysql,如圖:
原本一開始我是在QtCreator裏面寫的,編譯的時候發現不知道哪裏加-l mysqlclient這個連接選項,沒辦法,一點都不會用qmake,也不會用cmake,而後就想用Eclipse來寫,而後又發現Eclipse沒辦法識別mysql的那些頭文件,因而又折騰了一陣子。寫倒不是問題,主要是這些IDE調試的時候比較方便(其實也主要是由於不太會用GDB),唉,各類碰壁。
這個不相關的問題是怎麼來的?其實就是由於編譯器提示某個頭文件找不到,我覺得是當前用戶沒權限去訪問/usr/lib/mysql文件夾裏面的庫文件(這個文件夾是cp過去的,當時我也不清楚它的權限狀態)。因而我把/usr/lib/mysql文件夾的所屬用戶改爲了nerohwang,並且還重啓了計算機,悲劇了。
從新進入系統之後,每次使用sudo命令的時候都提示,/usr/lib下的某文件出錯,該文件的所屬用戶必須是UID爲0的用戶(其實就是root用戶)。
可想而知,一個使用Linux系統的人沒法經過sudo來獲取root權限是什麼感受,感受就是什麼事情都作不了。沒錯,能夠經過su命令來變成root用戶,可是我是沒有對root指定密碼的,因此沒有辦法,甚至一度想過對系統進行重裝(自殺)。
後來想到去Windows系統下用軟碟通(UltrISO)寫一個Ubuntu系統到U盤裏,而後U盤啓動之後選試用Ubuntu而不是安裝。進到試用系統後,獲取根用戶權限(居然不用密碼),而後將原系統的那些文件權限恢復:
sudo su
cd /你平時用的Linux根目錄的路徑(桌面系統會幫你把這個系統掛載上,你能夠點選之後經過右鍵--屬性選項查看)
chown -R root:root /usr/lib
chown -R root:root /usr/include
上面所說的,桌面系統會幫你掛載那個分區,固然也能夠自行掛載:
fdisk -l -------查看分區狀況,好比說咱們發現那個系統分區在/dev/sda1上:
mount /dev/sda1 /mnt/DirName --須要根用戶權限
重啓,進入系統,恢復正常。因此說,根目錄的東西不要去亂搞。
其實這個最沒什麼好說的,不過最後仍是寫了個Demo 。
開始建表以下:
id爲INT,主鍵,AUTO_INCREMENT,text爲varchar(15)。
程序源碼:
1 /*Author:nerohwang 2 Date:2014/3/7*/ 3 #include <stdio.h> 4 #include<stdlib.h> 5 #include<mysql/mysql.h> 6 #include<string.h> 7 #define INSERT_QUERY "INSERT INTO tblTest(text) values(?)" 8 void main(void) 9 { 10 size_t break_point = 0; 11 printf("Hello World!\n"); 12 MYSQL *conn; 13 MYSQL mysql; 14 MYSQL_RES *mysql_res; 15 MYSQL_ROW *mysql_row; 16 MYSQL_FIELD *mysql_field; 17 MYSQL_STMT *mysql_stmt; 18 unsigned int num_fields; 19 const char * server = "localhost"; 20 const char *user = "root"; 21 const char *passwd = "cc527888"; 22 const char *dataBase = "dbTest"; 23 const char *query_select = "select * from tblTest"; 24 conn = mysql_init(NULL); 25 if(!mysql_real_connect(conn,server,user,passwd,dataBase,0,NULL,0)) 26 { 27 fprintf(stdout,"Error connecting to Mysql: %s\n",mysql_error(conn)); 28 } 29 int t = mysql_query(conn,query_select); 30 if(t) //t=0 means correct 31 { 32 fprintf(stderr,"Query error occurs:%s\n",mysql_error(conn)); 33 } 34 35 mysql_res = mysql_use_result(conn); 36 if(mysql_res == NULL) 37 { 38 fprintf(stderr,"Query error occurs: %s!\n",mysql_error(conn)); 39 } 40 num_fields = mysql_num_fields(mysql_res); 41 unsigned int num_rows = mysql_num_rows(mysql_res); 42 printf("There're %d columns in the table tblTest\n",num_fields); 43 //The code below won't return correct result until all rows in result_Set have been retieved 44 printf("There're %d rows affected in the table tblTest\n",num_rows); 45 mysql_field = mysql_fetch_fields(mysql_res); 46 unsigned int i=0; 47 for(i=0; i< num_fields; i++) 48 { 49 printf("Field %u is %s\t",i,mysql_field[i].name); 50 } 51 printf("\n"); 52 size_t i_temp=0; 53 while((mysql_row=mysql_fetch_row(mysql_res))) 54 { 55 printf("The ID %d is %s\n",++i_temp,mysql_row[1]); 56 } 57 num_rows = mysql_num_rows(mysql_res); 58 printf("There're %d rows affected in the table tblTest\n",num_rows); //Now ,it's correct 59 60 61 //Insert operation////////////////////////////////////////////////////////////////////////// 62 if(!(mysql_stmt=mysql_stmt_init(conn))) 63 { 64 fprintf(stderr,"Statement initialization failed: %s\n",mysql_stmt_error(mysql_stmt)); 65 exit(0); 66 } 67 if(mysql_stmt_prepare(mysql_stmt,INSERT_QUERY,strlen(INSERT_QUERY))) //0 means correct 68 { 69 fprintf(stderr,"Statament preparation failed:%s and %s\n",mysql_error(conn),mysql_stmt_error(mysql_stmt)); 70 exit(0); 71 } 72 fprintf(stdout,"Init and preparation succeeded!\n"); 73 MYSQL_BIND bind[1]; 74 memset(bind, 0, sizeof(bind)); 75 char *ch = "test_in"; 76 int lengthCH = strlen(ch); 77 bind[0].buffer_type = MYSQL_TYPE_VARCHAR; 78 bind[0].buffer = ch; 79 bind[0].is_null = 0; 80 bind[0].length = &lengthCH; 81 if (mysql_stmt_bind_param(mysql_stmt, bind)) 82 { 83 fprintf(stderr, " mysql_stmt_bind_param() failed\n"); 84 fprintf(stderr, " %s\n", mysql_stmt_error(mysql_stmt)); 85 exit(0); 86 } 87 88 if(mysql_stmt_execute(mysql_stmt)) 89 { 90 fprintf(stderr,"Execution failed:%s\n",mysql_stmt_error(mysql_stmt)); 91 exit(0); 92 } 93 my_ulonglong affected_rows= mysql_stmt_affected_rows(mysql_stmt); 94 fprintf(stdout, " total affected rows(insert 1): %l\n", 95 (unsigned long) affected_rows); 96 97 if (mysql_stmt_close(mysql_stmt)) 98 { 99 fprintf(stderr, " failed while closing the statement\n"); 100 fprintf(stderr, " %s\n", mysql_stmt_error(mysql_stmt)); 101 exit(0); 102 } 103 //Insert opration success//////////////////////////////////////////////////////////// 104 mysql_close(conn); 105 printf("End of the file\n"); 106 }
執行若干次之後結果以下:
寫完,睡覺。