3

我有以下查询:

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. Inner SELECT 通过给定的令牌在“会话”表中查找用户 ID,然后为该用户查找未过期的游戏。
  2. 它返回被修改的游戏阶段(增加、减少或保持不变,取决于 :i 值)。
  3. 外部 SELECT 为从字典中找到的阶段返回一个唯一的脚本。

显然,修改后的阶段编号(g.stage + :i)应该写回数据库,因为游戏已经进化了。我可以替换SELECT scriptSELECT script, g.stage + :i,并在另一个 ( UPDATE) 查询中使用修改后的数字,但也许我可以在单个查询中做同样的事情?

我的 DBMS 是 mySQL 5.5。

问候,

4

3 回答 3

1

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

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

于 2012-08-11T23:31:06.627 回答
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
于 2012-08-19T11:44:17.893 回答
0

mysql没有单一的查询解决方案。但是如果你的数据库使用 innodb 作为引擎,你可以试试

select ... for update

锁定行,然后对其进行更新。查看 mysql 手册“14.3.9.3. SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads”了解详细信息。

于 2014-03-03T06:43:38.060 回答