2012-04-04 70 views
1

我正在使用MySQL InnoDB。MySQL - 在单个查询中更新列的顺序

我想更新一个表并控制每列更新的顺序。所有在一个查询如果可能的话。原因是我有一个游戏队列系统。当你完成queue_1时,我希望为它分配queue_2的值,然后擦除queue_2。

现在我收到了不可预测的结果。有时total_price_2设置为零,则加载到total_price_1。两者都变为零。 (不是我想要的。)

我读到DB决定运行更新的顺序。如果我必须做两个更新,那很好。我的目标是表现。

UPDATE 
queue 
SET  
queue_1 = queue_2, 
total_price_1 = total_price_2, 
total_wait_1 = total_wait_2, 
queue_2 = '', 
total_price_2 = 0, 
total_wait_2 = 0 
WHERE id IN(1,2,3) 
+1

您确定'total_price_2'在更新之前不是'0'吗? – MichaelRushton 2012-04-04 08:12:34

+0

@MichaelRushton好想法。在您的评论后,我正在尝试自己的查询,而不是在代码中的自然上下文中查询。 7次尝试,每次都在努力。使用我给它的订单。我会继续嗅探并回传。 – Dor1000 2012-04-04 08:25:15

+0

我在更新之前和之后选择并回显队列数据。我发现我的更新正在按计划进行,但其他情况在后来改变了这些值。氙气在这方面有一个很好的答案。 – Dor1000 2012-04-04 08:44:55

回答

2

检查total_price_2在更新之前不是0,如MichaelRushton所示。

单表UPDATE分配一般是由左向右进行评估:

在MySQL,单表UPDATE查询从“从左到右”,其在本UPDATE声明文档中所述进行处理。对于多表更新,不保证分配按任何特定顺序执行。 (Source

具体地,请注意本实施例中:

在下面的语句集COL2到当前(更新)值COL1,而不是原来的col1值的第二指派。结果是col1和col2具有相同的值。此行为不同于标准SQL。

UPDATE t1 SET col1 = col1 + 1, col2 = col1; 


旁注

作为一个位一个侧面说明,你也可以明确指定的顺序为通过使用ORDER BY条款进行更新:

没有WHERE子句,所有行都被更新。如果指定了ORDER BY子句,则按照指定的顺序更新行。 (Source

0

拆分queue_1queue_2您更新查询。

进行一次更新查询queue_1,另一个用于queue_2, 因为MySQL变得迷茫的时候它更新的值,它queue_1,这使得你的结果0之前更新queue_2

0

值得一提的是,如果你是依赖于依赖服务器的行为,如所暗示的This behavior differs from standard SQL,你需要在今后要细心。如果你改变DB呢?或者别人更新了代码而没有意识到排序的重要性?

将更新拆分为两个明确的语句并使用事务来确保它们以原子方式运行可能会更好。

+0

好点。我有一个文本文件,可以在笔记上记录我的项目,供将来参考。我将添加一个注释,即移动队列是为MySQL编码的。我会在代码中添加一条评论,说明它的顺序非常敏感。感谢Cylindric。 – Dor1000 2012-04-05 04:59:04