最近在使用Mysql時,經常需要用到游標,所以將使用方法做下記錄以備日后查看。(這里只是為了說明游標的用法,不會涉及復雜的業務邏輯,所以舉的例子可能並不恰當)
首先,創建兩張表departmentinfo(部門信息表)和employeeinfo(員工信息表)

表結構如下:
表departmentinfo存儲部門名及部門總銷售額

表employeeinfo存儲員工名、員工所在部門ID及員工個人銷售額

表中初始數據如下:
各部門總銷售額均為0

員工分別在3個部門下,且都有自己的銷售額

然后創建存儲過程P_ChangeSales,代碼如下
CREATE DEFINER = 'root'@'localhost' PROCEDURE test.P_ChangeSales(OUT ExtReturnValue INT) TOP: BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SET ExtReturnValue = 0; -- Failed END; START TRANSACTION; BEGIN DECLARE isLeave INT; -- 是否要跳出循環,0:繼續 1:跳轉 DECLARE depId INT; -- 部門ID變量 DECLARE salesVal INT; -- 銷售額變量 DECLARE curSales CURSOR FOR SELECT DepartmentID,Sales FROM employeeinfo; -- 聲明游標 DECLARE CONTINUE HANDLER FOR NOT FOUND SET isLeave = 1; -- 出現溢出則賦值為1,作為跳出循環的判斷 OPEN curSales; -- 開啟游標 SET isLeave = 0; curSales_loop:LOOP FETCH curSales INTO depId, salesVal; IF isLeave = 1 THEN -- 循環結束 LEAVE curSales_loop; ELSE UPDATE departmentinfo SET Sales = Sales + salesVal WHERE DepartmentID = depId; -- 增加部門總銷售額 END IF; END LOOP curSales_loop; CLOSE curSales; -- 關閉游標 END; UPDATE employeeinfo SET Sales = 0; -- 員工個人銷售額清0 SET ExtReturnValue = 1; -- Success COMMIT; END
現在我們執行上面的存儲過程

存儲過程執行成功,得到返回值1。查看表中數據
表departmentinfo中計算出的部門總銷售額

表employeeinfo中員工的個人銷售額變為0

至此,我們完成了Mysql中游標的簡單應用。
還有一點需要注意,存儲過程中變量的定義不要和我們表中的字段名相同,不然會有問題。例如,我們將存儲過程中的所有”salesVal”全部改為”sales”與字段名”Sales”相同(不區分大小寫)。此時保存修改,並不會報錯,存儲過程也可以執行,但是會得到如下返回值

我們的存儲過程執行時出現問題,進行了回滾,才會得到這個返回值。
下面我們對存儲過程進行調試發現,執行到”FETCH … INTO …”后,”depId”中得到正確的值,但是”sales”的值為NULL。

所以存儲過程在執行到下面的sql語句時,出錯回滾,這點大家一定要注意。
