linux下c語言學習筆記——操作mysql

noter發表於2007-06-05
linux下c語言學習筆記——操作mysql
作者:kyako
1,[比較詳細]在 C 裡嵌入 SQL:http://www.pgsqldb.org/pgsqldoc-7.4/ecpg.html
2,[在MySQL資料庫中使用C執行SQL語句]:http://www.dvbbs.net/tech/data/2006031818989.asp
3,MySQL客戶工具和API:http://www.yesky.com/imagesnew/software/mysql/manual_Clients.html
4,基於mysql的高效能資料庫應用開發:http://cache.baidu.com/c?word=mysql%3B%5F%3Breal%3B%5F%3Bconnect%2C%B2%CE%CA%FD&url=http%3A//www%2Edaima%2Ecom%2Ecn/Info/76/Info27780/&b=0&a=2&user=baidu


大家一起來開始練習羅
注:下面的所有例子在mandriva linux下測試通過

1,使用c語言操作mysql之前,先在mysql裡頭建立一個資料庫,一個表,在表裡頭新增資料如下:

建立資料庫,庫名為cusemysql:
mysql>create database cusemysql;
建立表,表名為:
mysql>use cusemysql;
mysql>create table children(childno int not null unique,fname varchar(20),age int);
新增一點資料哦:
mysql>insert into children values(5,"花兒",10);
對拉,為了方便起見,把表的大致樣子給大家看看


childno         fname         age
1                   小星         9
2                   大量           15



2 ,下面進行具體的操作

插入:insert     

好的,我們現編輯一段c程式碼,取名為insert.c


Code:
/*  insert.c */

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/mysql/include/mysql/mysql.h"
/*注意哦,上面必須是mysql.h的絕對地址,一般在mysql下的include目錄下,仔細看看你的在哪裡?*/

int main(int argc, char *argv[])
{

  MYSQL my_connection;
  int res;
  mysql_init(&my_connection);

/*mysql_real_connect(&mysql,host,user,passwd,dbname,0,NULL,0) == NULL)*/
  if (mysql_real_connect(&my_connection, "localhost", "root", "","cusemysql",0,NULL,CLIENT_FOUND_ROWS)) {   
        printf("Connection success/n");   
        res = mysql_query(&my_connection, "insert into children values(10,'Ann',5)");   

        if (!res)   {      
                printf("Inserted %lu rows/n",(unsigned long)mysql_affected_rows(&my_connection)); /*裡頭的函式返回受表中影響的行數*/   
        }   else   {      
                fprintf(stderr, "Insert error %d: s/n",mysql_errno,(&my_connection),mysql_error(&my_connection));   
        }   

        mysql_close(&my_connection);
   } else {   
        fprintf(stderr, "Connection failed/n");   
        if (mysql_errno(&my_connection))   {      
                 fprintf(stderr, "Connection error %d: %s/n",      
                           mysql_errno(&my_connection),       mysql_error(&my_connection));      
        }
  }
return EXIT_SUCCESS;

}

[Ctrl+A Select All]



程式碼寫完了,要編譯哦
#gcc -o insert insert.c -L /usr/local/mysql/lib/mysql/*.a -lz
如果上邊的編譯不成功,可以試一下下邊的
#gcc -o insert insert.c `mysql_config --cflags --libs`
ok,現在我們執行看看
#./insert
Connection Success
Inserted 1 rows

year,果然可以,呵呵
不信到mysql下看看錶children中是否多了剛才插入的那一行資料

注:也許你會問上面gcc的命令引數是什麼意思阿,其實,我也不太清楚,呵呵
大概是要把mysql下的某個特定庫包含進來,可是我不知道具體是個什麼庫,所以用*.a全部包含進來拉
其實只要包含mysqlclient.a就可以,你試試看


更新:update

我們只要把上面的程式碼中的

res = mysql_query(&my_connection, "insert into children values(10,'Ann',5)");

換成

res = mysql_query(&my_connection, "update children set age=20 where childno<5 ");

即可
上面語句實現的功能是,把編號小於5的所有孩子的年齡全部改成20歲



