1. 初始化一个连接句柄
MYSQL *mysql_init(MYSQL *);
正确:返回一个指向新分配的链接句柄结构的指针
错误:NULL
注:该函数的传入参数通常为NULL即可。
2. 建立物理连接
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即为访问数据库的用户名和密码,如果sql_user_name为空,那么默认为当前Linux user的用户名,如果sql_password为空,那么只能访问不需要密码的数据。密码在经网络传输之前都经过加密处理。通常情况下,如果你没有改变MySQL的默认安装,port_number和*unix_socket_name的值分别为0和NULL即可,他们默认为当前相应值。flags参数允许我们改变当前使用协议的特性,默认情况下,置0即可。
如果连接不成功,该函数返回NULL
3. 断开连接
void mysql_close(MYSQL *connection);
使用该函数可以断开指定的链接。不让不需要的连接断开会浪费资源,但重新建立连接需要额外开销,在实际工作中我们可根据需要权衡。
4. 选项设置
int mysql_options(MYSQL *connection, enum option_to_set,
const char *argument);
该函数可用在mysql_init和mysql_real_connect之间来设置一些连接选项,option_to_set参数如MYSQL_OPT_CONNECT_TIMEOUT用来设置连接超时的时间(秒),MYSQL_OPT_COMPRESS表示在网络传输中对数据进行压缩,而MYSQL_INIT_COMMAND指定每当连接建立时用来发送的命令。
函数成功时返回0,因为该函数仅仅用来设置选项,所以失败意味着使用了无效的选项。此外,该函数每次只能设置一种选项,所以每设置一个选项就必须调用该函数一次。
举例:
unsigned int timeout = 7;
connection = mysql_init(NULL);
ret = mysql_options(connection, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
if (ret) {
/* Handle error */
...
}
connection = mysql_real_connect(connection ...
5. 错误处理
unsigned int mysql_errno(MYSQL *connection);
char *mysql_error(MYSQL *connection);
错误代码为非0值
举例:
if (mysql_errno(&my_connection)) {
fprintf(stderr, “Connection error %d: %s/n”, mysql_errno(&my_connection),
mysql_error(&my_connection));
6. 执行SQL命令
int mysql_query(MYSQL *connection, const char *query)
该函数用来执行SQL命令,如果执行成功则返回0。如果涉及二进制数据,可使用mysql_real_query这个函数
my_ulonglong mysql_affected_rows(MYSQL *connection);
该函数返回被update,insert,delete等查询命令影响的行数,返回值为unsigned Long(使用printf时需使用“lu"格式。当使用update命令时,该函数返回实际影响的行,而不是与where语句的匹配值(有些行已经是我们需要的那样,所以无需update)。如果我们希望该函数update的返回值与我们希望的那样,我们需要在mysql_real_connect函数中使用CLIENT_FOUND_ROWS flag,如
if (mysql_real_connect(&my_connection, “localhost”,
“rick”, “secret”, “foo”, 0, NULL, CLIENT_FOUND_ROWS)) {
此外,当我们使用delete命令删除整个表时,此函数返回0。
MySQL提供了LAST_INSERT_ID()函数来获取上次插入操作AUTO_INCREMENT列的数值,如SELECT LAST_INSERT_ID();即可在mysql_query函数中使用该语句。
举例:
res = mysql_query(&my_connection, “SELECT LAST_INSERT_ID()”);
if (res) {
printf(“SELECT error: %s/n”, mysql_error(&my_connection));
} else {
res_ptr = mysql_use_result(&my_connection);
if (res_ptr) {
while ((sqlrow = mysql_fetch_row(res_ptr))) {
printf(“We inserted childno %s/n”, sqlrow[0]);
}
mysql_free_result(res_ptr);
}
7. 数据控制
MYSQL_RES *mysql_store_result(MYSQL *connection);
该函数成功时返回一个指向返回集的指针,否则返回NULL。
my_ulonglong mysql_num_rows(MYSQL_RES *result);
该函数获取返回集中的行数,若为0表示没有返回行。
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
该函数从mysql_store_result返回集中取出一行,当没有数据或者出差时返回NULL
void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset);
该函数用于设置下一个被mysql_fetch_row取出的行,offset的值在0到rownum-1之间,当offset的值为0时,下一次用mysql_fetch_row取出的行就是返回集中的第一行。
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result);
该函数用于获取返回集中当前指针的位置,并不是行数,所以不能与mysql_data_seek函数一 起使用
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset);
该函数用于移动返回集中指针的位置并返回先前的位置
void mysql_free_result(MYSQL_RES *result);
该函数用于释放返回集。
MYSQL_RES *mysql_use_result(MYSQL *connection);
该函数并不像mysql_store_result那样将数据存储到返回集中,而是返回一个返回集对象指针,所以你必须返回使用mysql_fetch_row取回数据,这对于大的数据集来说可以减少客户端的存储空间。此外,先前的mysql_data_seek,mysql_row_tell,mysql_row_seek也不能在此使用,mysql_num_rows函数只有在所有数据都被检索出后才能为我所用。
8. 数据处理
unsigned int mysql_field_count(MYSQL *connection);
通常,该函数获取返回集中数据的列数。此外,我们还可以将该函数用于其它情况,比如说确定mysql_store_result函数失败的原因;如果mysql_store_result返回NULL,而mysql_filed_count返回了一个大于0的数,说明是检索错误,但如果mysql_field_count返回0,则表明为存储错误。
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);
该函数可获得与列字段相关信息的结构指针,包括如下等字段
char *name 列的名字
char *table 该列的表名,用于多表查询
enum enum_field_types type 列的类型
unsigned int length 列的宽度
unsigned int max_length; mysql_store_result返回集中列的最大长度字节
unsigned int flags; 列的定义,包括NOT_NULL_FLAG, PRI_KEY_FLAG,
UNSIGNED_FLAG, AUTO_INCREMENT_FLAG, and
BINARY_FLAG.
unsigned int decimals; 小数点后的位数
常用的type有:
FIELD_TYPE_DECIMAL
FIELD_TYPE_LONG
FIELD_TYPE_STRING
FIELD_TYPE_VAR_STRING
宏IS_NUM当参数字段为数字类型的时候返回TRUE,如
if (IS_NUM(myslq_field_ptr->type)) printf(“Numeric type field/n”);
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
MYSQL_FIELD_OFFSET offset);
设置mysql_fetch_field下一次取出列的位置,如果offset为0,下次将会取出第一列。
9. 获取系统信息
char *mysql_get_client_info(void); 返回客户端库文件的版本
char *mysql_get_host_info(MYSQL *connection); 返回服务器连接信息
char *mysql_get_server_info(MYSQL *connection);返回当前连接的服务器的信息
char *mysql_info(MYSQL*connection);. 返回最近一次执行的query的信息,但只对update和 insert有效
int mysql_select_db(MYSQL *connection,const char *dbname);改变当前连接的数据库,成功后返回0
int mysql_shutdown(MYSQL *connection); 关闭数据库服务器,成功后返回0,前提是你有改 权限。
10. 一个实例
#include <stdlib.h>
#include <stdio.h>
#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 res;
int first_row = 1;
mysql_init(&my_connection);
if (mysql_real_connect(&my_connection, “localhost”, “rick”,
“bar”, “rick”, 0, NULL, 0)) {
printf(“Connection success/n”);
res = mysql_query(&my_connection, “SELECT childno, fname,
age FROM children WHERE age > 5”);
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);
} /* switch */
} /* else */
printf(“/t Max width %ld/n”, field_ptr->length);
if (field_ptr->flags & AUTO_INCREMENT_FLAG)
printf(“/t Auto increments/n”);
printf(“/n”);
} /* while */
}
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”);
}