用C语言连接Mysql数据库包含两个步骤:

1 初始化一个连接句柄结构

2 实际进行连接


使用mysql_init来初始化连接句柄

#include <mysql.h>

MYSQL * mysql_init(MYSQL *);

通常你传递NULL给这个例程,它会返回一个指向新分配的连接句柄结构的指针。如果你传递一个已有的结构,它将被重新初始化。这个例程在出错时返回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:指向已经被mysql_init初始化过的结构

server_host:可以是主机名,也可以是ip地址。如果只是连接到本地机器,你可以通过指定localhost来优化连接类型。

sql_user_name:数据库登录名

sql_password:数据库密码

db_name:数据库名

port_number:端口号(没改变Mysql默认设置,使用0表示默认值)

unix_socket_name:为NULL表示默认值

flags:用来对一些定义的位模式进行OR操作,使得改变使用协议的某些特性。


void mysql_close(MYSQL *connection);

关闭连接。如果连接是由mysql_init建立的,MySQL结构会被释放。指针将会失效并无法再次使用。保留一个不需要的连接是对资源的浪费,但是重新打开连接也会带来额外的开销,所以必须自己权衡何时使用这些选项。



mysql_options(仅能在mysql_init和mysql_real_connect之间调用)

int mysql_options(MYSQL *connection,enum option_to_set,const char *argument);

因为mysql_options一次只能设置一个选项,所以每设置一个选项就得调用它一次。你可以多次调用,只要它出现在mysql_init和mysql_real_connect之间即可。

列出3个最常用的选项,如下:

enum选项实际参数类型说明
MySQL_OPT_CONNECT_TIMEOUTconst unsigned int *连接超时之前的等待秒数
MySQL_OPT_COMPRESS使用NULL网络连接中使用压缩机制
MySQL_INIT_COMMANDconst char * 每次连接建立后发送的命令

一次成功的调用返回0。


以用户名root和密码yao来连接本机服务器上名为test的数据库

connect.c

#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
 int main(int argc,char **argv)
{
   MYSQL * conn_ptr;
                                                                                                                                                                                                                                                                                                                                                                                     
   conn_ptr = mysql_init(NULL);
   if(!conn_ptr)
  {
     perror("mysql_init failed\n");
     exit(1);
  }
  conn_ptr = mysql_real_connect(conn_ptr,"localhost","root","yao","test",0,NULL);
 if(conn_ptr)
{
  printf("connection success\n");
}
 else
{
  printf("connection failed\n");
}
                                                                                                                                                                                                                                                                                                                                                                                    
  mysql_close(conn_ptr);
                                                                                                                                                                                                                                                                                                                                                                                    
  return 0;
}


编译这个程序,需要同时添加include路径和库文件路径,以及指定链接的库模块mysqlclient。

gcc -I/usr/include/mysql connect.c -L/usr/lib/mysql -lmysqlclient -o connect


可能的错误:

Centos 6.4 64位系统下使用C语言访问Mysql 找不到mysqlclient


解决:

-L/usr/lib/mysql改为 -L/usr/lib64/mysql



错误处理

MySQL使用一系列由连接句柄结构报告的返回码。

unsigned int mysql_errno(MYSQL * connection);

char * mysql_error(MYSQL * connection);

通过调用mysql_errno并传递连接结构来获得错误码,通常都是非0值。如果未设定错误码,它将返回0。因为每次调用库都会更新错误码,所以你只能得到最后一个执行命令的错误码。上面两个错误检查函数是例外,它们不会导致错误码的更新。

mysql_errno的返回值实际上就是错误码,它们在头文件errmsg.h或mysqld_error.h中定义。这两个文件都可以在MySQL的include目录中找到。前者报告客户端错误,后者关注服务端错误。

如果喜欢文本信息错误,调用mysql_error,提供了有意义的文本信息,这些信息被写入一些内部静态内存空间中。


使用非动态分配的连接结构

#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
 int main(int argc,char **argv)
{
  MYSQL mysql_conn;
  mysql_init(&mysql_conn);
           if(mysql_real_connect(&mysql_conn,"localhost","root","dfdsfjfd","test",0,NULL))
{
  printf("connection success\n");
  mysql_close(&mysql_conn);
}
 else
{
  perror("connection failed\n");
  if(mysql_errno(&mysql_conn))
 {
   fprintf(stderr,"connection error %d:%s\n",mysql_errno(&mysql_conn),mysql_error(&mysql_conn));
 }
}
  return 0;
}

注:这里我使用动态分配的连接结构,错误信息不产生。


执行SQL语句

执行SQL语句的函数为

int mysql_query(MYSQL *connection,const char *query);

这个函数接受连接结构指针和文本字符串形式的有效SQL语句(没有结束的分号)。如果成功,返回0.对于包含二进制数据的查询,可以使用第二个函数mysql_real_query。


1 不返回数据的SQL语句

不返回任何数据的SQL语句:update delete insert


这里介绍另一个重要函数,用于检查首查询影响的行数

my_ulonglong mysql_affected_rows(MYSQL *connection);

这个函数的返回值类型很不常见,它使用无符号类型。当你使用printf时,推荐使用%lu格式将其转换为无符号长整数。这个函数返回受之前执行的update、insert或delete查询影响的行数。如果你使用过其他SQL数据库,MySQL返回的是被一个更新操作修改的行数,但许多其他数据库将仅仅因为记录匹配where子句就把它视为已经更新过。


插入一条数据

#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
 int main(int argc,char **argv)
{
  MYSQL mysql_conn;
  int res;
  mysql_init(&mysql_conn);
     if(mysql_real_connect(&mysql_conn,"localhost","root","yao","test",0,NULL))
{
  printf("connection success\n");
                                 
  res = mysql_query(&mysql_conn,"insert into child(childid,age,name) values (1,12,'bing')");
  if(!res)
 {
   printf("inserted %lu rows\n",(unsigned long)mysql_affected_rows(&mysql_conn));
 }
                                
 else
{
  fprintf(stderr,"insert error %d:%s",mysql_errno(&mysql_conn),mysql_error(&mysql_conn));
}
  mysql_close(&mysql_conn);
}
 else
{
  fprintf(stderr,"connection failed\n");
  if(mysql_errno(&mysql_conn))
 {
    fprintf(stderr,"Connection error %d:%s\n",mysql_errno(&mysql_conn),mysql_error(&mysql_conn));
 }
}
   return 0;
}

今天先到这,下次继续补充。。。