访问MySQL服务器,这需要使用mysqlclient库,MySQL的大多数客户端API(除了
Java和.NET)都是通过这个库来和MySQL服务器通讯的,而这个库正是用C编写的。
1.代码编写和编译
2.连接MySQL服务器
初始化一个MYSQL结构,该结构在几乎所有的MySQL C API函数(除了预处理语句相关的函数)中都会用到。
MYSQL *mysql_init(MYSQL *mysql)
3.连接MySQL服务器使用 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_READ_DEFAULT_FILE
作为选项名来调用mysql_options(),
再调用mysql_real_connect()
来连接服务器;
mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my.cnf")
mysql_real_connect(*mysql, NULL, NULL, NULL, NULL, 0, NULL, 0)
说明:my.cnf文件中记录了连接MySQL服务器所需的各项参数(地址,端口,用户名,密码,数据库,字符集,Unix Socket等)。这样可以灵活的修改连接参数而不必重新编译程序。
要关闭连接,则调用 mysql_close()void mysql_close(MYSQL *mysql)
4.执行查询
1)调用mysql_query()来执行SQL语句,如果语句中包含二进制数据,则需要调用
mysql_real_query()
int mysql_query(MYSQL *mysql, const char *stmt_str)
int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length)
2)若执行的是UPDATE, DELETE或INSERT语句,则可通过mysql_affected_rows()
获知
受影响的记录数。my_ulonglong mysql_affected_rows(MYSQL *mysql)
。
还可以通过mysql_insert_id()
来获取由最近的UPDATE或INSERT语句生成的自增值。 my_ulonglong mysql_insert_id(MYSQL *mysql)
3)若执行的是SELECT语句,则有两种方式来获取结果集。
- 一种方式是通过
mysql_store_result()
将整个结果集全部取回来。MYSQL_RES *mysql_store_result(MYSQL *mysql)
- 另一种方式则是调用mysql_use_result()初始化获取操作,但暂时不取回任何记录。
MYSQL_RES *mysql_use_result(MYSQL *mysql);
- 两种方法均通过
mysql_fetch_row()
来访问每一条记录。MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
注意:若先前调用的是mysql_store_result(), 则直接在本地访问记录;若先前调用的是mysql_use_result(), 则此时才到服务器上去获取记录。
4)当处理完结果集后,调用mysql_free_result()
来释放它所占的内存。 void mysql_free_result(MYSQL_RES *result)。
5)可调用mysql_errno()
和mysql_error()
来获知最近执行的API函数的错误代码和错误信息。 unsigned int mysql_errno(MYSQL *mysql)
const char *mysql_error(MYSQL *mysql)
5.预处理语句
MySQL C API还提供了另一种方式来执行SQL语句,即先预处理(prepare)再执行(execute). 对于多次执行的SQL语句,该方式可以提高其执行效率。具体步骤如下:
* 5.1.调用mysql_stmt_init()
创建语句句柄,该句柄在随后的函数调用中都要用到。 MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)
- 5.2.调用
mysql_stmt_prepare()
对SQL语句进行预处理int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *stmt_str, unsigned long length)
- 5.3.如果SQL语句中有参数,则需要调用mysql_stmt_bind_param()进行参数绑定。
my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)
如果参数的类型为TEXT或BLOB, 并且数据量很大,可以调用 mysql_stmt_send_long_data()
来向服务器发送数据。 my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int parameter_number, const char *data, unsigned long length)
- 5.4.调用mysql_stmt_execute()来执行查询。
int mysql_stmt_execute(MYSQL_STMT *stmt)
- 5.5.若查询不产生结果集,可以调用
mysql_stmt_affected_rows()
和my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)
来获得被改变的记录数和生成的自增值。
my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)
my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)
否则,执行mysql_stmt_bind_result()
对结果集中的字段进行绑定。 my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
- 5.6调用
mysql_stmt_fetch()
来逐行获取结果集中的记录。int mysql_stmt_fetch(MYSQL_STMT *stmt)
在调用mysql_stmt_fetch()
之前,还可以执行mysql_stmt_store_result()
将结果
集预先缓存到本地。 int mysql_stmt_store_result(MYSQL_STMT *stmt)
- 5.7重复步骤3-6, 每次使用不同的实参来执行查询。
- 5.8调用
mysql_stmt_close()
关闭句柄,释放资源my_bool mysql_stmt_close(MYSQL_STMT *)
此外,可以调用mysql_stmt_errno()
和mysql_stmt_error()
来获知最近执行的预处理语句API函数的错误代码和错误信息。
unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)
const char *mysql_stmt_error(MYSQL_STMT *stmt)
- 5.9其他说明:
mysql_stmt_execute()
中有调用案例 - http://dev.mysql.com/doc/refman/5.1/zh/apis.html#c-api-multiple-queries
- 25.2.7.11. mysql_stmt_fetch()