我有一个要执行的MySQL任务表,每行都有一个任务的参数 有许多工作者应用程序(可能在不同的机器上),循环执行任务 应用程序使用MySQL的本机C API访问数据库。
为了拥有一个任务,应用程序会做类似的事情:
生成全球唯一ID(为简单起见,假设它是一个数字)
UPDATE tasks
SET guid = %d
WHERE guid = 0 LIMIT 1
SELECT params
FROM tasks
WHERE guid = %d
如果最后一个查询返回一行,我们拥有它并让参数运行
有没有办法在一次调用服务器时达到相同的效果(即'拥有'一行并获取其参数)?
答案 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