MySQL之常用C API详述

一、C API数据类型

MYSQL: 该结构代表1个数据库连接的句柄。不应尝试拷贝MYSQL结构。不保证这类拷贝结果会有用。 
MYSQL_RES:  该结构代表返回行的查询结果(SELECT, SHOW, DESCRIBE, EXPLAIN)。
MYSQL_ROW: 这是1行数据的“类型安全”表示。行是通过调用mysql_fetch_row()获得的。它目前是按照计数字节字符串的数组实施的。  typedef char **MYSQL_ROW。MYSQL_ROW指针是一简单的字符串数组,所有的数据类型被转换成字符串送到客户端。
MYSQL_FIELD: 该结构包含关于字段的信息,如字段名、类型和大小。通过重复调用mysql_fetch_field(),可为每个字段获得MYSQL_FIELD结构。字段值不是该结构的组成部份,它们包含在MYSQL_ROW结构中。 
MYSQL_FIELD_OFFSET: 这是MySQL字段列表偏移量的“类型安全”表示(由mysql_field_seek()使用)。偏移量是行内的字段编号,从0开始。 
my_ulonglong: 用于行数以及mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()的类型。该类型提供的范围为0~1.84e19。 在某些系统上,不能打印类型my_ulonglong的值。要想打印这类值,请将其转换为无符号长整数类型并使用%lu打印格式,例如:
printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result)); 


二、C API函数概述
与MySQL交互时,应用程序应使用该一般性原则:
(1)通过调用mysql_library_init(),初始化MySQL库。库可以是mysqlclient C客户端库,或mysqld嵌入式服务器库,具体情况取决于应用程序是否与“-libmysqlclient”或“-libmysqld”标志链接。如果愿意,可省略对mysql_library_init()的调用,这是因为,必要时,mysql_init()会自动调用它。
(2)通过调用mysql_init()初始化连接处理程序,并通过调用mysql_real_connect()连接到服务器。
(3)发出SQL语句并处理其结果。当连接处于活动状态时,客户端或许会使用mysql_query()或mysql_real_query()向服务器发出SQL查询。两者的差别在于,mysql_query()预期的查询为指定的、由Null终结的字符串,而mysql_real_query()预期的是计数字符串。如果字符串包含二进制数据(其中可能包含Null字节),就必须使用mysql_real_query()。
      对于每个非SELECT查询(例如INSERT、UPDATE、DELETE),通过调用mysql_affected_rows(),可发现有多少行已被改变(影响)。
      对于SELECT查询,能够检索作为结果集的行。注意,某些语句因其返回行,类似与SELECT。包括SHOW、DESCRIBE和EXPLAIN。应按照对待SELECT语句的方式处理它们。
      客户端处理结果集的方式有两种:
      第一种方式是,通过调用mysql_store_result(),一次性地检索整个结果集。该函数能从服务器获得查询返回的所有行,并将它们保存在客户端。
      第二种方式是,针对客户端的,通过调用mysql_use_result(),对“按行”结果集检索进行初始化处理。该函数能初始化检索结果,但不能从服务器获得任何实际行。
      在这两种情况下,均能通过调用mysql_fetch_row()访问行。通过mysql_store_result(),mysql_fetch_row()能够访问以前从服务器获得的行。通过mysql_use_result(),mysql_fetch_row()能够实际地检索来自服务器的行。通过调用mysql_fetch_lengths(),能获得关于各行中数据大小的信息。完成结果集操作后,请调用mysql_free_result()释放结果集使用的内存。这两种检索机制是互补的。客户端程序应选择最能满足其要求的方法。
      实际上,客户端最常使用的是mysql_store_result()。mysql_store_result()的1个优点在于,由于将行全部提取到了客户端上,你不仅能连续访问行,还能使用mysql_data_seek()或mysql_row_seek()在结果集中向前或向后移动,以更改结果集内当前行的位置。通过调用mysql_num_rows(),还能发现有多少行。另一方面,对于大的结果集,mysql_store_result()所需的内存可能会很大,你很可能遇到内存溢出状况。
       通过重复调用mysql_fetch_field(),可以按顺序访问行内的字段信息,或者,通过调用mysql_fetch_field_direct(),能够在行内按字段编号访问字段信息。通过调用mysql_field_seek(),可以改变当前字段的光标位置。对字段光标的设置将影响后续的mysql_fetch_field()调用。此外,你也能通过调用mysql_fetch_fields(),一次性地获得关于字段的所有信息。为了检测和通报错误,MySQL提供了使用mysql_errno()和mysql_error()函数访问错误信息的机制。
(4)通过调用mysql_close(),关闭与MySQL服务器的连接。
(5)通过调用mysql_library_end(),结束MySQL库的使用。 


三、C API函数描述
(1)mysql_init()

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL *MYSQL *mysql_init(MYSQL *mysql) ;  
        分配或初始化与mysql_real_connect()相适应的MYSQL对象。如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时,将释放该对象。
