c语言连接mysql
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用C语言操作MySQL数据库2009年04月23日 13:00
1.连接数据库。
从C语言连接MySQL数据库包含两个步骤:
a)初始化连接句柄结构;
b)实际创建连接。
首先使用mysql_init初始化连接句柄:
MYSQL * mysql_init (MYSQL *);
通常传递一个空指针给mysql_init这个函数,它会返回一个指向新分配的连接句柄结构的指针。如果传递一个已有的结构,他将被重新初始化。如果出错,返回NULL。
初始化成功后,则使用mysql_real_connect来创建一个实际的连接:
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必须是已经初始化的连接句柄结构,server_host可以是主机名,也可以是IP地址,如果仅仅连接到本机,可以使用 localhost来优化连接类型。port_number和unix_socket_name应该分别为0和NULL,除非改变了MYSQL安装的默认 设置。
如果无法连接,返回NULL。完成连接后,在程序正常退出前,应该使用mysql_close关闭这个连接句柄。
void mysql_close(MYSQL * connection);
现在我们试图调用以上函数来建立一个对以上已经建好的数据库的访问,程序为connect1.c。内容如下:
#include
#include
#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); //建立实际连接
//参数分别为:初始化的连接句柄指针,主机名(或者IP),用户名,密码,数据库名,0,NULL,0)后面三个参数在默认安装mysql>的情况下不用改
if(conn_ptr){
printf("Connection success\n");
}
else {
printf("Connection failed\n");
}
mysql_close(conn_ptr); //关闭连接
return EXIT_SUCCESS;
}
然后编译:
#gcc -I/usr/include/mysql connect1.c -lmysqlclient -o connect1
connect1.c:4:19: 错误:mysql.h:没有那个文件或目录
提示是没有找到mysql.h,产生这个错误的原因是没有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发现可以在后面用-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已经在运行了:
sudo /etc/rc.d/init.d/mysqld restart
然后执行生成的可执行文件:
./connect1
Connection success
打印出了我们设计好了的连接成功的打印信息。这样就通过C语言进入了MySQL数据库了。
##########################################
#在以上这一段编译这个connect1.c的文件过程了,出过两次错误,分别记录如上,看起来 #
#解决的办法很简单,但是自己当时确实是很迷茫,不知什么原因,网上搜索的结果大都不得#
#要领,最终还是靠自己静下心来看gcc的手册,man gcc才解决。 #
#P.S. man gcc真长。 要冷静! #
##########################################
2. 操作数据库
进入数据库中之后,就可以开始对数据库进行读写操作了。
数据库的主要操作包括select, insert, update, delete四种。
a)sql语句的嵌入:
执行SQL语句的主要API函数是:
int mysql_query(MYSQL *connection, const char * query)
接受已经建立的连接结构指针和文本字符串形式的有效SQL语句(句末不用分号)。成功返回0。
还有一个比较重要的函数,mysql_affected_rows(),他返回无符号类型,当使用printf时,推荐使用%lu格式将其转换为无符号长整型。此函数返回受之前执行的update,delete,insert等查询影响的行数。
my_ulonglong mysql_affected_rows(MYSQL *connection);
MySQL返回被一个更新操作修改的行数,但其他许多数据库将仅仅因为记录匹配where字句而把它视为已经更新过。
通常对于mysql_函数,返回值0表示没有行受到影响,正数则是实际的结
果,一般表示受语句影响的行数。
b)select语句的使用:
select语句是SQL语句中使用最频繁的操作。
一个完整的提取数据过程应该包含以下四个步骤:执行查询,提取数据,处理数据,清理。
使用mysql_query来发送SQL语句,使用mysql_store_result或者mysql_use_result来提取数据。然后使用 mysql_fetch_row调用来处理数据,最后,使用mysql_free_result来释放查询占用的内存资源。
mysql_use_result和mysql_store_result都是返回一个指向结果集结构(result set structure)的指针,如果失败则返回NULL。区别在于store将查询到的数据库中的结果直接放在这个结果集中,而use则不直接将最终数据库 的数据结果放在这个结果集中。store其实就是把数据直接读到本地内存中,因此它比较适合数据量较小的查询。use则类似于一种流的操作,并不是一次就 返回所有的结果。因此,对于这个结果集,必须反复调用mysql_fetch_row直到提取所有的数据。
1)一次获取所有的数据:
MYSQL_RES *mysql_store_result(MYSQL *connection);
在成功调用mysql_query之后使用此函数,将立即保存在客户端中返回的所有数据,并将指向此结果集的指针返回。如果失败则返回NULL。
成功之后,可以用mysql_num_rows来得到返回记录的数目,一般应该是个正数,若没有返回行匹配,则返回0.
my_ulonglong mysql_num_rows(MYSQL_RES *result);
现在得到来数据,可使用mysql_fetch_row来处理它,也可以使用mysql_data_seek,mysql_row_seek和mysql_row_tell在数据集中来回移动。
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
此函数从上面得到的结果集中提取一行,并把它放在一个行结构中。当数据用完或者出错时返回NULL。
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
此函数允许结构集当前指针的跳转,设置会被下一个mysql_fetch_row操作返回的行。offset是行号,在0到总行数减1的范围内。传递0,则返回初始位置。
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);
此函数返回结果集的当前位置。不能把它用于mysql_data_seek。
完成来对数据的所有操作之后,必须调用mysql_free_result来让MYSQL数据库完成善后处理。
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)一次提取一行数据
建议使用这种提取数据的方式。它能取得更好的网络负载平衡,以及减少大数据集可能造成的存储过载。但是它也增加来时延,并且在特殊的情况下,比如网络链接在操作中途失败时,可能会得到不完整的数据甚至造成混乱。
此时依靠mysql_use_result:
MYSQL_RES *mysql_use_result(MYSQL * connection);
与store一样,出错返回NULL,成功则返回指向结果集对象的指针。
--------------------------------------使用范例---------------------------------------------------------
//这里只写取数据的部分
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这三个操作是不用返回任何数据的语句,他们都是使用mysql_query来执行语句。
--------------------------------------使用范例---------------------------------------------------------
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返回的是真正受到影响或者说是被改
变的行数,而不仅仅是匹配where字句的行数。
3 一个完整的显示数据库中元数据和数据的例子:
#include
#include
#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");
}
C语言对mysql数据库的操作 收藏
这已经是一相当老的话题。不过今天我才首次使用,把今天的一些体会写下来,也许能给一些新手带来一定的帮助,更重要的是供自己今后忘记的怎么使用而进行查阅的!
我们言归正传
1.头文件:
#include
#include
#include
2.定义一个MYSQL变量:
MYSQL mysql;
这里MYSQL是一个用于连接MySql数据库的变量。
在后面对mysql数据库的操作中,我们就用这个MYSQL变量作为句柄的。
3.定义数据库参数:
char host[32]=”localhost”;
char user[32]=”username”;
char passwd[32]=”pwd”;
char dbname[32]=”testdb”;
4.数据库操作
1).初始化数据库:
mysql_init(&mysql);
2).连接数据库:
mysql_real_connect(&mysql,host,user,passwd,dbname,0,NULL,0);
我们在操作时,可以对以上的函数进行if测试,如果初始化或者连接出错,作出相应提示,以便调试。
5.对数据库的操作:
Mysql_query(&mysql, “select * from testdb where condition”);
我们在实际操作中,为了更方便的使用程序中的某些变量,我们将会用到一个函数:
int sprintf(char *str, const char *format, …);
这个函数用来格式化我们的字符串,然后将变量按照给你的格式,赋给第一个参数。
我们使用这个方法方法可以很方便的使用我们的变量来对数据库进行操作。例如我们将要进行数据库的查询操作,我们就可以这样使用:
sprintf(sql,”select * from testdb where username = ‘%s’”, u_name);
然后使用mysql_query(&mysql, sql)进行查询。
其实大家已经注意到了,在sprintf函数中第二个参数是我们非常熟悉的sql语句,只不过在条件的右端使用了类似输出函数的格式符,因为我们使用了变量。当然,在没有变量的时候,我们可以省去第三个参数,但是这样,我们使用sprintf的作用也就随之消失了。
大家对sql语句的操作一定比我更加熟悉,因此,关于删除和修改的例子我们就不过列举了。
6.关闭数据库连接:
Mysql_close(&mysql);
也许大伙都使用过php对mysql进行操作。也许也已经发现,在c语言中,对mysql数据库的操作和php有很大的相似之处。
下面我赋上一段小小的代码,来结束这篇文档!:)希望大家给予指点。
#include
#include
#include
#include
#include
MYSQL mysql;
main(){
char host[32]=”localhost”; // mysql host
char user[32]=”username”;//mysql user name
char passwd[32]="pwd"; //mysql pwd
char dbname[32]=”testdb”;//mysql db
if( mysql_init(&mysql) == NULL )
{
syslog(LOG_USER|LOG_INFO,”inital mysql handle error\n”);
return 1;
}
if (mysql_real_connect(&mysql,host,user,passwd,dbname,0,NULL,0) == NULL)
{
syslog(LOG_USER|LOG_INFO, “Failed to connect to database: Error: %s\n”,mysql_error(&mysql));
return 1;
}
else syslog(LOG_USER|LOG_INFO, “connect to database: \n”);
printf(”connected to the db!\n”);
int a = find_ps();
printf(”the num is:%d\n”,a);
db_close();
return 0;}int db_close(){
mysql_close(&mysql);
return 0;
}
int find_ps (){
MYSQL_ROW m_row;
MYSQL_RES *m_res;
char sql[1024],username[32];
int res=1;
int *id;
sprintf(sql,”select * from testdb where user_name = ‘%s’”, u_name);
if(mysql_query(&mysql,sql) != 0)
{
syslog(LOG_USER|LOG_INFO, “select ps_info Error: %s\n”,mysql_error(&mysql));
return res;
}
m_res = mysql_store_result(&mysql);
if(m_res==NULL)
{
syslog(LOG_USER|LOG_INFO, “select username Error: %s\n”,mysql_error(&mysql));
res = 3;
return res;
}
}
mysql_free_result(m_res);
return res;}
7.编译:
别忘了加上库位置,否则编译无法通过!
gcc -L/usr/lib/mysql –lmysqlclient func.c -o func
呵呵,别忘记哦!
本文来自CSDN博客,转载请标明出处:/reachcool/archive/2006/10/10/1329193.aspx