Jun
06


2008-06-06 8:19 pm 作者:tangfl.openid.35.com

简介

C APIs包含在mysqlclient库文件当中与MySQL的源代码一块发行,用于连接到数据库和执行数据库查询。有一些例子在MySQL原代码的clients目录里。

MySQL C 变量类型

以下变量类型在MySQL的库当中定义。我们需要这些变量是为了使用MySQL的函数。这些变量有详细的解释,但是这些解释对于写代码来说并不重要。

MYSQL

要连接MYSQL,必须建立MYSQL实例,通过mysql_init初始化方能开始进行连接。

typedef struct st_mysql {
NET           net;            /* Communication parameters */
gptr          connector_fd;   /* ConnectorFd for SSL */
char          *host,*user,*passwd,*unix_socket,
*server_version,*host_info,*info,*db;
unsigned int  port,client_flag,server_capabilities;
unsigned int  protocol_version;
unsigned int  field_count;
unsigned int  server_status;
unsigned long thread_id;      /* Id for connection in server */
my_ulonglong affected_rows;
my_ulonglong insert_id;       /* id if insert on table with NEXTNR */
my_ulonglong extra_info;              /* Used by mysqlshow */
unsigned long packet_length;
enum mysql_status status;
MYSQL_FIELD   *fields;
MEM_ROOT      field_alloc;
my_bool       free_me;        /* If free in mysql_close */
my_bool       reconnect;      /* set to 1 if automatic reconnect */
struct st_mysql_options options;
char          scramble_buff[9];
struct charset_info_st *charset;
unsigned int  server_language;
} MYSQL;

MYSQL_RES

这个结构代表返回行的一个查询的(SELECT, SHOW, DESCRIBE, EXPLAIN)的结果。返回的数据称为“数据集”,在C的API里对应的就是MYSQL_RES,从数据库读取数据,最后就是从MYSQL_RES中读取数据。

typedef struct st_mysql_res {
my_ulonglong row_count;
unsigned int  field_count, current_field;
MYSQL_FIELD   *fields;
MYSQL_DATA    *data;
MYSQL_ROWS    *data_cursor;
MEM_ROOT      field_alloc;
MYSQL_ROW     row;            /* If unbuffered read */
MYSQL_ROW     current_row;    /* buffer to current row */
unsigned long *lengths;       /* column lengths of current row */
MYSQL         *handle;        /* for unbuffered reads */
my_bool       eof;            /* Used my mysql_fetch_row */
} MYSQL_RES;

MYSQL_ROW

这是一个行数据的类型安全(type-safe)的表示。当前它实现为一个计数字节的字符串数组。(如果字段值可能包含二进制数据,你不能将这些视为空终止串,因为这样的值可以在内部包含空字节) 行通过调用mysql_fetch_row()获得。

typedef char **MYSQL_ROW;

MYSQL_FIELD

这个结构包含字段信息,例如字段名、类型和大小。其成员在下面更详细地描述。你可以通过重复调用mysql_fetch_field()对每一列获得MYSQL_FIELD结构。字段值不是这个结构的部分;它们被包含在一个MYSQL_ROW结构中。

typedef struct st_mysql_field {
char *name;                   /* Name of column */
char *table;                  /* Table of column if column was a field */
char *def;                    /* Default value (set by mysql_list_fields) */
enum enum_field_types type;   /* Type of field. Se mysql_com.h for types */
unsigned int length;          /* Width of column */
unsigned int max_length;      /* Max width of selected set */
unsigned int flags;           /* Div flags */
unsigned int decimals;        /* Number of decimals in field */
} MYSQL_FIELD;

my_ulonglong
typedef unsigned long my_ulonglong;

该类型用于行编号和mysql_affected_rows()、mysql_num_rows()和mysql_insert_id()。这种类型提供 0到1.84e19的一个范围。在一些系统上,试图打印类型my_ulonglong的值将不工作。为了打印出这样的值,将它变换到unsigned long并且使用一个%lu打印格式。例如:

printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));

连接MySQL,查询数据

MySQL的库文件在mysqlclient,因此在编译MySQL程序的时候有必要加上-lmysqlclient编译选项。
MySQL 的头文件在/usr/include/mysql目录下(根据Linux的发行版本的不同,这个目录也有所不同),因此你的程序头部看起来有点这个样子:

#include <mysql.h>

MySQL的变量类型和函数都包含在这个头文件当中

然后,我们需要创建连接数据库的变量,可以简单地这么做:

MYSQL mysql;

