C语⾔实现程序连接数据库并实现简单的嵌⼊式服务器
我们可以直接访问数据库,当然我们也需要在程序中连接数据库。
接下来我将介绍嵌⼊式MySQL服务器库。
使⽤嵌⼊式 MySQL 服务器库, 能够在客户端应⽤程序中使⽤具备全部特性的 MySQL 服务器。 主要优点在于,增加了速度,并使得嵌⼊式应⽤程序的管理更简单。嵌⼊式服务器库是以 MySQL 的客户端/ 服务器版本为基础的, 采⽤ C/C++语⾔编写。 其结果是嵌⼊式服务器也是⽤ C/C++语⾔编写的。 在其他语⾔中, 嵌⼊式服务器不可⽤。
具体简单步骤:
1.获取或者初始化MYSQL结构
⾸先MYSQL是⼀个结构类型,该结构代表 1 个数据库连接的句柄。 ⼏乎所有的 MySQL 函数均使⽤它。
函数介绍
MYSQL *mysql_init(MYSQL *mysql)
/*
分配或初始化与 mysql_real_connect()相适应的 MYSQL 对象。如果 mysql 是 NULL 指针,
该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址。如果
mysql_init()分配了新的对象,当调⽤ mysql_close()来关闭连接时。将释放该对象。
初始化的 MYSQL*句柄。如果⽆⾜够内存以分配新的对象,返回 NULL。
*/
我们来获得⼀个句柄
MYSQL *mysql =mysql_init(NULL);//获得数据库连接的句柄,分配或初始化与 mysql_real_connect()相适应的 MYSQL 对象
if(mysql == null){
printf("mysql_init error!\n");
return-1;
}
2.尝试与数据库引擎建⽴连接
我们会⽤到⼀个函数
函数介绍
MYSQL *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 long client_flag)
/*
描述:mysql_real_connect()尝试与运⾏在主机上的 MySQL 数据库引擎建⽴连接。在你能够执⾏
需要有效 MySQL 连接句柄结构的任何其他 API 函数之前, mysql_real_connect()必须成功完成。
第 1 个参数应是已有 MYSQL 结构的地址。调⽤ mysql_real_connect()之前,必须调
purchasedcooling⽤ mysql_init()来初始化 MYSQL 结构。
“host”的值必须是主机名或 IP 地址。如果“host”是 NULL 或字符串"localhost",连接
将被视为与本地主机的连接。
“user”参数包含⽤户的 MySQL 登录 ID。如果“user”是 NULL 或空字符串"",⽤户将
被视为当前⽤户。
“passwd”参数包含⽤户的密码。如果“passwd”是 NULL,仅会对该⽤户的(拥有 1
个空密码字段的)⽤户表中的条⽬进⾏匹配检查。
“db”是数据库名称。如果 db 为 NULL,连接会将默认的数据库设为该值。
如果“port”不是 0,其值将⽤作 TCP/IP 连接的端⼝号。
如果 unix_socket 不是 NULL,该字符串描述了应使⽤的套接字或命名管道。
client_flag 的值通常为 0,
*/
我们来尝试连接
mysql =mysql_real_connect(mysql,"localhost(主机)","root(⽤户)","password(密码)","databases(数据库名称)",3306,NULL,0);
if(mysql ==NULL){
printf("mysql_real_connect error:%s\n",mysql_error(mysql));
//mysql_error()这个函数返回上次调⽤的MYSQL函数的错误信息,是⼀串以null终结的字符串
return-1;
}
3.执⾏SQL语句
连接上数据库后,我们就可以执⾏SQL语句了,这些语句可以是DDL,DQL,DML等等语句,由⽤户⾃⼰输⼊。
函数介绍
mysql_query(MYSQL *mysql,const char*sql);
/*
执⾏由“Null 终结的字符串”查询指向的 SQL 查询。正常情况下,字符串必须包含 1 条 SQL
语句,⽽且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执⾏,字符串可包含多条由分号隔开的语句。
如果希望了解查询是否应返回结果集,可使⽤ mysql_field_count()进⾏检查
如果查询成功,返回 0。如果出现错误,返回⾮ 0 值。
*/
接下来我们⾃⼰输⼊想要执⾏的SQL语句
char query[1024]={};
printf("mysql>");
gets(query);
if(strcmp(query,"quit")==0||strcmp(query,"exit")==0){
//当输⼊的sql语句是quit或者exit时,退出该嵌⼊式服务器
printf("Bye!\n");
break;
}
mysql_query(mysql,"set names utf8");
//这⾏代码的作⽤是当设置环境为utf-8编码,
//如果不设置,很有可能中⽂字符⽆法正常显⽰,会显⽰为⼀堆乱码
c中的switch语句 例子int ret =mysql_query(mysql,query);onbeforeunload和onunload区别
//执⾏sql语句
if(ret !=0){
printf("mysql_query error:%s\n",mysql_error(mysql));
continue;
}
4.获得结果集
当我们执⾏完⼀条sql语句后,可能有结果集,也有可能没有结果集,所以接下来我们将会⽤个函数来接收⼀个结果集。
函数介绍
MYSQL_RES *mysql_store_result(MYSQL *mysql);
/*
对于成功检索了数据的每个查询(SELECT、 SHOW、 DESCRIBE、 EXPLAIN、 CHECKTABLE 等),
必须调⽤ mysql_store_result()或 mysql_use_result()
于其他查询,不需要调⽤ mysql_store_result()或 mysql_use_result(),但是如果在任何情
况下均调⽤了 mysql_store_result(),它也不会导致任何伤害或性能降低。通过检查
mysql_store_result()是否返回 0,
如果查询未返回结果集, mysql_store_result()将返回 Null 指针(例如,如果查询是 INSERT
语句)。
如果读取结果集失败, mysql_store_result()还会返回 Null 指针。通过检查 mysql_error()是
否返回⾮空字符串, mysql_errno()是否返回⾮ 0 值,或 mysql_field_count()是否返回 0,可
以检查是否出现了错误。
如果未返回⾏,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。
*/
那我们看⼀下执⾏完sql语句后的结果集如何
我们还需要介绍⼀下另外⼀个结构体MYSQL_RES,该结构代表返回⾏的查询结果(SELECT, SHOW, DESCRIBE, EXPLAIN) 。
MYSQL *result =mysql_store_result(mysql);
if(result ==NULL){
if(mysql_errno(mysql)!=0){
printf("mysql_store_result error:%s\n",mysql_error(mysql));
return-1;
}else{
printf("Query OK!\n");
continue;
}
/*
有必要解释这⼏⾏代码,当result为空的时候,会有两种情况,第⼀种就是出现了错误,
//那我们需要显⽰错误信息,当发⽣错误时,mysql_errno()会返回上次调⽤的 MySQL 函数的错误编号,
//这个编码为⾮0值,所以当mysql_errno(mysql) != 0时就是表⽰发⽣了错误。
所以当mysql_errno(mysql) == 0时表⽰没有出现错误,但是没有结果集,
//⽐如当我们执⾏DML,DDL,TCL语句时就不会反回结果,这回返回影响了⼏条记录,⽐如"Query OK, 1 row affected (0.00 sec)"
*/
}
5.显⽰结果集
当我们获得结果集后,就需要显⽰结果集了,⾸先我们需要知道这个结果集中⼀⾏(即⼀条记录,元组)的信息,这时候我们⼜有了另外两个结构体类型 MYSQL_ROWh和MYSQL_FIELD。
MYSQL_ROW这是 1 ⾏数据的“类型安全”表⽰。 它⽬前是按照计数字节字符串的数组实施的。 (如果字段值可能包含⼆进制数据, 不能将其当作由 Null 终结的字符串对待, 这是因为这类值可能会包含 Null 字节) 。 ⾏是通过调⽤ mysql_fetch_row()获得的。
MYSQL_FIELD该结构包含关于字段的信息, 如字段名、 类型和⼤⼩。 这⾥详细介绍了其成员。 通过重复调⽤ mysql_fetch_field(),可为每个字段获得 MYSQL_FIELD 结构。 字段值不是该结构的组成部份, 它们包含在 MYSQL_ROW 结构中。
接下来我们看⼀下该如何显⽰结果集
函数介绍
unsigned int mysql_num_fields(MYSQL_RES *result);
//返回结果集中的⾏数。注意,你可以从指向结果集的指针或指向连接句柄的指针获得⾏数。
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);
//对于结果集,返回所有 MYSQL_FIELD 结构的数组。每个结构提供了结果集中 1 列的字段定义。
my_ulonglong mysql_num_rows(MYSQL_RES *result);
//返回结果集中的⾏数。
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
//检索结果集的下⼀⾏。在 mysql_store_result()之后使⽤时,如果没有要检索的⾏,
//mysql_fetch_row()返回 NULL。在 mysql_use_result()之后使⽤时,如果没有要检索的⾏或出现了
//错误, mysql_fetch_row()返回 NULL。
具体代码实现
unsigned int fields =mysql_num_fields(result);
MYSQL_ROW record;
MYSQL_FIELD *fl =mysql_fetch_field(result);
size_t i;
printf("**************************\n");
for(i=0;i<fields;i++){
printf("%-15s ",fl[i].name);
}
printf("\n");
while(record =mysql_fetch_row(result)){
for(i=0;i<fileds;i++){
printf("%-10s ",record[i]);
}
printf("\n");
}
my_ulonglong rows =mysql_num_rows(result);
printf("%lu rows in set (0.012 sec)\n",(unsigned long int)(rows));
6.释放资源,关闭连接
当我们完成数据库的操作后,需要释放资源和关闭连接,否则会出现其他许多问题。函数介绍
void mysql_free_result(MYSQL_RES *result);
//释放由 mysql_store_result()、 mysql_use_result()、 mysql_list_dbs()等为结果集分配的内存。//完成对结果集的操作后,必须调⽤ mysql_free_result()释放结果集使⽤的内存
void mysql_close(MYSQL *mysql);
//关闭前⾯打开的连接。如果句柄是由 mysql_init()或 mysql_connect()⾃动分配的,
//mysql_close()还将解除分配由 mysql 指向的连接句柄。
最后我们关闭连接,释放资源
if(result !=NULL){
//如果当我们执⾏的第⼀句sql语句就是exit或者quit时,此时result仍未null,
控件类型有哪三种//那这时候不需要释放,如果强⾏释放就会产⽣段错误.
mysql_free_result(result);
}
mysql_close(mysql);
7.全部源代码
最后我们以这份源代码收尾
#include<mysql/mysql.h>
#include<stdio.h>
int main(){
mysql无法连接到服务器MYSQL *mysql =mysql_init(NULL);
if(mysql ==NULL){
printf("mysql_init error!\n");
return-1;
}
mysql =mysql_real_connect(mysql,"localhost","root","123456","test",3306,NULL,0);
//这⾥需要根据每个数据库的具体数据来写参数
if(mysql ==NULL){
printf("mysql_real_connect error:%s\n",mysql_error(mysql));
return-1;
staking}
MYSQL_RES *result=NULL;
while(1){
char query[1024]={};
printf("mysql>");
gets(query);
if(strcmp(query,"quit")==0||strcmp(query,"exit")==0){
printf("Bye\n");
break;
}
mysql_query(mysql,"set names utf8");
int ret =mysql_query(mysql,query);
if(ret !=0){
printf("mysql_query error:%s\n",mysql_error(mysql));
continue;
}
result =mysql_store_result(mysql);//获得结果集
if(result ==NULL){
if(mysql_errno(mysql)!=(unsigned int)(0)){
printf("mysql_store_result error:%s\n",mysql_error(mysql));
return-1;
}else{
continue;
}
}
unsigned int fields =mysql_num_fields(result);
MYSQL_ROW record;
MYSQL_FIELD *fl =mysql_fetch_field(result);
size_t i;
printf("**************************\n");
for(i=0;i<fields;i++){
printf("%-15s ",fl[i].name);
}
printf("\n");
while(record =mysql_fetch_row(result)){
for(i=0;i<fields;i++){
printf("%-10s ",record[i]);
}
printf("\n");
}
my_ulonglong rows =mysql_num_rows(result);
printf("%lu rows in set (0.012 sec)\n",(unsigned long int)(rows));
}
if(result!=NULL){
mysql_free_result(result);
}
mysql_close(mysql);
return0;
}
在运⾏这段程序前,我们还需要下载⼀个库libmysqlclient或者,平台不同要下载的东西也不同,但是⼤致都⼀样。
8.运⾏效果
最后的最后我们来看⼀下结果怎么样?
BYEBYE;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论