亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 995 | 回復(fù): 0
打印 上一主題 下一主題

The MySQL C API 編程實例 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-12-19 13:55 |只看該作者 |倒序瀏覽
在網(wǎng)上找了一些MYSQL C API編程的文章,看了后覺得還是寫的不夠充分,根據(jù)自己經(jīng)驗寫了這篇《The MySQL C API 編程實例》,希望對需要調(diào)用到MYSQL的C的API的朋友有所幫助,附例中的環(huán)境為RedHat
    在這篇文章里,我們將學(xué)會怎么使用MySQL 的C APIs(Application Programming Interfaces 編程接口)。為了很好地了解這篇文章,您需要具備以下前提知識:
•C語言變量
•C語言函數(shù)
•C語言指針
簡介C APIs包含在mysqlclient庫文件當(dāng)中與MySQL的源代碼一塊發(fā)行,用于連接到數(shù)據(jù)庫和執(zhí)行數(shù)據(jù)庫查詢。有一些例子在MySQL原代碼的clients目錄里。
 
MySQL C 變量類型以下變量類型在MySQL的庫當(dāng)中定義。我們需要這些變量是為了使用MySQL的函數(shù)。這些變量有詳細(xì)的解釋,但是這些解釋對于寫代碼來說并不重要。
MYSQL
    以下代碼塊是用來連接數(shù)據(jù)庫的通訊過程,要連接MYSQL,必須建立MYSQL實例,通過mysql_init初始化方能開始進(jìn)行連接,這個在后面會講到。
typedef struct st_mysql {  NET           net;            /* Communication parameters */  gptr          connector_fd;   /* ConnectorFd for SSL */  char          *host,*user,*passwd,*unix_socket,                *server_version,*host_info,*info,*db;  unsigned int  port,client_flag,server_capabilities;  unsigned int  protocol_version;  unsigned int  field_count;  unsigned int  server_status;  unsigned long thread_id;      /* Id for connection in server */  my_ulonglong affected_rows;  my_ulonglong insert_id;       /* id if insert on table with NEXTNR */  my_ulonglong extra_info;              /* Used by mysqlshow */  unsigned long packet_length;  enum mysql_status status;  MYSQL_FIELD   *fields;  MEM_ROOT      field_alloc;  my_bool       free_me;        /* If free in mysql_close */  my_bool       reconnect;      /* set to 1 if automatic reconnect */  struct st_mysql_options options;  char          scramble_buff[9];  struct charset_info_st *charset;  unsigned int  server_language;} MYSQL;
 
MYSQL_RES
    這個結(jié)構(gòu)代表返回行的一個查詢的(SELECT, SHOW, DESCRIBE, EXPLAIN)的結(jié)果。返回的數(shù)據(jù)稱為“數(shù)據(jù)集”,用過數(shù)據(jù)庫的朋友應(yīng)該對數(shù)據(jù)庫中查詢后得到的結(jié)果集不會陌生,在C的API里對應(yīng)的就是MYSQL_RES了,從數(shù)據(jù)庫讀取數(shù)據(jù),最后就是從MYSQL_RES中讀取數(shù)據(jù)。
typedef struct st_mysql_res {  my_ulonglong row_count;  unsigned int  field_count, current_field;  MYSQL_FIELD   *fields;  MYSQL_DATA    *data;  MYSQL_ROWS    *data_cursor;  MEM_ROOT      field_alloc;  MYSQL_ROW     row;            /* If unbuffered read */  MYSQL_ROW     current_row;    /* buffer to current row */  unsigned long *lengths;       /* column lengths of current row */  MYSQL         *handle;        /* for unbuffered reads */  my_bool       eof;            /* Used my mysql_fetch_row */} MYSQL_RES;
 
MYSQL_ROW這是一個行數(shù)據(jù)的類型安全(type-safe)的表示。當(dāng)前它實現(xiàn)為一個計數(shù)字節(jié)的字符串?dāng)?shù)組。(如果字段值可能包含二進(jìn)制數(shù)據(jù),你不能將這些視為空終止串,因為這樣的值可以在內(nèi)部包含空字節(jié)) 行通過調(diào)用mysql_fetch_row()獲得。
typedef char **MYSQL_ROW;
MYSQL_FIELD 這個結(jié)構(gòu)包含字段信息,例如字段名、類型和大小。其成員在下面更詳細(xì)地描述。你可以通過重復(fù)調(diào)用mysql_fetch_field()對每一列獲得MYSQL_FIELD結(jié)構(gòu)。字段值不是這個結(jié)構(gòu)的部分;他們被包含在一個MYSQL_ROW結(jié)構(gòu)中。
 
