使用C語言串連MySQL資料庫_初級

來源:互聯網
上載者:User

/*

 * 1. 編譯環境

 *      作業系統  Ubuntu10.04
 *      GCC     4.4.3
 *      首先請確保你的系統安裝了下列軟體包:
 *      1. mysql-client,libmysqlclient-dev和libmysqlclient15off
 *            sudo apt-get install mysql-client libmysqlclient-dev libmysqlclient15off
 *       ps:若提示找不到libmysqlclient15off,請在軟體源中添加
 *                deb http://security.ubuntu.com/ubuntu hardy-security main
 *      2. mysql-server
 *            sudo apt-get install mysql-server
 *

 * 2. 使用前,先在mysql中建立資料庫batman: create database batman;

 *          在batman中建立兩張表:TCPpackets, UDPpackets
 *          create table UDPpackets(MB double,KbperSec double,seconds double,percents double);
 *          create table TCPpackets(MB double,KbperSec double);
 *

 * 3. 編譯選項:

 *      gcc -o c_mysql ./c_mysql.c -I /usr/include/mysql -L /usr/lib/mysql -l mysqlclient -std=c99
 *

 * 4. 使用方法:

 *      ./c_mysql <filename> -tcp|-udp

 */

源檔案c_mysql.c的內容如下:

#if defined(_WIN32) || defined(_WIN64)  //為了支援windows平台上的編譯#include <windows.h>#endif#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <mysql.h>  //我的機器上該檔案在/usr/include/mysql下//定義資料庫操作的宏,也可以不定義留著後面直接寫進代碼#define INSERT_UDP "insert into UDPpackets values(%f,%f,%f,%f);"#define INSERT_TCP "insert into TCPpackets values(%f,%f);"//input file type#define TCP_DATA     1#define UDP_DATA     2typedef struct _UDPData{    double MB;    double KbperSec;    double seconds;    double percents;}UDPData, *pUDPData;typedef struct _TCPData{    double MB;    double KbperSec;}TCPData,*pTCPData;int readLine(FILE* fd, char* buf){    char c;    c = fgetc(fd);    while(c != '\n' && c != EOF)    {        *(buf++) = c;        c = fgetc(fd);    }    *buf = '\0';    if(c == EOF)        return EOF;    else        return 0;}void paresUDPRow(char* buf, pUDPData pudp){    int index = 0,strIndex = 0;    char str[20];    char *model[] = {"sec","MBytes","Kbits/sec","("};    double dd[4];    for(int i=0; i<4; i++)    {        index = strstr(buf,model[i]) - buf;        index += strlen(model[i]);        while( buf[index] == ' ')            index++;        strIndex = 0;        while( isdigit(buf[index]) || buf[index] == '.' )        {            str[strIndex++] = buf[index++];        }        str[strIndex] = 0;        dd[i] = atof(str);    }    pudp->MB = dd[0];    pudp->KbperSec = dd[1];    pudp->seconds = dd[2];    pudp->percents = dd[3];}void paresTCPRow(char* buf, pTCPData ptcp){    int index = 0,strIndex = 0;    char str[20];    char *model[] = {"sec","MBytes"};    double dd[2];    for(int i=0; i<2; i++)    {        index = strstr(buf,model[i]) - buf;        index += strlen(model[i]);        while( buf[index] == ' ')            index++;        strIndex = 0;        while( isdigit(buf[index]) || buf[index] == '.' )        {            str[strIndex++] = buf[index++];        }        str[strIndex] = 0;        dd[i] = atof(str);    }    ptcp->MB = dd[0];    ptcp->KbperSec = dd[1];}int main(int argc, char **argv) //char **argv 相當於 char *argv[]{    MYSQL mysql,*sock;    //定義資料庫連接的控制代碼,它被用於幾乎所有的MySQL函數    MYSQL_RES *res;       //查詢結果集,結構類型    char  buf[256];    char  qbuf[256];      //存放查詢sql語句字串    char * filename = NULL;    int  fileType = TCP_DATA;    FILE* fudp;    UDPData udp;    TCPData tcp;    if (argc != 3) {  //檢查輸入參數        fprintf(stderr,"usage : ./c_mysql <filename> -tcp|-udp\n\n");        exit(1);    }    filename = argv[1];    if(strcmp(argv[2],"-tcp")!=0 && strcmp(argv[2],"-udp")!=0)    {        fprintf(stderr,"usage : ./c_mysql <filename> -tcp|-udp\n\n");        exit(EXIT_FAILURE);    }    fileType = !strcmp(argv[2],"-udp") ? UDP_DATA : TCP_DATA;    mysql_init(&mysql);    if (!(sock = mysql_real_connect(&mysql,"localhost","root","123456","batman",0,NULL,0))) {        fprintf(stderr,"Couldn't connect to engine!\n%s\n\n",mysql_error(&mysql));        perror("");        exit(1);    }    fudp = fopen(filename,"r");    if(fudp == NULL)    {        fprintf(stderr,"Couldn't open file %s\n\n",filename);        exit(1);    }    while(readLine(fudp,buf) != EOF)    {        if(fileType == UDP_DATA)        {            paresUDPRow(buf,&udp);            sprintf(qbuf, INSERT_UDP, udp.MB, udp.KbperSec, udp.seconds, udp.percents);        }        else        {            paresTCPRow(buf,&tcp);            sprintf(qbuf,INSERT_TCP,tcp.MB,tcp.KbperSec);        }        fprintf(stdout,qbuf);        fprintf(stdout,"\n");        res = mysql_query(sock,qbuf);        if( res )        {            fprintf(stderr,"Update failed (%s)\n",mysql_error(sock));            exit(1);        }    }    mysql_close(sock);    fclose(fudp);    exit(0);    return 0;   //. 為了相容大部分的編譯器加入此行}

