码迷,mamicode.com
首页 > 数据库 > 详细

Mysql 中C API 的学生信息管理

时间:2015-01-20 15:49:14      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:mysql   api   c   



使用嵌入式MySQL服务器库,能够在客户端应用程序中使用具备全部特性的MySQL服务器。 主要优点在于,增加了速度,并使得嵌入式应用程序的管理更简单。

嵌入式服务器库是以MySQL的客户端/服务器版本为基础的,采用C/C++语言编写。 其结果是嵌入式服务器也是用C/C++语言编写的。 在其他语言中,嵌入式服务器不可用。

API与嵌入式MySQL版本和客户端/服务器版本等效。 要想更改旧的线程式应用程序以使用嵌入式库,正常情况下,仅需添加对下述函数的调用即可。

MySQL交互时,应用程序应使用该一般性原则:

1.    通过调用mysql_library_init(),初始化MySQL库。库可以是mysqlclient C客户端库,或mysqld嵌入式服务器库,具体情况取决于应用程序是否与“-libmysqlclient”或“-libmysqld”标志链接。

2.    通过调用mysql_init()初始化连接处理程序,并通过调用mysql_real_connect()连接到服务器。

3.    发出SQL语句并处理其结果。(在下面的讨论中,详细介绍了使用它的方法)。

4.    通过调用mysql_close(),关闭MySQL服务器的连接。

5.    通过调用mysql_library_end(),结束MySQL库的使用。

调用mysql_library_init()mysql_library_end()的目的在于,为MySQL库提供恰当的初始化和结束处理。对于与客户端库链接的应用程序,它们提供了改进的内存管理功能。如果不调用mysql_library_end(),内存块仍将保持分配状态(这不会增加应用程序使用的内存量,但某些内存泄漏检测器将抗议它)。对于与嵌入式服务器链接的应用程序,这些调用会启动并停止服务器。

mysql_library_init()mysql_library_end()实际上是#define符号,这类符号使得它们等效于mysql_server_init()mysql_server_end(),但其名称更清楚地指明,无论应用程序使用的是mysqlclientmysqld库,启动或结束MySQL库时,应调用它们。对于早期的MySQL版本,可调用mysql_server_init()mysql_server_end()取而代之。

如果愿意,可省略对mysql_library_init()的调用,这是因为,必要时,mysql_init()会自动调用它。

要想连接到服务器,可调用mysql_init()来初始化连接处理程序,然后用该处理程序(以及其他信息,如主机名、用户名和密码)调用mysql_real_connect()。建立连接后,在低于5.0.3版的API中,mysql_real_connect()会将再连接标志(MYSQL结构的一部分)设置为1,或在较新的版本中,将其设置为0。对于该标志,值“1”指明,如果因连接丢失而无法执行语句,放弃之前,会尝试再次连接到服务器。从MySQL 5.0.13开始,可以在mysql_options()上使用MYSQL_OPT_RECONNECT选项,以控制再连接行为。完成连接后,调用mysql_close()中止它。

当连接处于活动状态时,客户端或许会使用mysql_query()mysql_real_query()向服务器发出SQL查询。两者的差别在于,mysql_query()预期的查询为指定的、由Null终结的字符串,而mysql_real_query()预期的是计数字符串。如果字符串包含二进制数据(其中可能包含Null字节),就必须使用mysql_real_query()

对于每个非SELECT查询(例如INSERTUPDATEDELETE),通过调用mysql_affected_rows(),可发现有多少行已被改变(影响)。

对于SELECT查询,能够检索作为结果集的行。注意,某些语句因其返回行,类似与SELECT包括SHOWDESCRIBEEXPLAIN。应按照对待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_use_result()1个优点在于,客户端所需的用于结果集的内存较少,原因在于,一次它仅维护一行(由于分配开销较低,mysql_use_result()能更快)。它的缺点在于,你必须快速处理每一行以避免妨碍服务器,你不能随机访问结果集中的行(只能连续访问行),你不知道结果集中有多少行,直至全部检索了它们为止。不仅如此,即使在检索过程中你判定已找到所寻找的信息,也必须检索所有的行。

通过API,客户端能够恰当地对查询作出响应(仅在必要时检索行),而无需知道查询是否是SELECT查询。可以在每次mysql_query()mysql_real_query()后,通过调用mysql_store_result()完成该操作。如果结果集调用成功,查询为SELECT,而且能够读取行。如果结果集调用失败,可调用mysql_field_count()来判断结果是否的确是所预期的。如果mysql_field_count()返回0查询不返回数据(表明它是INSERTUPDATEDELETE等),而且不返回行。如果mysql_field_count()是非0值,查询应返回行,但没有返回行。这表明查询是失败了的SELECT。关于如何实现该操作的示例,请参见关于mysql_field_count()的介绍。