在连接数据库之前,先调用以下函数初始化这个变量:

mysql_init(&mysql);

然后,调用mysql_real_connect函数:

MYSQL *         STDCALL 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 int clientflag);

该函数被调用连接到数据库。host是MySQL服务器的主机名,user是登录的用户名,passwd是登录密码,db是要连接的数据库,port是 MySQL服务器的TCP/IP端口,unix_socket是连接类型,clientflag是MySQL运行成ODBC数据库的标记。连接寻建立后,这个函数返回0。

现在可以连接数据库,进行查询了:

char *query;

使用这个字符串我们可以创立任何SQL查询语句进行查询。执行这个查询的函数是:

int STDCALL mysql_real_query(MYSQL *mysql, const char *q, unsigned int length);

mysql是我们前面用过的变量,q是SQL查询语句,length是这个查询语句的长度。如果查询成功,函数返回0。

查询之后,我们要到一个MYSQL_RES变量来使用查询的结果。以下这行创立这个变量:

MYSQL_RES *res;

然后

 res = mysql_store_result(&mysql);

对客户端而言,有两种方法处理结果集合。一种方法是通过调用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_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);

该函数把结果转换成“数组”。你可能注意到了,该函数返回的是MYSQL_ROW变量类型。以下语句创立那样的变量:

 MYSQL_ROW row = mysql_fetch_row(res)

如前所解释的,变量row是一个字符串数组。也就是说,row[0]是数组的第一个值,row[1]是数组的第二个值...当我们用mysql_fetch_row的时候,接着变量row会取得结果的下一组的数据。当到了结果的尾部,该函数返回一负值。

使用数据集结束后,记得释放数据集,否则会发生内存泄漏,释放数据集函数如下:

void mysql_free_result(MYSQL_RES *result)

释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为一个结果集合分配的内存。当你用完了一个结果集合时,你必须调用mysql_free_result()来释放它使用的内存。

最后我们要关闭这个连接:

mysql_close(&mysql);

例子程序

执行一个select操作,从数据库中取数据,并执行一个insert操作,往数据库中插入数据,根据这两个操作你可以自由的扩展为任意数据库操作,
准备条件

1、已经安装mysql,上有数据库test,如果没有执行Create Databse test

建立数据库

2、test数据库上有表t1,如果没有,执行CREATE TABLE `t1` (
`id` int(11) default NULL,
`name` varchar(100) default NULL
)

建立表t1
testsql.c:

  #include <mysql.h>
#include <stdio.h>
int main(){
MYSQL mysql;     // need a instance to init
MYSQL_RES *res;
MYSQL_ROW row;
char *query;
int t,r;
// connect the database
mysql_init(&mysql);
if (!mysql_real_connect(&mysql,"localhost", "mmim", "mmim", "test",0,NULL,0))
{
printf( "Error connecting to database: %s\n",mysql_error(&mysql));
}
else printf("Connected...\n");

// get the result from the executing select query
query = "select * from t1";

t = mysql_real_query(&mysql,query,(unsigned int) strlen(query));
if (t)
{
printf("Error making query: %s\n",
mysql_error(&mysql));
}
else printf("[%s] made...\n", query);
res = mysql_store_result(&mysql);
while(row = mysql_fetch_row(res))
{
for(t=0;t<mysql_num_fields(res);t++)
{
printf("%s ",row[t]);
}
printf("\n");
}

printf("mysql_free_result...\n");
mysql_free_result(res);     //free result after you get the result

sleep(1);

// execute the insert query
query = "insert into t1(id, name) values(3, 'kunp')";
t = mysql_real_query(&mysql,query,(unsigned int) strlen(query));
if (t)
{
printf("Error making query: %s\n",
mysql_error(&mysql));
}
else printf("[%s] made...\n", query);

mysql_close(&mysql);

return 0;
}

编译

假定mysql的头文件在/usr/include/mysql,库文件在/usr/lib/mysql,执行下列命令进行编译:
gcc testsql.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient

推荐(0)
收藏

发表评论:

得到OpenID
使用OpenID提供商
35OpenID 35OpenID MyOpenID MyOpenID Flickr Flickr
Google Google Yahoo Yahoo! AOL AOL
Blogger Blogger LiveJournal LiveJournal Verisign Verisign
ClaimID ClaimID Technorati Technorati Vidoop Vidoop
OpenID OpenID 帮助
您还没有登录,请登录后继续操作。
提示:您必需打开Cookie才能使用本系统
请输入您的 OpenID OpenID 登录:
例如:http://yourname.openid.35.com
close