使用INTO内部游标的MySQL / MariaDB设置值具有不正确的迭代
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用INTO内部游标的MySQL / MariaDB设置值具有不正确的迭代相关的知识,希望对你有一定的参考价值。
有人可以解释一下为什么我运行这段代码:
BEGIN
-- Declare loop constructs --
DECLARE done INT DEFAULT FALSE;
-- Declare Person variables --
DECLARE s_trnsf_id INT(11) DEFAULT NULL;
DECLARE s_trnsf_trnsp_id INT(11) DEFAULT NULL;
DECLARE s_trnsf_bacc_id INT(11) DEFAULT NULL;
DECLARE s_trnsf_cus_id INT(11) DEFAULT NULL;
DECLARE s_trnsf_bacc_amnt DECIMAL(18,4) DEFAULT NULL;
DECLARE s_trnsf_recidue_amnt DECIMAL(18,4) DEFAULT NULL;
DECLARE t_trnsf_id INT(11) DEFAULT NULL;
DECLARE t_trnsf_recidue_amnt DECIMAL(18,4) DEFAULT NULL;
DECLARE c1 INT(11) DEFAULT 0;
-- Declare Cursor --
DECLARE member_cursor CURSOR FOR
SELECT trnsf_id, trnsf_trnsp_id, trnsf_bacc_id, trnsf_cus_id, trnsf_bacc_amnt,trnsf_recidue_amnt
FROM d_transfers
WHERE
trnsf_bacc_amnt < 0
AND trnsf_recidue_amnt <> 0
ORDER BY #trnsf_trnsp_id ASC, trnsf_bacc_id ASC, trnsf_cus_id ASC,
trnsf_transfer_ts ASC;
-- Declare Continue Handler --
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN member_cursor;
read_loop: LOOP
SET c1 = c1+1;
-- Fetch data from cursor --
FETCH member_cursor
INTO s_trnsf_id,
s_trnsf_trnsp_id,
s_trnsf_bacc_id,
s_trnsf_cus_id,
s_trnsf_bacc_amnt,
s_trnsf_recidue_amnt;
-- Exit loop if finished --
IF done THEN
LEAVE read_loop;
END IF;
##MARKED_BEGIN######################
SELECT trnsf_id#,trnsf_recidue_amnt
into t_trnsf_id#,t_trnsf_recidue_amnt
from d_transfers
WHERE trnsf_bacc_amnt > 0
AND trnsf_recidue_amnt > 0
AND trnsf_trnsp_id = s_trnsf_trnsp_id
AND trnsf_bacc_id = s_trnsf_bacc_id
AND trnsf_cus_id = s_trnsf_cus_id
ORDER BY trnsf_transfer_ts ASC limit 1;
##MARKED_END######################
END LOOP read_loop;
CLOSE member_cursor;
SELECT c1;
END
它返回:
+-------+
| c1 |
+-------+
| 138 |
+-------+
但是,如果我用代码替换MARKED_BEGIN和MARKED_END之间的代码:
SET t_trnsf_id = (
SELECT trnsf_id#,trnsf_recidue_amnt
FROM d_transfers
WHERE trnsf_bacc_amnt > 0
AND trnsf_recidue_amnt > 0
AND trnsf_trnsp_id = s_trnsf_trnsp_id
AND trnsf_bacc_id = s_trnsf_bacc_id
AND trnsf_cus_id = s_trnsf_cus_id
ORDER BY trnsf_transfer_ts ASC limit 1
);
我明白了:
+-------+
| c1 |
+-------+
| 54742 |
+-------+
我认为它应该返回相同的结果!
如果我排除
AND trnsf_trnsp_id = s_trnsf_trnsp_id
AND trnsf_bacc_id = s_trnsf_bacc_id
AND trnsf_cus_id = s_trnsf_cus_id
从上面的代码返回正确的迭代(select语句中的行数)
我在MacOS上使用MariaDB 10.1.10
答案
@Solarflare,谢谢你的提示!添加CONTINUE HANDLER可以解决问题。
BEGIN
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = FALSE;
BEGIN
-- body of handler
##MARKED_BEGIN######################
SELECT trnsf_id,trnsf_recidue_amnt
into t_trnsf_id,t_trnsf_recidue_amnt
from d_transfers
WHERE trnsf_bacc_amnt > 0
AND trnsf_recidue_amnt > 0
AND trnsf_trnsp_id = s_trnsf_trnsp_id
AND trnsf_bacc_id = s_trnsf_bacc_id
AND trnsf_cus_id = s_trnsf_cus_id
ORDER BY trnsf_transfer_ts ASC limit 1;
##MARKED_END######################
END;
END;
以上是关于使用INTO内部游标的MySQL / MariaDB设置值具有不正确的迭代的主要内容,如果未能解决你的问题,请参考以下文章