MySQL - 在存储过程中调用多个存储过程

3
我希望从一个过程内调用多个过程。在下面的SQL中,我创建了三个过程。当我从命令行单独调用upd_r_money和upd_r_fuel时,它们都按预期工作。但是当我调用upd_all时,只有在upd_all内的第一次调用运行;第二次调用upd_r_money不运行。
我无法弄清楚为什么会发生这种情况——也许是我的upd_r_fuel过程中的某些内容导致我的upd_all过程提前结束?我是编写过程和SQL的新手。
这里曾经有另一个关于这个问题的问题,但答案与我已经在做的完全相同,答案的链接已失效。
drop procedure upd_r_money;
delimiter //
CREATE procedure upd_r_money(row_id int)
BEGIN
DECLARE money_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set money = money + period * money_rate,
lastaccessed = now()
where id = row_id;
END;
//
delimiter ;

drop procedure upd_r_fuel;
delimiter //
CREATE procedure upd_r_fuel(row_id int)
fuel: BEGIN
DECLARE fuel_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set fuel = fuel + period * fuel_rate,
lastaccessed = now()
where id = row_id;
END fuel;
//
delimiter ;

drop procedure upd_all;
delimiter //
CREATE PROCEDURE upd_all(row_id int)
BEGIN
call upd_r_fuel(row_id);
call upd_r_money(row_id);
END;
//
delimiter ;

如果我复制并粘贴上面的SQL命令,我的过程将成功创建且无错误,并且我可以调用其中的所有三个。然而,正如我先前所写的那样,upd_all似乎在调用其内部的第一个过程后停止。如果我使用upd_r_fuel替换upd_r_money,则会发生相同的行为-仅调用第一个过程。

enter image description here


我喜欢你图片中的开端。透明的控制台背景 ;) - Lukasz Szozda
1个回答

1
我猜测它不能按预期工作是因为你更新了lastaccessed时间并计算与NOW的差异。第一个工作是因为有显著差异。但是在第二个存储过程中,你有timestammpdiffNOW()NOW() - 毫秒数之间的差异。

检查一下在第一个存储过程中是否删除更新中的lastaccessed有所帮助。

drop procedure upd_r_money;
delimiter //
CREATE procedure upd_r_money(row_id int)
BEGIN
DECLARE money_rate INT DEFAULT 1;
DECLARE period INT DEFAULT 0;
SET period = (select timestampdiff(second, (select lastaccessed from gamerows where id = row_id), now()));
update gamerows
set money = money + period * money_rate
where id = row_id;
END;
//
delimiter ;

警告:现在执行顺序很重要。

另外,您的存储过程非常相似,我建议将它们合并为一个 UPDATE:

update gamerows
set fuel = fuel + period * fuel_rate,
    money = money + period * money_rate,
    lastaccessed = now()
where id = row_id;

1
那真是太有见地了,小伙子——我在第一次调用时更新了我的lastaccessed时间,所以第二次调用只经过不到一秒钟的时间,所以我没有看到任何变化。这是我经常为同学们修正的那种愚蠢的疏忽(我是一名志愿教学助理)。我简直不敢相信我会犯如此明显的错误,就像我经常为别人修正的那些错误一样!哈;就在前几天,我在另一个程序中不小心写成了“const int pi = 3.1459;”。也许这只是我这个笨蛋的一周!非常感谢你,伙计! - Magical Gordon
顺便说一下,我什么时候能玩这个游戏?;) - Lukasz Szozda
1
我在学校的一个俱乐部领导一个团队,我们正在努力在四周内推出我们的最小可行产品。当然,这几乎完全依赖于我,因为除了前端HTML/CSS之外,我几乎做了所有的事情。我试图将大量逻辑放入我的数据库中,以减少PHP代码和网络调用等,我认为在SQL中编写过程非常酷。所以,四周时间可以吗?这是一个完全未完成的产品:https://github.com/candyapplecorn/php-mysql-game - Magical Gordon
@MagicalGordon 很高兴听到这个好消息。祝你在开发中好运,并记住 SO 社区一定会提供帮助的 ;) - Lukasz Szozda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接