(2)mysql_options()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg);   
         用于设置额外的连接选项,并影响连接的行为。可多次调用该函数来设置数个选项,但是应在mysql_init()之后、以及mysql_connect()或mysql_real_connect()之前调用mysql_options()。

(3)mysql_real_connect()

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL *mysql_real_connect(MYSQL *mysql,   
  2.                           const char *host,   
  3.                           const char *user,   
  4.                           const char *passwd,   
  5.                           const char *db,   
  6.                           unsigned int port,   
  7.                           const char *unix_socket,   
  8.                           unsigned long client_flag) ;  
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.   

         mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。在你能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect()必须成功完成。       

         如果连接成功,返回MYSQL*连接句柄。如果连接失败,返回NULL。对于成功的连接,返回值与第1个参数的值相同。 第1个参数mysql是已有MYSQL结构的地址,调用mysql_real_connect()之前,必须调用mysql_init()来初始化MYSQL结构,通过mysql_options()调用,可更改多种连接选项。 “host”的值必须是主机名或IP地址,如果“host”是NULL或字符串"localhost",连接将被视为与本地主机的连接。“user”参数包含用户的MySQL登录ID。如果“user”是NULL或空字符串"",用户将被视为当前用户。在UNIX环境下,它是当前的登录名。在Windows ODBC下,必须明确指定当前用户名。“passwd”参数包含用户的密码。“db”是数据库名称。如果db为NULL,连接会将默认的数据库设为该值。如果“port”不是0,其值将用作TCP/IP连接的端口号。注意,“host”参数决定了连接的类型。如果unix_socket不是NULL,该字符串描述了应使用的套接字或命名管道。client_flag的值通常为0。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL mysql;  
  2. mysql_init(&mysql);  
  3. mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");  
  4. if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))  
  5. {  
  6.     fprintf(stderr, "Failed to connect to database: Error: %s\n",  
  7.     mysql_error(&mysql));  
  8. }  
(4)mysql_query()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int mysql_query(MYSQL *mysql, const char *query) ;  
        执行由“Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含多条由分号隔开的语句。 如果查询成功,返回0。如果出现错误,返回非0值。
      mysql_query()不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之(二进制数据可能包含字符‘\0’,mysql_query()会将该字符解释为查询字符串结束)。
(5) mysql_real_query()
int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length); 
      执行由“query”指向的SQL查询,它应是字符串长度字节“long”。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含由分号隔开的多条语句。如果希望知道查询是否应返回结果集,可使用mysql_field_count()进行检查。
(6) mysql_store_result()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL_RES *mysql_store_result(MYSQL *mysql) ;  
        将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中。对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()或mysql_use_result() 。对于其他查询,不需要调用mysql_store_result()或mysql_use_result(),但是如果在任何情况下均调用了mysql_store_result(),它也不会导致任何伤害或性能降低。通过检查mysql_store_result()是否返回0,可检测查询是否没有结果集(以后会更多)。
         一旦调用了mysql_store_result()并获得了不是Null指针的结果, 可调用mysql_num_rows()来找出结果集中的行数,也可以调用mysql_num_fields()来获取结果集中的列数,或调用mysql_fetch_row()来获取结果集中的行,或调用mysql_row_seek()mysql_row_tell()来获取或设置结果集中的当前行位置。 一旦完成了对结果集的操作,必须调用mysql_free_result()。
(7)mysql_num_fields()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. unsigned int mysql_num_fields(MYSQL_RES *result);  
       返回结果集中的行数。要想传递MYSQL*参量取而代之,请使用无符号整数mysql_field_count(MYSQL *mysql)。
       你可以从指向结果集的指针或指向连接句柄的指针获得行数。如果mysql_store_result()或mysql_use_result()返回NULL,应使用连接句柄(因而没有结果集指针)。在该情况下,可调用mysql_field_count()来判断mysql_store_result()是否生成了非空结果。这样,客户端程序就能采取恰当的行动,而不需要知道查询是否是SELECT语句(或类似SELECT的语句)。
(8)mysql_num_rows()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. my_ulonglong mysql_num_rows(MYSQL_RES *result) ;  
      返回结果集中的行数。 mysql_num_rows()的使用取决于是否采用了mysql_store_result()或mysql_use_result()来返回结果集。如果使用了mysql_store_result(),可以立刻调用mysql_num_rows()。如果使用了mysql_use_result(),mysql_num_rows()不返回正确的值,直至检索了结果集中的所有行为止。
(9)mysql_fetch_row()
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);   
       该函数把结果转换成数组”, 下一行的MYSQL_ROW结构(检索结果集的下一行)。 如果没有更多要检索的行或出现了错误,返回NULL。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],访问这些值的指针。行中的NULL值由NULL指针指明。可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,字段为NULL,否则字段为空。 如执行MYSQL_ROW row = mysql_fetch_row(res);变量row是一个字符串数组。也就是说,row[0]是数组的第一个值,row[1]是数组的第二个值...
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. MYSQL_ROW row;  
  2. unsigned int num_fields;  
  3. unsigned int i;  
  4.    
  5. num_fields = mysql_num_fields(result);  
  6. while ((row = mysql_fetch_row(result)))  
  7. {  
  8.    unsigned long *lengths;  
  9.    lengths = mysql_fetch_lengths(result);  
  10.    for(i = 0; i < num_fields; i++)  
  11.    {  
  12.        printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");  
  13.    }  
  14.    printf("\n");  
  15. }  


