MYSQL嵌套游標產生混亂的解決方法及注意地方
1. 在編寫存儲過程中, 有時會處理些較復雜的數據, 用到多個游標, 並且嵌套使用,如果控制不好,
在子層游標記錄處理完後, 上層游標也會捕獲NOT FOUND異常, 並改變標示值. 產生數據混亂.
例:
[sql]
BEGIN
DECLARE name_stop int default 0;
DECLARE www.2cto.com
cur_name CURSOR FOR SELECT
NAME
FROM mytable;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET name_stop =1;
open cur_name;
FETCH cur_name into v_name;
START TRANSACTION;
BEGIN
DECLARE ext_stop int DEFAULT 0;
DECLARE cur_ext
CURSOR for select
propertyid
from propertys;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET ext_stop =1;
..............................
當子層cur_ext游標記錄處理完後, 會拋出NOT FOUND, 不僅影響自身, 而且上層游標也會受影響, name_stop 會變成1, 這時就會跳出循環, 不再執行. www.2cto.com
解決的辦法是加入標記塊放置復合語句中,
如: BLOCK1:BEGIN
....
END BLOCK1;
限制作用范圍, 這樣就能解決各游標間的干擾.
2. 在實際使用中, 可能會采用SELECT ... INTO ...語句進行賦值, 但是如果沒有找到記錄, 是不會把NULL值賦給相應變量, 而是拋出NOT FOUND.
如果采用了游標, 這將會影響正常使用.
所以, 最好把select into語句放入單獨的復合語句, 並加入標記塊,
注意, 需要加入一個臨時的HANDLER, 如果沒有HANDLER捕獲, 仍會跳入上層, 影響游標.
正確使用方法, 如下所示:
[sql]
BLOCK4: BEGIN
DECLARE temp_a int default 0;
declare continue handler for not found set temp_a = -1;
select account into v_exist_account from t_user where account = v_account limit 1;
end BLOCK4; www.2cto.com
如果v_exist_account有後續業務處理, 記得處理完後要清空值.
摘自 hxx688的專欄