免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2619 | 回复: 3

这是mysql update语句求值顺序的一个Bug吗? [复制链接]

论坛徽章:
0
发表于 2009-06-12 15:22 |显示全部楼层
情况是这样的,我用的mysql 5.1.31
create table test1(id int not null primary key,num1 int);
create table test2(test1id int not null,num2 int);              
insert into test1 values(1,233);
insert into test2(1,0);

select * from test1,test2;
+----+------+---------+------+
| id | num1 | test1id | num2 |
+----+------+---------+------+
|  1 |  233 |       1 |    0 |
+----+------+---------+------+


现在我想把num1的20%转到num2上去,对于例子中的数据,应该是num1减47,num2加47.
执行一个多表联合更新
update test1,test2 set num2=num2+ceil(num1*0.2),num1=num1-ceil(num1*0.2) where id=1 and test1id=id;
mysql> select * from test1,test2;
+----+------+---------+------+
| id | num1 | test1id | num2 |
+----+------+---------+------+
|  1 |  186 |       1 |   38 |
+----+------+---------+------+  
              

结果,num1减的是47没错,但是num2只加了38.
也就是说这个update语句中: "set num2=num2+ceil(num1*0.2),num1=num1-ceil(num1*0.2)" 求值顺序不是按照sql语句写得那样,而是先计算了逗号后面的。

请问,这算是mysql的bug还是设计如此(注意单表upate不存在此问题)?
如果是设计如此,那么我用什么方法实现这个逻辑?      
注:要求的20%应该是当前表中数据的20%,如果先求出20%是多少,例如47,然后再num2=num2+47,num1=num1-47,则多个客户并发执行时,执行结果会违反要求的逻辑

[ 本帖最后由 oyd_admin 于 2009-6-12 15:45 编辑 ]

论坛徽章:
0
发表于 2009-06-12 16:33 |显示全部楼层
你可以这么做:
UPDATE test1 a,
test2 b,
(
SELECT *
FROM test1, test2
WHERE id =1
AND test1id = id
)c
SET b.num2 = c.num2 + ceil( c.num1 * 0.2 ) ,
a.num1 = c.num1 - ceil( c.num1 * 0.2 )
WHERE a.id = c.id AND b.test1id = c.test1id

论坛徽章:
0
发表于 2009-06-12 17:16 |显示全部楼层
谢谢啊,很管用。

论坛徽章:
9
每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00数据库技术版块每周发帖之星
日期:2016-03-07 16:30:25
发表于 2009-06-12 17:49 |显示全部楼层
update test1 ,test2 ,test1 as temp1
    set test2.num2 = temp1.num1 * 0.2 ,
       test1.num1 = temp1.num1 * 0.8
    where temp1.id=1 and test1.id=temp1.id and test1.id=test2.test1id;
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP