2012-08-11 73 views
2

返回更新的行我有以下查询:更新则表中的MySQL

SELECT script FROM d_stages WHERE id IN 
(SELECT g.stage + :i FROM games g INNER JOIN sessions s ON 
g.expired = 0 AND s.user = g.user AND s.token = :token) 
  1. 内心的选择由给定令牌会在“会话”表中的用户ID,那么对非过期该用户的游戏。
  2. 它返回游戏的阶段,它被修改(增加,减少或保持不变,取决于:i值)。
  3. Outer SELECT从字典中为找到的舞台返回一个唯一的脚本。

很显然,修改后的阶段号(g.stage +:i)应该写回数据库,因为游戏已经发展了。我可以使用SELECT script, g.stage + :i替换SELECT script,并在另一个(UPDATE)查询中使用修改后的数字,但也许我可以在单个查询中执行相同操作?

我的DBMS是mySQL 5.5。

Regards,

回答

0

我认为,只有一个办法:

CREATE DEFINER=`root`@`localhost` PROCEDURE `goto_stage`(IN `inc` INT, IN `session_token` VARCHAR(64)) 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    MODIFIES SQL DATA 
    SQL SECURITY DEFINER 
    COMMENT '' 
BEGIN 
    DECLARE new_stage INT; 
    SELECT g.stage + inc INTO new_stage FROM games g INNER JOIN sessions s ON 
      g.expired = 0 AND s.user = g.user AND s.token = session_token; 
    UPDATE games SET stage = new_stage; 
    SELECT script FROM d_stages WHERE id = new_stage; 
END 
1

您只能使用UPDATE查询进行更新。 UPDATE查询只能返回一件事情:然后受影响的行数。因此,您无法在单个查询中更新并选择所需的值。

因此,您必须使用额外的UPDATE查询来更新数据。您可以在SELECT查询之前执行此操作,具体取决于代码中的简单性或真实点,代码中应该提交新值。

0

没有单一的解决办法查询到MySQL。但是,如果你的数据库使用InnoDB的发动机,你可以尝试

select ... for update 

锁定行,然后就更新它。检查mysql手册“14.3.9.3。选择...更新并选择...锁定共享模式锁定读取”以获取详细信息。