檢索:select

看程式碼之前,最好是先看藍色字型的部分[介紹了程式碼中用到的一些函式的作用]


Code:

/*  select.c */

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/mysql/include/mysql/mysql.h"

int main(int argc, char *argv[])
{
  MYSQL my_connection;
  MYSQL_RES *res_ptr;
  MYSQL_ROW sqlrow;

  int res;
  mysql_init(&my_connection);

  /*mysql_real_connect(&mysql,host,user,passwd,dbname,0,NULL,0) == NULL)*/
  if (mysql_real_connect(&my_connection, "localhost", "root", "","cusemysql",0,NULL,CLIENT_FOUND_ROWS)){   
        printf("Connection success/n");  
        res = mysql_query(&my_connection, "select childno,fname,age from  children where age<20");  
        if (res)   {      
                printf("SELECT error:%s/n",mysql_error(&my_connection));   
        }   else   {      
                res_ptr=mysql_store_result(&my_connection);     
               
                if(res_ptr)      {            
                      printf("Retrieved %lu Rows/n",(unsigned long)mysql_num_rows(res_ptr));            
                      while((sqlrow=mysql_fetch_row(res_ptr)))  {                    
                                  printf("Fetched data.../n");            
                      }            
                      if (mysql_errno(&my_connection)) {                    
                                  fprintf(stderr,"Retrive error:s/n",mysql_error(&my_connection));            
                      }      
                }      
                mysql_free_result(res_ptr);      
         }   
         mysql_close(&my_connection);
   }else{   
         fprintf(stderr, "Connection failed/n");  
         if (mysql_errno(&my_connection))   {      
                   fprintf(stderr, "Connection error %d: %s/n",       mysql_errno(&my_connection),       mysql_error(&my_connection));           }
   }   

   return EXIT_SUCCESS;

}

[Ctrl+A Select All]


上面語句實現的功能是:檢索出年齡小於20歲的小孩的資訊,不過沒有對資訊進行任何處理哦
下次我們對資料進行一定的處理

這裡介紹上面用到的幾個函式:                                   
                                                                                                           

                        可以從SELECT語句(或其他返回資料的語句)中檢索完所有資料,在單一呼叫中,使用mysql_store_result:
                        
                        MYSQL_RES *mysql_store_result(MYSQL *connection);
                        
必須在mysql_query檢索資料後才能呼叫這個函式,以在結果集中儲存該資料。這個函式從伺服器中檢索所有資料並立即將它儲存在客戶機中。它返回一個指向以前我們從未遇到過的結構(結果集結構)的指標。如果語句失敗,則返回NULL。
                        
                        使用等價的PostgreSQL時,應該知道返回NULL意味著已經發生了錯誤,並且這與未檢索到資料的情況不同。即使,返回值不是NULL,也不意味著當前有資料要處理。
                        
                        如果未返回NULL,則可以呼叫mysql_num_rows並且檢索實際返回的行數,它當然可能是0。
                        
                        my_ulonglong mysql_num_rows(MYSQL_RES *result);
                        
                        它從mysql_store_result取得返回的結果結構,並且在該結果集中返回行數,行數可能為0。如果mysql_store_result成功,則mysql_num_rows也總是成功的。
                        
這種mysql_store_result和mysql_num_rows的組合是檢索資料的一種簡便並且直接的方法。一旦 mysql_store_result成功返回,則所有查詢資料都已經儲存在客戶機上並且我們知道可以從結果結構中檢索它,而不用擔心會發生資料庫或網路 錯誤,因為對於程式所有資料都是本地的。還可以立即發現返回的行數,它可以使編碼更簡便。如前所述,它將所有結果立即地傳送回客戶機。對於大結果集,它可 能耗費大量的伺服器、網路和客戶機資源。由於這些原因,使用更大的資料集時,最好僅檢索需要的資料。不久,我們將討論如何使用 mysql_use_result函式來完成該操作。
                        
