免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6173 | 回复: 5
打印 上一主题 下一主题

mysql++编程遇到的判断update是否成功的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-26 11:29 |只看该作者 |倒序浏览
Mysql的Update如果找不到符合条件的row的话,Query::affected_rows()返回0,
如果有符合条件的row,但是要set的值和原值一样的话,也返回0.

比如:
mysql> select * from EAD0_PKG_RG;
+----------+---------+
| PKG_ID   | RG_ID   |
+----------+---------+
| PKG00002 | RG00006 |
+----------+---------+
1 rows in set (0.01 sec)

Update一条不存在的row, affected_rows = 0, matched_rows = 0
mysql> update EAD0_PKG_RG set RG_ID='RG00001' where PKG_ID='PKGdkfjiejf';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

Update一条存在但是set的值和原值一样的row, affected_rows =0, matched_rows =1
mysql> update EAD0_PKG_RG set RG_ID='RG00006' where PKG_ID='PKG00002';         
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

我要提供一个update接口给用户,显然上面两种update之后affected_rows=0的情况是不一样的,
对于第一种,用户可能会发现update失败了是因为记录不存在,需要再insert一遍,第二种客户应该
发现所要实现的值已经达到,不需要再做什么了。

但是mysql++或者mysql C函数接口似乎都没有提供让我获得matched row的方法,难道要我再select一下
才能区分这2种affected_rows=0的update结果?有没有达人能帮忙解答一下。

另外我觉得mysql对存在值和set值相等的update返回affect_rows=0的做法值得商榷,
在实现上这种情况确实不需要affect到记录,但是再update业务上,呈现给用户的应该是update成功了才对啊。

论坛徽章:
0
2 [报告]
发表于 2008-06-26 17:28 |只看该作者
有人指点下吗?

论坛徽章:
0
3 [报告]
发表于 2008-06-30 13:10 |只看该作者

回复 #1 PinkOrient 的帖子

mysql_affected_rows    +   CLIENT_FOUND_ROWS   +  google

论坛徽章:
0
4 [报告]
发表于 2008-07-01 16:26 |只看该作者

回复 #3 7islands 的帖子

多写兄弟,我弄懂了

论坛徽章:
0
5 [报告]
发表于 2008-07-01 16:39 |只看该作者
总结帖,说说这个问题怎么解决

首先用上面兄弟的说法,上google搜索 mysql_affected_rows+CLIENT_FOUND_ROWS 可以找到文章,说

mysql_affected_rows函数返回的行数是否包含where子句匹配得到,但是没有发生改变的行,是由mysql_real_connect函数

的最后一个参数clientflag决定的,如果连接数据库的时候给一个CLIENT_FOUND_ROWS参数的话,就可以返回where匹配到的

行数,而不是实际影响的行数。

MYSQL *     STDCALL 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 clientflag);

这个是C函数接口的,可是我的程序用的是mysql++,还好mysql++是开源的,继续深挖代码。。

最后找到一个FoundRowsOption类干的是设这个参数的事情,代码例子如下

    try{
        m_pCon = new mysqlpp::Connection();
        FoundRowsOption *option = new FoundRowsOption(true); //don't delete it, mysqlpp will manage this ptr
        m_pCon->set_option(option); //set CLIENT_FOUND_ROWS option
        m_pCon->connect(cfg.m_Database, cfg.m_Host, cfg.m_User, cfg.m_Password); //connnect
    } catch (....) {
             ......
    }

注意这里创建一个FoundRowsOption 对象要创建在堆上,因为调用set_option之后mysql++里面的DBDriver类会管理这块内存的释放,
如果创建在栈上出了这个函数就释放掉了,等到释放DBDriver的时候会释放多一次,导致Segment Fault

论坛徽章:
0
6 [报告]
发表于 2008-07-01 16:55 |只看该作者
它的手册上的例子是  m_pCon->set_option(new FoundRowsOption(true))   后面也有详细的说明。

好难得看到有人总结哦!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP