小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

使用C語言操作MySQL數(shù)據(jù)庫

 看風(fēng)景D人 2014-03-19
1.連接數(shù)據(jù)庫。
  從C語言連接MySQL數(shù)據(jù)庫包含兩個步驟:
  a)初始化連接句柄結(jié)構(gòu);
  b)實際創(chuàng)建連接。
 
  首先使用mysql_init初始化連接句柄:
  MYSQL * mysql_init (MYSQL *);
  通常傳遞一個空指針給mysql_init這個函數(shù),它會返回一個指向新分配的連接句柄結(jié)構(gòu)的指針。如果傳遞一個已有的結(jié)構(gòu),他將被重新初始化。如果出錯,返回NULL。初始化成功后,則使用mysql_real_connect來創(chuàng)建一個實際的連接:
      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,
                      const char * unix_socket_name,
                      unsigned int flags
        );
  connection必須是已經(jīng)初始化的連接句柄結(jié)構(gòu),server_host可以是主機名,也可以是IP地址,如果僅僅連接到本機,可以使用 localhost來優(yōu)化連接類型。port_number和unix_socket_name應(yīng)該分別為0和NULL,除非改變了MYSQL安裝的默認 設(shè)置。
 如果無法連接,返回NULL。完成連接后,在程序正常退出前,應(yīng)該使用mysql_close關(guān)閉這個連接句柄。
   void mysql_close(MYSQL * connection);
  現(xiàn)在我們試圖調(diào)用以上函數(shù)來建立一個對以上已經(jīng)建好的數(shù)據(jù)庫的訪問,程序為connect1.c。內(nèi)容如下:
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"

int main (int argc, char *argv[])
{
      MYSQL *conn_ptr;
      conn_ptr=mysql_init(NULL); //連接初始化
      if(!conn_ptr){
              fprintf(stderr, "mysql_init failed\n");
              return EXIT_FAILURE;
      }

      conn_ptr = mysql_real_connect(conn_ptr, "localhost", "moldao","newpassword","moldao_test", 0, NULL, 0); //建立實際連接
      //參數(shù)分別為:初始化的連接句柄指針,主機名(或者IP),用戶名,密碼,數(shù)據(jù)庫名,0,NULL,0)后面三個參數(shù)在默認安裝mysql>的情況下不用改
      if(conn_ptr){
              printf("Connection success\n");
              }
      else {
              printf("Connection failed\n");
      }

      mysql_close(conn_ptr); //關(guān)閉連接
      return EXIT_SUCCESS;
}
  然后編譯:
  #gcc -I/usr/include/mysql connect1.c -lmysqlclient -o connect1
 connect1.c:4:19: 錯誤:mysql.h:沒有那個文件或目錄
  提示是沒有找到mysql.h,產(chǎn)生這個錯誤的原因是沒有mysql.h文件,它在mysql-devel包中,需要安裝這個包:
     sudo yum install mysql-devel -y
  然后找一下:
     #locate mysql.h
     /usr/include/mysql/mysql.h
  這樣就可以找到這個頭文件了(-I的含義是在指定位置搜索頭文件,參見man gcc)。再次嘗試編譯:
  # gcc -I/usr/include/mysql connect1.c -lmysqlclient -o connect1
 /usr/bin/ld: cannot find -lmysqlclient
 collect2: ld 返回 1
  鏈接庫有問題,找不到mysqlclient鏈接庫,man gcc發(fā)現(xiàn)可以在后面用-L指定搜索位置,于是我們先找到mysqlclient庫的位置:
 locate *mysqlclient*
 /usr/lib/mysql/libmysqlclient.a
 /usr/lib/mysql/libmysqlclient.so
 /usr/lib/mysql/libmysqlclient.so.15
 /usr/lib/mysql/libmysqlclient.so.15.0.0
 /usr/lib/mysql/libmysqlclient_r.a
 /usr/lib/mysql/libmysqlclient_r.so
 /usr/lib/mysql/libmysqlclient_r.so.15
 /usr/lib/mysql/libmysqlclient_r.so.15.0.0
  這樣找到位置就可以編譯了:
    gcc -I/usr/include/mysql connect1.c -lmysqlclient -L/usr/lib/mysql -o connect1
  編譯成功,于是就可以運行了,在此之前,確保mysqld已經(jīng)在運行了:
  sudo /etc/rc.d/init.d/mysqld restart
  然后執(zhí)行生成的可執(zhí)行文件:
  ./connect1
 Connection success
  打印出了我們設(shè)計好了的連接成功的打印信息。這樣就通過C語言進入了MySQL數(shù)據(jù)庫了。

  ##########################################
  #在以上這一段編譯這個connect1.c的文件過程了,出過兩次錯誤,分別記錄如上,看起來 #
  #解決的辦法很簡單,但是自己當(dāng)時確實是很迷茫,不知什么原因,網(wǎng)上搜索的結(jié)果大都不得#
  #要領(lǐng),最終還是靠自己靜下心來看gcc的手冊,man gcc才解決。                       #
  #P.S. man gcc真長。 要冷靜!                                                     #
  ##########################################