[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <my_global.h>  
  4. #include <mysql.h>  
  5. #include <string.h>  
  6.   
  7. int main(int argc, char **agrv)  
  8. {  
  9.     char *host = "222.24.59.100";     
  10.     char *user = "ssss";  
  11.     char *password = "ssss";  
  12.     char *database = "school";  
  13.     unsigned int port = 3306;  //无符号整形  
  14.   
  15.     char sqltext[100] = {0};  
  16.   
  17.     MYSQL *con;  
  18.     con = mysql_init(NULL);  
  19.     if(con == NULL)  
  20.     {  
  21.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con));  
  22.         exit(1);  
  23.     }  
  24.   
  25.     if(mysql_real_connect(con, host, user, password, database, port, NULL, 0) == NULL)  
  26.     {  
  27.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con));  
  28.         exit(1);  
  29.     }  
  30.     printf("success to connect to database!\n");  
  31. /* 
  32.     sprintf(sqltext,"SET CHARACTER SET GBK"); //设置编码 
  33.     if(mysql_real_query(con,sqltext,(unsigned int)strlen(sqltext))); 
  34.     { 
  35.         printf("编码设置失败!\n"); 
  36.         exit(1); 
  37.     } 
  38. */  
  39.     sprintf(sqltext, "CREATE TABLE IF NOT EXISTS student(no varchar(10) unique  not null,name varchar(20) not null,class varchar(10) not null,birth_date datetime)");  
  40.     if(mysql_query(con, sqltext))//如果查询成功,返回0。如果出现错误,返回非0值。  
  41.     {  
  42.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con));  
  43.         exit(1);          
  44.     }  
  45. /* 
  46.     if(mysql_query(con, "INSERT INTO student(no,name,class,birth_date) VALUES('1203210001','Parry','0804','2008-09-01 12:23:12')")) 
  47.     { 
  48.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con)); 
  49.         exit(1);             
  50.     } 
  51.     if(mysql_query(con, "INSERT INTO student(no,name,class,birth_date) VALUES('1203210002','Jack','0803','2008-10-01 12:24:12')")) 
  52.     { 
  53.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con)); 
  54.         exit(1);             
  55.     } 
  56.     if(mysql_query(con, "INSERT INTO student(no,name,class,birth_date) VALUES('1203210003','Rose','0801','2008-08-01 10:02:58')")) 
  57.     { 
  58.         printf("error %u:%s.\n", mysql_errno(con), mysql_error(con)); 
  59.         exit(1);             
  60.     } 
  61.  
  62.     if(mysql_query(con, "select * from student")) 
  63.     { 
  64.         printf("Error %u: %s\n", mysql_errno(con), mysql_error(con)); 
  65.         exit(1); 
  66.     } 
  67. */  
  68.     sprintf(sqltext,"SELECT * FROM student WHERE birth_date='2008-09-01 12:24:12'");  
  69.     if(mysql_query(con, sqltext))  
  70.     {  
  71.         printf("Error %u: %s\n", mysql_errno(con), mysql_error(con));  
  72.         exit(1);  
  73.     }     
  74.   
  75.     MYSQL_RES *result;//保存结果集  
  76.     MYSQL_FIELD *result_field;//保存字段名字信息  
  77.     MYSQL_ROW row;  
  78.     int num_rows,num_fields;  
  79.     int i;  
  80.   
  81.     result = mysql_store_result(con);  
  82.     num_rows = mysql_num_rows(result);  
  83.     num_fields = mysql_num_fields(result);//获取查询结果中,字段的个数  
  84.   
  85.     printf("num_rows = %d , num_fields = %d\n\n", num_rows , num_fields);  
  86.   
  87.     while((row = mysql_fetch_row(result)))//遍历查询结果中的各行记录,从结果集中取出下一行数据  
  88.     {  
  89.         for(i = 0 ; i < num_fields ; i++)  
  90.         {  
  91.             printf("%s", row[i] ? row[i] : "NULL");  
  92.         }  
  93.         //printf("%s\n", row[3]);//调试行:取出第四个字段,显示时间  
  94.         printf("\n");  
  95.     }  
  96.   
  97.   
  98.     result_field = mysql_fetch_fields(result); //获取查询结果中,各个字段的名字;返回所有字段结构的数组,区别mysql_fetch_field:返回下一个字段的类型  
  99.     for(i = 0; i < num_fields;i++)  
  100.     {  
  101.         printf("field %u is %s\n",i,result_field[i].name);//获取的是字段名字(属性),而不是具体数值(字段值)  
  102.     }  
  103.   
  104.     mysql_free_result(result);  
  105.     mysql_close(con);  
  106. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值