MySQL UPDATE和SELECT一次通过

时间:2009-02-18 20:29:54

标签: mysql sql-update

我有一个要执行的MySQL任务表,每行都有一个任务的参数 有许多工作者应用程序(可能在不同的机器上),循环执行任务 应用程序使用MySQL的本机C API访问数据库。

为了拥有一个任务,应用程序会做类似的事情:

  • 生成全球唯一ID(为简单起见,假设它是一个数字)

  • UPDATE tasks
    SET guid = %d
    WHERE guid = 0 LIMIT 1

  • SELECT params
    FROM tasks
    WHERE guid = %d

  • 如果最后一个查询返回一行,我们拥有它并让参数运行

有没有办法在一次调用服务器时达到相同的效果(即'拥有'一行并获取其参数)?

6 个答案:

答案 0 :(得分:9)

试试这个

UPDATE `lastid` SET `idnum` =  (SELECT `id` FROM `history` ORDER BY `id` DESC LIMIT 1);

以上代码为我工作

答案 1 :(得分:6)

您可以创建一个执行此操作的过程:

CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200))
BEGIN

  DECLARE task_id INT;

  SELECT id, out_params
  INTO task_id, out_params
  FROM tasks
  WHERE guid = 0
  LIMIT 1
  FOR UPDATE;

  UPDATE task
  SET guid = in_guid
  WHERE id = task_id;

END;

BEGIN TRANSACTION;

CALL prc_get_task(@guid, @params);

COMMIT;

答案 2 :(得分:1)

如果您正在寻找单个查询,则无法进行。 UPDATE函数专门返回已更新的项目数。类似地,SELECT函数不会改变表,只返回值。

使用一个程序确实会把它变成一个单独的函数,如果你担心锁定,它会很方便。如果您最关心的是网络流量(即:传递太多查询),请使用该过程。如果您担心的是服务器过载(即:数据库工作太辛苦),那么程序的额外开销可能会使事情变得更糟。

答案 3 :(得分:1)

我有完全相同的问题。我们最终使用的是PostreSQL,UPDATE ... RETURNING

  

可选的RETURNING子句使UPDATE根据实际更新的每一行计算并返回值。可以计算使用表的列的任何表达式,和/或FROM中提到的其他表的列。使用表格列的新(更新后)值。 RETURNING列表的语法与SELECT的输出列表的语法相同。

示例:UPDATE 'my_table' SET 'status' = 1 WHERE 'status' = 0 LIMIT 1 RETURNING *;

或者,在您的情况下:UPDATE 'tasks' SET 'guid' = %d WHERE 'guid' = 0 LIMIT 1 RETURNING 'params';

抱歉,我知道这并没有回答MySQL的问题,而且切换到PostgreSQL可能并不容易,但这是我们发现它的最佳方式。即使6年后,MySQL仍然不支持UPDATE ... RETURNING。它可能会在将来的某个时候添加,但现在MariaDB only has it for DELETE statements

编辑 add UPDATE ... RETURNING support to MariaDB有一项任务(低优先级)。

答案 4 :(得分:0)

我不知道单个呼叫部分,但你所描述的是锁定。锁是关系数据库的基本要素。

我不知道锁定行,读取它,然后在MySQL中更新它的具体细节,但通过阅读mysql lock documentation,您可以进行各种基于锁定的操作。 / p>

locks的postgres文档有一个很好的例子来描述你想要做的事情:锁定表格,阅读表格,修改表格。

答案 5 :(得分:0)

UPDATE tasks
SET guid = %d, params = @params := params
WHERE guid = 0 LIMIT 1;

它将返回1或0,具体取决于值是否有效更改。

SELECT @params AS params;

这个只是从连接中选择变量。

来自:here