我的sql循环永远不会结束为什么? 我在循环时做了一个简单的游标,但是我得到了一个无限循环,我找不到bug。 我没有性能问题它是一个无限循环,我有35K记录,但循环持续很长时间后,我停止执行,我无法得到它是怎么回事,循环应该是光标选择检索的确切计数
DROP PROCEDURE IF EXISTS tlaTempAmoutUSDTrades;
CREATE PROCEDURE tlaTempAmoutUSDTrades()
BEGIN
DECLARE bDone INT;
DECLARE pTradeGUID binary(16); -- or approriate type
DECLARE pTradeAmountUSD double; -- or approriate type
DECLARE curs CURSOR FOR SELECT t.guid FROM trades as t
JOIN `orderslogadd` as `o` on`t`.`orderId` = `o`.`orderId`
JOIN `currencypairs` as `ccp` on`o`.`ccpair` = `ccp`.`id`
JOIN `currencies` as `ccy1` on`ccp`.`currency1` = `ccy1`.`id`
JOIN `currencies` as `ccy2` on`ccp`.`currency2` = `ccy2`.`id`
left JOIN tlaAmountUSD tau on tau.guid = t.guid
WHERE tau.amountUSD is null ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN curs;
setAmountUSD: LOOP
FETCH curs INTO pTradeGUID;
IF (bDone = 1) OR (pTradeGUID is null) THEN
LEAVE setAmountUSD;
END IF;
SET pTradeAmountUSD = (select `crosUSDValV22`(`ccy1`.`id`,`ccy2`.`id`,`t`.`amount`,`t`.`amountCcy`,`t`.`dealtRate`,`t`.`guid`) as tradeAmountUSD
FROM `trades` as t
JOIN `orderslogadd` as `o` on`t`.`orderId` = `o`.`orderId`
JOIN `currencypairs` as `ccp` on`o`.`ccpair` = `ccp`.`id`
JOIN `currencies` as `ccy1` on`ccp`.`currency1` = `ccy1`.`id`
JOIN `currencies` as `ccy2` on`ccp`.`currency2` = `ccy2`.`id`
where t.guid=pTradeGUID);
insert into tlaAmountUSD (guid,amountUSD) values (pTradeGUID,pTradeAmountUSD);
END LOOP setAmountUSD;
关闭诅咒;
END;
答案 0 :(得分:0)
根据您在此处显示的内容,在从curs
获取最后一行之后,将调用continue处理程序,bDone
将设置为1,然后条件测试将是是的,循环将退出。这看起来不像是一个无限循环。
如果这是实际执行的代码,那么只需要时间来完成该过程。 (也许游标定义中的查询真的慢,或者循环体中的查询真的很慢......引用的表被锁定,或INSERT阻塞等等。
为了进行调试,您可以考虑在游标查询中添加LIMIT 1,看看是否可以让它完成一行,并查看需要多长时间。
您可以尝试注释掉正在执行此工作的过程的主体,然后执行获取,以查看需要多长时间。
此外,对两个查询(在游标中和循环中)运行EXPLAIN,验证是否正在使用适当的索引,以及查询计划是否合理。还要测试这些查询,以验证它们是否返回了您期望的结果。
这将有助于缩小问题所在。
除非您指定了不同的分隔符,否则显示的CREATE PROCEDURE
语句将抛出错误;否则,遇到的第一个分号将(过早地)“结束”存储过程定义
CREATE PROCEDURE tlaTempAmoutUSDTrades()
BEGIN
DECLARE bDone INT;
^
要创建该过程,您需要执行以下操作:
DELIMITER $$
CREATE PROCEDURE tlaTempAmoutUSDTrades()
BEGIN
DECLARE bDone INT;
-- ...
END $$
DELIMITER ;