MySQL儲存過程遊標(cursor)示例
阿新 • • 發佈:2019-01-28
Mysql建立儲存過程,使用遊標Cursor迴圈更新
使用遊標(cursor)
1.宣告遊標
DECLARE cursor_name CURSOR FOR select_statement
這個語句宣告一個遊標。也可以在子程式中定義多個遊標,但是一個塊中的每一個遊標必須有唯一的名字。宣告遊標後也是單條操作的,但是不能用SELECT語句不能有INTO子句。
2. 遊標OPEN語句
OPEN cursor_name
這個語句開啟先前宣告的遊標。
3. 遊標FETCH語句
FETCH cursor_name INTO var_name [, var_name] ...
這個語句用指定的開啟遊標讀取下一行(如果有下一行的話),並且前進遊標指標。
4. 遊標CLOSE語句
CLOSE cursor_name
這個語句關閉先前開啟的遊標。
寫之前查了好多資料但是總是執行不了,後來自琢磨了一下,寫了個例子,經過測試完全正確。
下面是建立儲存過程,使用遊標迴圈更新操作的例子:
下面是建立儲存過程,使用遊標迴圈更新操作的例子: -- Procedure "useCursor" DDL CREATE PROCEDURE `useCursor`() BEGIN /*區域性變數的定義 declare*/ declare aid bigint default 0 ; declare mdsl bigint default 0; declare stop int default 0; declare cur CURSOR FOR (select count(area_info.id) as mdsl, area_info.id as aid from area_info right join subbranch_info on subbranch_info.i_subbran_area=area_info.id where area_info.i_record_status=0 and subbranch_info.i_record_status=0 group by area_info.id); /* mysql 不知道為什麼用異常加入判斷 ? * 這把 遊標 異常後 捕捉 * 並設定 迴圈使用 變數 stop 為 null 跳出迴圈。 */ declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop = null; /*開遊標*/ OPEN cur; /*遊標向下走一步,將查詢出來的兩個值付給定義的兩個變數*/ FETCH cur INTO mdsl,aid; /* 迴圈體 這很明顯 把遊標查詢出的 name 都加起並用 ; 號隔開 */ WHILE ( stop is not null) DO update zlgsydrsp.area_info set i_subbran_count=mdsl where id = aid ; /*遊標向下走一步*/ FETCH cur INTO mdsl,aid; END WHILE; CLOSE cur; END;
drop procedure if exists pr_product_fix; -- --------------------------------------------------------------------------- -- author : pcwl -- create date : 2010-08-21 -- description : fix product detail -- --------------------------------------------------------------------------- create procedure pr_product_fix ( i_product_id int ,out o_ret int -- 0:ok, -1:system error ) labproc:begin declare v_fetch_status int default 1; declare v_product_id int; declare v_ret int; -- ------------------------------------------------------------------------ -- cursor for select products -- ------------------------------------------------------------------------ declare cur_sel cursor for select id from product where id = i_product_id or i_product_id is null order by id; declare continue handler for NOT FOUND begin set v_fetch_status = 0; end; declare exit handler for sqlexception begin rollback; end; set o_ret = -1; -- ------------------------------------------------------------------------ -- fix data -- ------------------------------------------------------------------------ open cur_sel; lab1:loop fetch cur_sel into v_product_id; -- fix data ... if v_fetch_status = 0 then leave lab1; end if; end loop lab1; close cur_sel; set o_ret = 0; end;
下面是去掉干擾部分,只突出顯示遊標cursor的又一個過程。
drop procedure if exists pr_product_fix;
create procedure pr_product_fix
(
i_product_id int
)
begin
declare v_fetch_status int default 1;
declare v_product_id int;
-- ------------------------------------------------------------------------
-- cursor for select products
-- ------------------------------------------------------------------------
declare cur_sel cursor for
select id
from product
where id = i_product_id or i_product_id is null
order by id;
declare continue handler for NOT FOUND
begin
set v_fetch_status = 0;
end;
-- ------------------------------------------------------------------------
-- open cursor and loop cursor
-- ------------------------------------------------------------------------
open cur_sel;
lab1:loop
fetch cur_sel into v_product_id;
-- fix data ...
-- update product set detail = '' where id = v_product_id;
if v_fetch_status = 0 then
leave lab1;
end if;
end loop lab1;
close cur_sel;
end;