1、 Mysql预处理简介
预处理的意思是先提交sql语句到mysql服务端,执行预编译,客户端执行sql语句时,只需上传输入参数即可,这点和存储过程有点相似。
一般而言,预处理的执行效率相对于一般的sql执行操作,效率比较高。由于客户端上传的或是读取的结果集是绑定输入内存地址和输出内存地址,对于一些二进制流,或大数据量的存储和读取显得尤为方便。
2、 参考说明
具体的可以参考mysql的操作手册,里面第25章,C API库,里面有详细的说明。链接地址如下:http://dev.mysql.com/doc/refman/5.1/zh/apis.html#c-api-prepared-statements
3、以一个简单的sql查询语句来简要说明一下mysql预处理的功能。
调用mysql c api的预处理函数,执行预处理功能的步骤一般如下:
1) 先调用mysql_init(),初始化一个MYSQL对象,用于与数据库的链接句柄
2) 调用mysql_real_connect()链接数据库服务端
3) 调用mysql_stmt_init()初始化一个MYSQL_STMT对象,用于处理对应的预处理操作
4) 调用mysql_stmt_prepare()接口,上传预处理的sql语句
5) 定义相应的MYSQL_BIND数据结构,调用mysql_stmt_bind_param用于绑定输入参数
6) 如果有输出结果集,可以选择调用mysql_stmt_result_metadata()接口以结果集MYSQL_RES形式返回预处理语句元数据。
7) 调用mysql_stmt_execute()执行相应的sql查询操作
8) 如果有输出结果,调用mysql_stmt_bind_result将输出结果绑定到MYSQL_BIND数据结构对象上,同时调用mysql_stmt_store_result()将所有的结果集保存到客户端的缓冲区中,并通过mysql_stmt_fetch()来进行调用获取返回的每行的值
-
-
- MYSQL* pSql = new MYSQL;
-
- Mysql_init(pSql);
-
- MYSQL_STMT* pSql_Stmt = mysql_stmt_int(pSql);
-
-
-
- Mysql_read_connect(pSql, “127.0.0.1”, “root”, “123456”, “STMT”, NULL, 0);
-
-
-
- CString strSql = “Select Name, PhotoData from PhotoData where ID = ? “;
-
-
-
- mysql_stmt_prepare(pSql_Stmt, strSql.Getbuffer(0), strSql.getlength());
-
-
-
-
-
- MYSQL_BIND v_pParaBind[1];
-
- My_Bool v_pParaIsNull[1];
-
- Unsigned long ParaLength[1];
-
- memset(v_pParaBind, 0, sizeof(v_pParaBind));
-
- memset(v_pParaIsNull, 0, sizeof(v_pParaIsNull));
-
- memset(Paralength, 0, sizeof(Paralength));
-
-
-
- int nID = 18;
-
- v_pParaBind [0].buffer = (char*)& nID;
-
- v_pParaBind [0].buffer_length = sizeof(int);
-
- Paralength[0] = sizeof(int);
-
- v_pParaBind [0].length = &(Paralength[0]);
-
- v_pParaBind [0].is_null = &( v_pParaIsNull [0]);
-
- v_pParaBind [0].buffer_type = MYSQL_TYPE_LONG;
-
-
-
-
-
- Mysql_stmt_bind_param(pSql_Stmt, v_pParaBind);
-
-
-
-
-
- Mysql_stmt_execute(pSql_Stmt);
-
-
-
-
-
- MYSQL_BIND v_pResultBind[2];
-
- My_bool v_pResultIsNull[2];
-
- Unsigned long ResultLength[2];
-
- char szName[200] = {0};
-
- char szPhotoData[2000] = {0};
-
- memset(v_pResultBind, 0, sizeof(v_pResultBind));
-
- memset(v_pResultIsNull, 0, sizeof(v_pResultIsNull));
-
- memset(ResultLength, 0, sizeof(ResultLength));
-
-
-
- v_pResultBind[0].buffer = szName;
-
- v_pResultBind[0].length = &(ResultLength[0]);
-
- v_pResultBind[0].is_null = &(v_pResultIsNull[0]);
-
- v_pResultBind[0].buffer_type = MYSQL_TYPE_STRING;
-
-
-
- v_pResultBind[1].buffer = szPhotoData;
-
- v_pResultBind[1].length = &(ResultLength[1]);
-
- v_pResultBind[1].is_null = &(v_pResultIsNull[1]);
-
- v_pResultBind[1].buffer_type = MYSQL_TYPE_BLOB;
-
-
-
- mysql_stmt_bind_result(pSql_Stmt, v_pResultBind);
-
-
-
-
-
- Mysql_stmt_store_result(pSql_Stmt);
-
- While(!mysql_stmt_fetch(pSql_Stmt))
-
- {
-
- If(!v_pResultIsNull[0])
-
- {
-
- Printf(“Name is %s, Name length is %d”, szName, ResultLength[0]);
-
- }
-
-
-
- If(!v_pResultIsNull[1])
-
- {
-
- Printf(“PhotoData length is %d”, ResultLength[0]);
-
-
-
- }
-
- }
-
-
-
-
-
- Mysql_stmt_close(pSql_Stmt);
-
- pSql_Stmt = NULL;
-
- Mysql_close(pSql);
-
- pSql = NULL;
4、 mysql_stmt_send_long_data()函数
改函数用于将比较长的参数分几块依次传输给服务端,用法和上例一样,只是在绑定MYSQL_BIND参数值时,调用mysql_stmt_send_long_data(),传入BIND指向的参数每一块指针和长度,具体可见:
http://dev.mysql.com/doc/refman/5.1/zh/apis.html#mysql-stmt-send-long-data