21

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

为了拥有一项任务,应用程序会执行以下操作:

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

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

  • SELECT params
    FROM tasks
    WHERE guid = %d

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

有没有办法在对服务器的一次调用中实现相同的效果(即“拥有”一行并获取其参数)?

4

6 回答 6

10

试试这样

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

上面的代码对我有用

于 2012-10-08T09:03:26.840 回答
7

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

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;
于 2009-02-18T20:43:38.990 回答
1

如果您正在寻找单个查询,那么它就不会发生。UPDATE 函数专门返回已更新的项目数。同样,SELECT 函数不会更改表,只会返回值。

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

于 2009-02-18T21:05:29.123 回答
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 仅用于 DELETE 语句

编辑:有一项任务(低优先级)来添加UPDATE ... RETURNING对 MariaDB的支持。

于 2015-11-19T21:41:43.450 回答
0

我不知道单个调用部分,但是您所描述的是锁。锁是关系数据库的基本元素。

我不知道锁定一行的细节,读取它,然后在 MySQL 中更新它,但是通过阅读mysql 锁定文档,您可以进行各种基于锁定的操作。

的 postgres 文档有一个很好的示例,准确地描述了您想要做什么:锁定表、读取表、修改表。

于 2009-02-18T20:35:30.240 回答
0
UPDATE tasks
SET guid = %d, params = @params := params
WHERE guid = 0 LIMIT 1;

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

SELECT @params AS params;

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

来自:这里

于 2014-08-07T11:37:52.830 回答