Linux下C鏈接MySql數據庫

目錄:html

1、解決小的問題;mysql

2、大問題,若是你不當心把/usr/lib的所屬用戶改了致使sudo命令用不了:sql

3、C鏈接MySql編程自己:編程

其實寫這個程序真的很簡單,十多分鐘的事情,只是之前沒在Linux下用純C連過Mysql,想試一下,居然搞了一成天,並且不是因爲編碼自己,是由於其餘的一些周邊問題,因此頗有必要作一下筆記。api

1、解決小的問題:

一、怎麼本身去學着編寫?

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

三、偶遇奇怪問題 fatal error: mysql/plugin_auth_common.h

這個問題其實不是什麼大問題,是頭文件引用的時候相對路徑不對,若是編譯器提示你某個頭文件不存在,可是你在那個文件夾裏查看又發現這個頭文件實際上是存在的。

好比說題述問題,咱們在Linux下用C連mysql的時候要包含頭文件:#include<mysql/mysql.h>,編譯的時候編譯器提示錯誤,<mysql/plugin_auth_common.h>不存在?

其實咱們能夠找到的是/usr/include/mysql/mysql/plugin_auth_common.h,而後,把該頭文件複製到父級目錄便可,編譯器就能正確找到這個頭文件。

其實都是相對路徑的問題。

四、怎麼用GCC命令正確編譯:

好比寫好的文件爲main.c,轉到文件所在目錄(cd命令),而後進行編譯,並嘗試執行:

gcc -o conn main.c -l mysqlclient

chmod +x conn

./conn

若是不加-lmysqlclient 連接選項的話,通常會提示undefined reference to `mysql_init' ,實際上是由於init是最開始被調用的函數,因此它就最早提示這個而已。

若是想要調試的話能夠用gdb,不過我本身用得都不是很熟,因此就很少說了。

五、Eclipse(Kepler-Cpp)構建針對MySql的開發環境:

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),唉,各類碰壁。

2、大問題,若是你不當心把/usr/lib的所屬用戶改了致使sudo命令用不了:

這個不相關的問題是怎麼來的?其實就是由於編譯器提示某個頭文件找不到,我覺得是當前用戶沒權限去訪問/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        --須要根用戶權限

重啓,進入系統,恢復正常。因此說,根目錄的東西不要去亂搞。

3、C鏈接MySql編程自己:

其實這個最沒什麼好說的,不過最後仍是寫了個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 }
C_Mysql

執行若干次之後結果以下:

 寫完,睡覺。

相關文章
相關標籤/搜索