2. 操作數(shù)據(jù)庫   
 進入數(shù)據(jù)庫中之后,就可以開始對數(shù)據(jù)庫進行讀寫操作了。
  數(shù)據(jù)庫的主要操作包括select, insert, update, delete四種。
  a)sql語句的嵌入:
      執(zhí)行SQL語句的主要API函數(shù)是:
      int mysql_query(MYSQL *connection, const char * query)
      接受已經(jīng)建立的連接結(jié)構(gòu)指針和文本字符串形式的有效SQL語句(句末不用分號)。成功返回0。
      還有一個比較重要的函數(shù),mysql_affected_rows(),他返回?zé)o符號類型,當(dāng)使用printf時,推薦使用%lu格式將其轉(zhuǎn)換為無符號長整型。此函數(shù)返回受之前執(zhí)行的update,delete,insert等查詢影響的行數(shù)。
      my_ulonglong mysql_affected_rows(MYSQL *connection);
      MySQL返回被一個更新操作修改的行數(shù),但其他許多數(shù)據(jù)庫將僅僅因為記錄匹配where字句而把它視為已經(jīng)更新過。
      通常對于mysql_函數(shù),返回值0表示沒有行受到影響,正數(shù)則是實際的結(jié)果,一般表示受語句影響的行數(shù)。
  
 b)select語句的使用:
  select語句是SQL語句中使用最頻繁的操作。    
  一個完整的提取數(shù)據(jù)過程應(yīng)該包含以下四個步驟:執(zhí)行查詢,提取數(shù)據(jù),處理數(shù)據(jù),清理。
  使用mysql_query來發(fā)送SQL語句,使用mysql_store_result或者mysql_use_result來提取數(shù)據(jù)。然后使用 mysql_fetch_row調(diào)用來處理數(shù)據(jù),最后,使用mysql_free_result來釋放查詢占用的內(nèi)存資源。
  mysql_use_result和mysql_store_result都是返回一個指向結(jié)果集結(jié)構(gòu)(result set structure)的指針,如果失敗則返回NULL。區(qū)別在于store將查詢到的數(shù)據(jù)庫中的結(jié)果直接放在這個結(jié)果集中,而use則不直接將最終數(shù)據(jù)庫 的數(shù)據(jù)結(jié)果放在這個結(jié)果集中。store其實就是把數(shù)據(jù)直接讀到本地內(nèi)存中,因此它比較適合數(shù)據(jù)量較小的查詢。use則類似于一種流的操作,并不是一次就 返回所有的結(jié)果。因此,對于這個結(jié)果集,必須反復(fù)調(diào)用mysql_fetch_row直到提取所有的數(shù)據(jù)。
  1)一次獲取所有的數(shù)據(jù):
  MYSQL_RES *mysql_store_result(MYSQL *connection);
  在成功調(diào)用mysql_query之后使用此函數(shù),將立即保存在客戶端中返回的所有數(shù)據(jù),并將指向此結(jié)果集的指針返回。如果失敗則返回NULL。
  成功之后,可以用mysql_num_rows來得到返回記錄的數(shù)目,一般應(yīng)該是個正數(shù),若沒有返回行匹配,則返回0.
  my_ulonglong mysql_num_rows(MYSQL_RES *result);
  現(xiàn)在得到來數(shù)據(jù),可使用mysql_fetch_row來處理它,也可以使用mysql_data_seek,mysql_row_seek和mysql_row_tell在數(shù)據(jù)集中來回移動。
  MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
  此函數(shù)從上面得到的結(jié)果集中提取一行,并把它放在一個行結(jié)構(gòu)中。當(dāng)數(shù)據(jù)用完或者出錯時返回NULL。
  void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
  此函數(shù)允許結(jié)構(gòu)集當(dāng)前指針的跳轉(zhuǎn),設(shè)置會被下一個mysql_fetch_row操作返回的行。offset是行號,在0到總行數(shù)減1的范圍內(nèi)。傳遞0,則返回初始位置。
  MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);
  此函數(shù)返回結(jié)果集的當(dāng)前位置。不能把它用于mysql_data_seek。
  完成來對數(shù)據(jù)的所有操作之后,必須調(diào)用mysql_free_result來讓MYSQL數(shù)據(jù)庫完成善后處理。
  void mysql_free_result(MYSQL_RES *result);