typedef struct st_mysql_field {  char *name;                   /* Name of column */  char *table;                  /* Table of column if column was a field */  char *def;                    /* Default value (set by mysql_list_fields) */  enum enum_field_types type;   /* Type of field. Se mysql_com.h for types */  unsigned int length;          /* Width of column */  unsigned int max_length;      /* Max width of selected set */  unsigned int flags;           /* Div flags */  unsigned int decimals;        /* Number of decimals in field */} MYSQL_FIELD;
my_ulonglong typedef unsigned long my_ulonglong;
 
該類型用于行編號和mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()。這種類型提供0到1.84e19的一個范圍。在一些系統(tǒng)上,試圖打印類型my_ulonglong的值將不工作。為了打印出這樣的值,將它變換到unsigned long并且使用一個%lu打印格式。例如:
printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
 
連接MySQL,查詢數(shù)據(jù)現(xiàn)在假設(shè)MySQL已安裝, 用戶和數(shù)據(jù)表在數(shù)據(jù)庫被創(chuàng)造。以防有什么不明問題的情況, 請參考www.mysql.com 網(wǎng)站。
前面已經(jīng)說過,MySQL的庫文件在mysqlclient。因此在編譯MySQL程序的時候有必要加上-lmysqlclient編譯選項。MySQL的頭文件在/usr/include/mysql目錄下(根據(jù)Linux的發(fā)行版本的不同,這個目錄也有所不同),因此你的程序頭部看起來有點這個樣子:
#include <mysql.h>
 
MySQL的變量類型和函數(shù)都包含在這個頭文件當(dāng)中
然后,我們需要創(chuàng)建連接數(shù)據(jù)庫的變量,可以簡單地這么做:
MYSQL mysql;
在連接數(shù)據(jù)庫之前,我們要調(diào)用以下函數(shù)初始化這個變量:
mysql_init(&mysql);
然后,調(diào)用mysql_real_connect函數(shù):
MYSQL *         STDCALL 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 int clientflag);

    該函數(shù)被調(diào)用連接到數(shù)據(jù)庫。host是MySQL服務(wù)器的主機(jī)名,user是登錄的用戶名,passwd是登錄密碼,db是要連接的數(shù)據(jù)庫,port是MySQL服務(wù)器的TCP/IP端口,unix_socket是連接類型,clientflag是MySQL運行成ODBC數(shù)據(jù)庫的標(biāo)記。在這篇文章當(dāng)中該標(biāo)記設(shè)成0,連接尋建立后,這個函數(shù)返回0。
現(xiàn)在可以連接數(shù)據(jù)庫,進(jìn)行查詢了:
char *query;
 
使用這個字符串我們可以創(chuàng)立任何SQL查詢語句進(jìn)行查詢。執(zhí)行這個查詢的函數(shù)是:
int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned int length);
 
mysql是我們前面用過的變量,q是SQL查詢語句,length是這個查詢語句的長度。如果查詢成功,函數(shù)返回0。
查詢之后,我們要到一個MYSQL_RES變量來使用查詢的結(jié)果。以下這行創(chuàng)立這個變量:
MYSQL_RES *res;
 
然后
 
res = mysql_store_result(&mysql);

    對客戶端而言,有兩種方法處理結(jié)果集合。一種方法是通過調(diào)用mysql_store_result()立刻檢索全部結(jié)果。該函數(shù)從服務(wù)器獲得查詢返回的所有行,并將他們存儲在客戶端。第二種方法是對客戶通過調(diào)用mysql_use_result()初始化一個一行一行地結(jié)果集合的檢索。該函數(shù)初始化檢索,但是實際上不從服務(wù)器獲得任何行。
在兩種情況中,你通過mysql_fetch_row()存取行。用mysql_store_result()、mysql_fetch_row()儲存取已經(jīng)從服務(wù)器被取出的行。用mysql_use_result()、mysql_fetch_row()實際上從服務(wù)器檢索行。調(diào)用mysql_fetch_lengths()可獲得關(guān)于每行中數(shù)據(jù)值尺寸的信息。

    在你用完一個結(jié)果集合以后,調(diào)用mysql_free_result()釋放由它使用的內(nèi)存。
