Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1405599
  • 博文数量: 277
  • 博客积分: 2551
  • 博客等级: 少校
  • 技术积分: 3918
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-21 22:46
文章分类

全部博文(277)

文章存档

2017年(3)

2016年(9)

2015年(65)

2014年(27)

2013年(85)

2012年(61)

2011年(27)

分类: Mysql/postgreSQL

2013-01-22 17:26:17

         使用super smack后,发现它有很多弱点。

             1、同一个表中的多个字段不能通过一个数据文件获取,要单独建立数据文件

                  而有的场合这个问题只能绕过去,例如:用户名和密码,这两个数据段是紧绑定的,不好单独导出数据文件。

             2、从字段中的数据文件获取的记录不能两次使用

                  例如,query "call  myproc('$user',substring_index('$user','@',1))",是有问题的,此时会取2次数据文件dat,两个$user是不同的

             3、super smack不支持存储过程

                  解决办法是修改mysql-client.cc中的safe_query函数

                  if(mysql_query(....)){

                     .....

                 }else{

                      if(strstr(query,"call"){

                         MYSQL_ROW  row;

                         MYSQL_RES   *res;

                         int  myret = 0;

                         res = mysql_use_result(&con);

                         while((row = mysql_fetch_row(res)){

                            //maybe real data this time;

                          }

                          mysql_free_result(res);

                          res = NULL;

                          while(1){

                               myret = mysql_next_result(&con):

                               if(myret ==0){

                                   res = mysql_use_result(&con);

                                   mysql_free_result(res);

                                   res = NULL;

                               }else if(myret ==-1){

                                  break;

                               }else if(myret > 0){

                                   cerr<<"proc exec fail"<

                                   break;

                               }

                          }

                     

                      }

                 }

       super smack不能执行存储过程的原因实际上是MySQL本身造成的。

            执行mysql语句或存储过程,一般只用mysql_query、mysql_use_result等几个函数。

            问题在于:

                 当执行一个存储过程的时候, 数据库返回的是多个数据集合,即使只有一个数据集合,它也会有一个空集合用于结束一次回话,回复不可能一次完成,需要多次网络交互,

                 那么所有的交互肯定需要一个结束符号,并且存储过程本来就可以返回多个数据集合,如果他在C API 中只做一个结果己处理就允许下一次全新的请求,那么对于同一连接,

                 在mysql服务断其实还有没有发送完成的数据,这个时候他安全的做法就是不接受任何新的请求,直到数据发送完全,或者连接关闭,不然,mysql协议解析就会出现问题,

                 下次发送就会出现黏包或者丢包,所以mysql的做法是完全正确的.

                 即使只有一个结果集合,也需要当前会话内的通讯(比如mysql_next_result)确认完毕,然后结束本次请求,这个时候服务端其实没有数据了,

                但是这个过程是不能省略的,然后在不关闭连接的情况下就可以进行全新的请求了。

                所以总结起来就是:使用存储过程的时候一定要循环执行,把所有的结果集合都取到,直到为空,这个时候当前数据库连接才可以安全归还回去

阅读(1743) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~