上述代碼的主要作用是把測試batman協議的結果資料儲存到MySQL中,結果包括對TCP測試的結果和對UDP測試的結果。這兩種資料的格式如下:
 TCP:

[  4]  0.0-24.9 sec  2.22 MBytes    747 Kbits/sec[  5]  0.0-1576.9 sec    125 MBytes    665 Kbits/sec[  4]  0.0-33.6 sec  2.00 MBytes    499 Kbits/sec[  5]  0.0-11.9 sec  1.05 MBytes    735 Kbits/sec[  4]  0.0-26.7 sec  1.98 MBytes    621 Kbits/sec[  5]  0.0-23.1 sec  1.76 MBytes    638 Kbits/sec

UDP:

[  3]  0.0-20.6 sec  2.08 MBytes    850 Kbits/sec  43.392 ms   36/ 1521 (2.4%)[  4]  0.0-20.9 sec  2.13 MBytes    853 Kbits/sec  45.070 ms    0/ 1517 (0%)[  3]  0.0-20.5 sec  1.80 MBytes    734 Kbits/sec  41.463 ms 9021/10302 (88%)[  4]  0.0-20.9 sec  2.13 MBytes    855 Kbits/sec  41.880 ms    0/ 1517 (0%)[  3]  0.0-20.6 sec  2.13 MBytes    869 Kbits/sec  12.608 ms    0/ 1521 (0%)[  4]  0.0-20.8 sec  2.13 MBytes    857 Kbits/sec  41.295 ms    0/ 1517 (0%)[  3]  0.0-733.7 sec  15.4 MBytes    176 Kbits/sec  359.811 ms 2913/13907 (21%)[  4]  0.0-10.3 sec  1.00 MBytes    818 Kbits/sec  22.526 ms    0/  713 (0%)[  3]  0.0-34.1 sec  2.00 MBytes    493 Kbits/sec  3.466 ms    0/ 1427 (0%)[  4]  0.0-12.2 sec  1.00 MBytes    688 Kbits/sec  84.498 ms    0/  714 (0%)

這不是重點,重點是對MySQL的操作。可是廢話已經一蘿筐了...

 1. 首先是第一個要用到的結構:

     MYSQL

        該結構代表1個資料庫連接的控制代碼。幾乎所有的MySQL函數均使用它。不應嘗試拷貝MYSQL

        結構。不保證這類拷貝結果會有用。在後續的資料庫操作中都要把它作為參數的。

 2. 在聲明一個MYSQL類型的變數mysql後,就要首先調用 mysql_init(&mysql);     該函數的原型是:MYSQL *mysql_init(MYSQL *mysql)

        描述

            分配或初始化與mysql_real_connect()相適應的MYSQL對象。如果mysql是NULL指標,該

  函數將分配、初始化、並返回新對象。否則,將初始化對象,並返回對象的地址。如果

   mysql_init()分配了新的對象,當調用mysql_close()來關閉串連時,將釋放該對象。


        傳回值
            初始化的MYSQL*控制代碼。如果無足夠記憶體以分配新的對象,返回NULL。
            
        錯誤
            在記憶體不足的情況下,返回NULL。

 3. 調用mysql_real_connect來獲得一個串連執行個體。

     該函數的原型是: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_real_connect()嘗試與運行在主機上的MySQL資料庫引擎建立串連。在你能夠執行

           需要有效MySQL串連控制代碼結構的任何其他API函數之前,mysql_real_connect()必須成功

           完成。


            參數的指定方式如下:
                #  第1個參數應是已有MYSQL結構的地址。調用mysql_real_connect()之前,必須調用

                    mysql_init()來初始化MYSQL結構。

                #  “host”的值必須是主機名稱或IP地址。如果“host”是NULL或字串"localhost",串連將被

                    視為與本地主機的串連。如果作業系統支援通訊端(Unix)或具名管道(Windows),

                    將使用它們而不是TCP/IP串連到伺服器。

                #  “user”參數包含使用者的MySQL登入ID。如果“user”是NULL或Null 字元串"",使用者將被視為

                   目前使用者。在UNIX環境下,它是當前的登入名稱。在Windows ODBC下,必須明確指定

                   目前使用者名。

                # “passwd”參數包含使用者的密碼。如果“passwd”是NULL,僅會對該使用者的(擁有1個空密

                   碼欄位的)使用者表中的條目進行匹配檢查。這樣,資料庫管理員就能按特定的方式設定

                   MySQL許可權系統,根據使用者是否擁有指定的密碼,使用者將獲得不同的許可權。



 4. 執行增刪改查操作mysql_query:

     該函數的原型是:int mysql_query(MYSQL *mysql, const char *query)
        描述

            # 執行由“Null終結的字串”查詢指向的SQL查詢。正常情況下,字串必須包含1條SQL語

               句,而且不應為語句添加終結分號(‘;’)或“\g”。如果允許多語句執行,字串可包含多條

               由分號隔開的語句。

            # mysql_query()不能用於包含位元據的查詢,應使用mysql_real_query()取而代之

             (位元據可能包含字元‘\0’,mysql_query()會將該字元解釋為查詢字串結束)。

            # 如果希望瞭解查詢是否應返回結果集,可使用mysql_field_count()進行檢查。

        傳回值
            如果查詢成功,返回0。如果出現錯誤,返回非0值。
            

 總結:以上只是介紹了本程式要用到的MySQL資料結構和函數,這些介紹都是來自MySQL手冊,

             詳細 資訊可以參考MySQL C API。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.