一旦檢索了資料,則可以使用mysql_fetch_row來檢索它,並且使用mysql_data_seek、mysql_row_seek、mysql_row_tell操作結果集。在開始檢索資料階段之前,讓我們先討論一下這些函式。
                        
                        MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
                        
                        這個函式採用從儲存結果中獲取的結果結構,並且從中檢索單一行,在行結構中返回分配給您的資料。當沒有更多資料或者發生錯誤時,返回NULL。稍後,我們將回來處理這一行中的資料。
                        
                        void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
                        
                        這個函式允許您進入結果集,設定將由下一個獲取操作返回的行。offset是行號,它必須在從0到結果集中的行數減 1 的範圍內。傳遞0將導致在下一次呼叫mysql_fetch_row時返回第一行。
                        
                        MYSQL_ROW_OFFEST mysql_row_tell(MYSQL_RES *result);
                        
                        這個函式返回一個偏移值,它表示結果集中的當前位置。它不是行號,不能將它用於mysql_data_seek。但是,可將它用於:
                        
                        MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);
                        
                        它移動結果集中的當前位置,並返回以前的位置。
                        
                        有時,這一對函式對於在結果集中的已知點之間跳轉很有用。請注意,不要將row tell和row seek使用的偏移值與data_seek使用的行號混淆。這些是不可交換的,結果將是您所希望看到的。
                        
                        void mysql_free_result(MYSQL_RES *result);
                        
                        完成結果集時, 必須總是呼叫這個函式,以允許MySQL庫整理分配給它的物件。
                        

檢索並處理[比較全面哦,呵呵]:select     

下面是詳細的程式碼:


Code:

/*  select1.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "/usr/local/mysql/include/mysql/mysql.h"

int main(int argc, char *argv[])
{
    MYSQL my_connection;
    MYSQL_RES *res_ptr;   /*指向檢索的結果存放地址的指標*/
    MYSQL_ROW sqlrow;     /*返回的記錄資訊*/
    MYSQL_FIELD *fd;      /*欄位結構指標*/
    char aszflds[25][25]; /*用來存放各欄位名*/
    int res;             /*執行查詢操作後的返回標誌*/
    int i,j,k;
   
    mysql_init(&my_connection);

    /*mysql_real_connect(&mysql,host,user,passwd,dbname,0,NULL,0) == NULL)*/
    if (mysql_real_connect(&my_connection, "localhost", "root", "","cusemysql",0,NULL,CLIENT_FOUND_ROWS)){   
        printf("Connection success/n");   
        res = mysql_query(&my_connection, "select childno,fname,age from children where age<20");   
        if (res)   {      
            printf("SELECT error:%s/n",mysql_error(&my_connection));   
        }   else   {      
            res_ptr=mysql_store_result(&my_connection);      
            if(res_ptr)      {            
                printf("Retrieved %lu Rows/n",(unsigned long)mysql_num_rows(res_ptr));             /*取得各欄位名*/            
                for(i=0;fd=mysql_fetch_field(res_ptr);i++)                    
                        strcpy(aszflds<i>,fd->name);             /*輸出各條記錄*/            
                printf("下面是檢索出的各條記錄資訊:/n");            
                j=mysql_num_fields(res_ptr);            
                for(i=0;i<j;i++)            
                        printf("%s/t",aszflds<i>);            
                printf("/n");            

                while((sqlrow=mysql_fetch_row(res_ptr))) {                  
                        for(i=0;i<j;i++)                  
                               printf("%s/t",sqlrow<i>);                    
                        printf("/n");            
                }            
                if (mysql_errno(&my_connection)) {                    
                        fprintf(stderr,"Retrive error:s/n",mysql_error(&my_connection));            
                }      
            }      

            mysql_free_result(res_ptr);      
        }   

        mysql_close(&my_connection);
    }else{   
        fprintf(stderr, "Connection failed/n");   
        if (mysql_errno(&my_connection))   {      
                fprintf(stderr, "Connection error %d: %s/n",       mysql_errno(&my_connection),       mysql_error(&my_connection));            
        }
    }   

    return EXIT_SUCCESS;

}

[Ctrl+A Select All]


【來源】

相關文章