兩種檢索機(jī)制是互補(bǔ)的?蛻舫绦驊(yīng)該選擇最適合他們的要求的途徑。在實踐中,客戶通常更愿意使用mysql_store_result()。
該函數(shù)讀出查詢結(jié)果。
盡管可以很容易地查詢了,要用這個查詢的結(jié)果還要用到其它的函數(shù)。第一個是:
 
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
 
該函數(shù)把結(jié)果轉(zhuǎn)換成“數(shù)組”。你可能注意到了,該函數(shù)返回的是MYSQL_ROW變量類型。以下語句創(chuàng)立那樣的變量:
 
MYSQL_ROW row = mysql_fetch_row(res)

    如前所解釋的,變量row是一個字符串?dāng)?shù)組。也就是說,row[0]是數(shù)組的第一個值,row[1]是數(shù)組的第二個值...當(dāng)我們用mysql_fetch_row的時候,接著變量row會取得結(jié)果的下一組的數(shù)據(jù)。當(dāng)?shù)搅私Y(jié)果的尾部,該函數(shù)返回一負(fù)值。
使用數(shù)據(jù)集結(jié)束后,記得釋放數(shù)據(jù)集,否則會發(fā)生內(nèi)存泄漏,釋放數(shù)據(jù)集函數(shù)如下:
void mysql_free_result(MYSQL_RES *result)
 
釋放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等為一個結(jié)果集合分配的內(nèi)存。當(dāng)你用完了一個結(jié)果集合時,你必須調(diào)用mysql_free_result()來釋放它使用的內(nèi)存。
最后我們要關(guān)閉這個連接:
mysql_close(&mysql);
 
例子程序執(zhí)行一個select操作,從數(shù)據(jù)庫中取數(shù)據(jù),并執(zhí)行一個insert操作,往數(shù)據(jù)庫中插入數(shù)據(jù),根據(jù)這兩個操作你可以自由的擴(kuò)展為任意數(shù)據(jù)庫操作,
準(zhǔn)備條件1、已經(jīng)安裝mysql,上有數(shù)據(jù)庫test,如果沒有執(zhí)行
Create Databse test
建立數(shù)據(jù)庫
2、test數(shù)據(jù)庫上有表t1,如果沒有,執(zhí)行
CREATE TABLE `t1` (
  `id` int(11) default NULL,
  `name` varchar(100) default NULL
)
建立表t1
testsql.c: /* testsql.c
  ** An example to use MYSQL C API
  ** Copyright 2004 Coon Xu.
  ** Author: Coon Xu
  ** Date: 05 Nov 2004
  */
  
  #include <mysql.h>
  #include <stdio.h>int main(){
   MYSQL mysql;     // need a instance to init
   MYSQL_RES *res;
   MYSQL_ROW row;
   char *query;
   int t,r; // connect the database
   mysql_init(&mysql);
   if (!mysql_real_connect(&mysql,"localhost", "mmim", "mmim", "test",0,NULL,0))
   {
       printf( "Error connecting to database: %s\n",mysql_error(&mysql));
   }
   else printf("Connected...\n");
 // get the result from the executing select query
 query = "select * from t1";
  
 t = mysql_real_query(&mysql,query,(unsigned int) strlen(query));
 if (t)
 {
    printf("Error making query: %s\n",
      mysql_error(&mysql));
 }
 else printf("[%s] made...\n", query);  res = mysql_store_result(&mysql);  while(row = mysql_fetch_row(res))
 {
  for(t=0;t<mysql_num_fields(res);t++)
  {
   printf("%s ",row[t]);
  }
  printf("\n");
 }
 
 printf("mysql_free_result...\n");
 mysql_free_result(res);     //free result after you get the result
 
 sleep(1);   
 
 // execute the insert query
 query = "insert into t1(id, name) values(3, 'kunp')";
 t = mysql_real_query(&mysql,query,(unsigned int) strlen(query));
 if (t)
 {
    printf("Error making query: %s\n",
      mysql_error(&mysql));
 }
 else printf("[%s] made...\n", query);
  
    mysql_close(&mysql);
  
   return 0;
}
編譯
假定mysql的頭文件在/usr/include/mysql,庫文件在/usr/lib/mysql,執(zhí)行下列命令進(jìn)行編譯:
gcc testsql.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
 

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/kunp/archive/2004/11/05/168499.aspx
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP