昨晚使用MySQL 的C API预处理功能,对多次同样的select操作进行优化时,返回结果时就是得不到返回结果,MySQL 文档里的例子只是没有输入参数的例子,跟我这里不一样,网上查了许久没有找到解决方法。现在解决了。做下笔记。
MySQL 5.1 文档第27.2.7.11节中使用的预处理语句是是没有绑定数据以传递给mysql_stmt_prepare(),相对没有那么复杂。
SELECT col1, col2, col3, col4 FROM test_table
而我要的是绑定数据到MYSQL_STMT句柄中,每次执行预处理之前改变绑定数据的值,得到新的结果。
我使用的预处理语句如下:
SELECT id, Name FROM group WHERE uid = ? AND gid = ?
需要绑定了两个数据到预处理语句中,返回两个结果。
语句:
SELECT col1, col2, col3, col4 FROM test_table
1. stat = mysql_stmt_init(); /* 初始化预处理句柄*/
2. mysql_stmt_prepare() /*准备字符串查询指向的SQL语句*/
3. mysql_stmt_param_count() /* 返回预处理语句中参数标记符的数目。此处应该返回0,因为没有绑定数据*/
4. 为bind指定结果返回存储的缓冲区
5. mysql_stmt_execute() /* 执行与语句句柄相关的预处理查询*/
6. mysql_stmt_bind_result() /* 用于将结果集中的列与数据缓冲和长度缓冲关联(绑定)起来*/
7. mysql_stmt_store_result() /*以便后续的mysql_stmt_fetch()调用能返回缓冲数据*/
8. mysql_stmt_fetch() /* 返回结果集中的下一行 */
9.mysql_stmt_close()
不再给出例子,可以查看文档。
语句:
SELECT id, Name FROM group WHERE uid = ? AND gid = ?
1. stat = mysql_stmt_init(); /* 初始化预处理句柄*/
2. mysql_stmt_prepare() /*准备字符串查询指向的SQL语句*/
3. mysql_stmt_param_count() /* 返回预处理语句中参数标记符的数目。此处应该返回0,因为没有绑定数据*/
4. 为bind指定结果返回存储的缓冲区
5. 绑定传入数据的参数
6. mysql_stmt_bind_param() /* 绑定传入参数到预处理语句中*/
7. 指定传入参数的值
8. mysql_stmt_execute() /* 执行与语句句柄相关的预处理查询*/
9. mysql_stmt_bind_result() /* 用于将结果集中的列与数据缓冲和长度缓冲关联(绑定)起来*/
10. mysql_stmt_store_result() /*以便后续的mysql_stmt_fetch()调用能返回缓冲数据*/
11. mysql_stmt_fetch() /* 返回结果集中的下一行 */
12.mysql_stmt_close()
仅仅展示了函数调用顺序和使用方法
#define GET_USER "SELECT id, Name FROM group WHERE uid = ? AND gid = ?"
int get_user(MYSQL *mysql, int curr_uid)
{
MYSQL_BIND bind1[2], bind2[2];
MYSQL_STMT *stat;
int uid, gid;
char name[20];
int cid;
my_bool is_null[2];
unsigned long length[2];
/* init stat*/
stat = mysql_stmt_init(mysql);
if (!stat)
{
fprintf(stderr, "mysql_stmt_init(), Out of memery\n");
return(-1);
}
if (mysql_stmt_prepare(stat, GET_STAT, strlen(GET_STAT))){
fprintf(stderr, "mysql_stmt_prepare() error:%s\n", mysql_stmt_error(stat));
return(-1); }
int param_count = mysql_stmt_param_count(stat);
if (param_count != 1)
{
fprintf(stderr, "invalid parameter count return by MySQL\n");
return(-1);
}
memset(&bind, 0, sizeof(bind1));
memset(&bind1, 0, sizeof(bind2));
/* 指定传入的参数 */
bind1[0].buffer_type = MYSQL_TYPE_LONG;
bind1[0].buffer = (char *)&uid;
bind1[0].is_null = 0;
bind1[0].length = 0;
bind1[1].buffer_type = MYSQL_TYPE_LONG;
bind1[1].buffer = (char *)&gid;
bind1[1].is_null =0;
bind1[1].length = 0;
/* 指定返回数据的缓冲区 */
bind2[0].buffer_type = MYSQL_TYPE_LONG;
bind2[0].buffer = (char *)&cid;
bind2[0].is_null = &is_null[0];
bind2[0].length = &length[0];
bind2[1].buffer_type = MYSQL_TYPE_STRING;
bind2[1].buffer = &name;
bind2[1].buffer_length = 20;
bind2[1].is_null = &is_null[1];
bind2[1].length = &length[1];
/* 绑定参数 */
if (mysql_stmt_bind_param(group, bind2)){
recordmsg(errout_mqd, 0, curr_uid, "get Contacts list:" "mysql_stmt_bind_param() failed:%s",
mysql_stmt_error(stat));
return(-1);
}
/* 指定参数值 */
uid = curr_uid;gid = 0;
/* 获取结果 */
if (mysql_stmt_execute(stat))
{
/* 错误处理 */
return(-1);
}
if (mysql_stmt_bind_result(group, bind3)){
/* 错误处理 */
return(-1);
}
if(mysql_stmt_store_result(stat)){
/* 错误处理 */
return(-1);
}
while(!mysql_stmt_fetch(stat)){
if(is_null[0])
printf("cid:%d \n", cid);
if (is_null[1])
printf("name:%d \n", name);
}
mysql_stmt_close(stat);
return(0);
}