无论是mysql_store_result()还是mysql_use_result(),均允许你获取关于构成结果集的字段的信息(字段数目,它们的名称和类型等)。通过重复调用mysql_fetch_field(),可以按顺序访问行内的字段信息,或者,通过调用mysql_fetch_field_direct(),能够在行内按字段编号访问字段信息。通过调用mysql_field_seek(),可以改变当前字段的光标位置。对字段光标的设置将影响后续的mysql_fetch_field()调用。此外,你也能通过调用mysql_fetch_fields(),一次性地获得关于字段的所有信息。

为了检测和通报错误,MySQL提供了使用mysql_errno()mysql_error()函数访问错误信息的机制。它们能返回关于最近调用的函数的错误代码或错误消息,最近调用的函数可能成功也可能失败,这样,你就能判断错误是在何时出现的,以及错误是什么。


MysqlCAPI的学生信息管理系统

  1. 首先我是在fedora-8中进行的实验

  2. 我把mysql需要的库安装在/usr/lib下,头文件安装在/usr/include/mysql/mysql.h

  3. 利用 mysql中的C API对学生信息进行单个表格的管理。

部分源代码:

void Show(char Table_Name[]) //输出表格内容
{
	char str[25];
	
	sprintf(str, "select * from %s", Table_Name);
	mysql_real_query(mysql, str, (unsigned int)strlen(str));
	results = mysql_store_result(mysql);
	printf("\n");
	while((field = mysql_fetch_field(results)))
	{
		printf("%s\t\t", field->name);
	}printf("\n");
	while((record = mysql_fetch_row(results)))
	{
		num_fields = mysql_num_fields(results);
		for(i = 0; i < num_fields; i++)
		{
			printf("%s\t\t", record[i]);
		}printf("\n");
	}
	
	mysql_free_result(results);
}

void Insert(char Table_Name[])  //添加信息
{
	char str1[4][10];
	char str[30];
	
	printf("请输入名字: ");
	scanf("%s", str1[0]);
	printf("请输入学号: ");
	scanf("%s", str1[1]);
	printf("请输入数学成绩: ");
	scanf("%s", str1[2]);
	printf("请输入语文成绩: ");
	scanf("%s", str1[3]);
	
	sprintf(str, "Insert into %s values(\"%s\", \"%s\", \"%s\", \"%s\")", Table_Name,str1[0],str1[1],str1[2],str1[3]);
	printf("\n>>>%s\n", str);
	mysql_real_query(mysql, str, (unsigned int)strlen(str));
	printf(">>>添加成功!!!\n\n");
}

void Delete(char Table_Name[])  //删除信息
{
	char Delete_Name[10];
	char Delete_Str[40];
	
	printf("请输入要删除的信息的名字: ");
	scanf("%s", Delete_Name);
	sprintf(Delete_Str, "Delete from %s where name=\"%s\"", Table_Name, Delete_Name);
	printf("\n>>>%s\n", Delete_Str);
	mysql_real_query(mysql, Delete_Str, (unsigned int)strlen(Delete_Str));
	printf(">>>删除成功!!!\n\n");
}


void Find(char Table_Name[]) //修改信息
{
	char Find_Str[40];
	char Find_Name[10];
	
	printf("请选择要查询的名字: ");
	scanf("%s", Find_Name);

	sprintf(Find_Str,"select * from %s where name=\"%s\"", Table_Name, Find_Name);
	printf("\n>>>%s\n", Find_Str);
	/*执行指定为“以Null终结的字符串”的SQL查询*/
	mysql_real_query(mysql, Find_Str, (unsigned int)strlen(Find_Str));
	
	results = mysql_store_result(mysql);	//能够访问以前从服务器获得的行
	printf(">>>共有%d条信息\n\n", *results);
	while((field = mysql_fetch_field(results)))
	{
		printf("%s\t\t", field->name);
	}printf("\n");
	while((record = mysql_fetch_row(results)))   //能够访问以前从服务器获得的行
	{
		num_fields = mysql_num_fields(results);
		for(i = 0; i < num_fields; i++)
		{
			printf("%s\t\t", record[i]);
		}
		printf("\n");
	}
	printf("\n");
}

以上只是部分简单的功能,还有更多功能请参考:http://download.csdn.net/detail/u013930856/8377673






Mysql 中C API 的学生信息管理

标签:mysql   api   c   

原文地址:http://blog.csdn.net/u013930856/article/details/42917629

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!