--------------------------------------使用范例--------------------------------------------------
 MYSQL my_connection;
 MYSQL_RES *res_ptr;
 MYSQL_ROW sqlrow;
 
  mysql_init(&my_connection);

  if(mysql_real_connect(&my_connection, "localhost", "moldao","password","moldao_test", 0, NULL, 0)){
              printf("Connection success\n");

              res = mysql_query(&my_connection, "select * from children where age < 10");

              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)){    
                                unsigned int field_count;
                                field_count =0;
                            while(field_count < mysql_field_count(&my_connection)){
                                printf("%s ", sqlrow[field_count]);field_count++;
                                         }
                              }
                              if(mysql_errno(&my_connection)){
                                      printf("Retrive error : %s\n", mysql_error(&my_connection));
                              }
                      }
              mysql_free_result(res_ptr);
              }
   mysql_close(&my_connection);
  -----------------------------------------------------------------------------------------------
  2)一次提取一行數(shù)據(jù)
  建議使用這種提取數(shù)據(jù)的方式。它能取得更好的網(wǎng)絡(luò)負載平衡,以及減少大數(shù)據(jù)集可能造成的存儲過載。但是它也增加來時延,并且在特殊的情況下,比如網(wǎng)絡(luò)鏈接在操作中途失敗時,可能會得到不完整的數(shù)據(jù)甚至造成混亂。
 此時依靠mysql_use_result:
  MYSQL_RES *mysql_use_result(MYSQL * connection);
  與store一樣,出錯返回NULL,成功則返回指向結(jié)果集對象的指針。
  --------------------------------------使用范例---------------------------------------------------------
 //這里只寫取數(shù)據(jù)的部分
 res_ptr = mysql_store_result(&my_connection);
   if(res_ptr){
      while (sqlrow = mysql_fetch_row(res_ptr)){
          //display_row_or_dealwith_row_here;
          }
      }
 ------------------------------------------------------------------------------------------------
  
 c)update,insert,和delete語句的使用
  update, insert和delete這三個操作是不用返回任何數(shù)據(jù)的語句,他們都是使用mysql_query來執(zhí)行語句。        
  --------------------------------------使用范例------------------------------------------------
 int res = mysql_query(&my_connection, "SQL語句");
  if(!res){
      printf("operation success\naffected %lu rows\n", (unsigned long)mysql_affected_row (&my_connection));
     }
  else{
      fprintf(stderr, "failed error: %d: %s", mysql_errno(&my_connection), mysql_error(&my_connection));
     }
   -----------------------------------------------------------------------------------------------
  注意的是mysql_affected_row返回的是真正受到影響或者說是被改變的行數(shù),而不僅僅是匹配where字句的行數(shù)。
 
 
3 一個完整的顯示數(shù)據(jù)庫中元數(shù)據(jù)和數(shù)據(jù)的例子:
#include <stdlib.h>
#include <stdio.h>

#include "mysql.h"

MYSQL my_connection;
MYSQL_RES *res_ptr;
MYSQL_ROW sqlrow;

void display_header();
void display_row();

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

      int first_row =1;
      int res;

      mysql_init(&my_connection); //連接初始化
/*      if(!conn_ptr){
              fprintf(stderr, "mysql_init failed\n");
              return EXIT_FAILURE;
      }
*/
      if(mysql_real_connect(&my_connection, "localhost", "moldao","savage","moldao_test", 0, NULL, 0)){
              printf("Connection success\n");

              res = mysql_query(&my_connection, "select * from children where age > 4");
              if(res){
                      fprintf(stderr, "Select error : %s\n", mysql_error(&my_connection));
                      }
              else{
                      res_ptr = mysql_use_result(&my_connection);
                      if(res_ptr){
                              display_header();
                              while((sqlrow = mysql_fetch_row(res_ptr))){
                                      if(first_row){
                                              display_header();
                                              first_row = 0;
                                              }
                                      display_row();
                                      }
                              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;
}

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 field\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 increment\n");
              printf("\n");
      }
}


void display_row(){
      unsigned int field_count;

      field_count = 0;
      while(field_count < mysql_field_count(&my_connection)){
      if(sqlrow[field_count])
              printf("%s ", sqlrow[field_count]);
      else printf("NULL");
      field_count++;

      }
      printf("\n");
}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多