(注意事項: 在使用游標的時候,不能在游標聲明之前,使用crud)
存儲過程示例
CREATE DEFINER=`root`@`::1` PROCEDURE `earnings_proceduce`(out result varchar(100)) label:BEGIN #收益記錄的分配 # 基本參數的定義 # 總金額 DECLARE _total_money BIGINT DEFAULT 0; # 發放配置占比 DECLARE _deduct BIGINT; # 待發放金額 DECLARE _stay_out BIGINT DEFAULT 0; # 用戶最多保存數量 DECLARE _num BIGINT DEFAULT 0; # 查詢通寶幣總額 DECLARE _tb_num BIGINT DEFAULT 0; # 實際發放金額 DECLARE _amount BIGINT DEFAULT 0; # 定時發放時間分鍾 DECLARE _time_mi BIGINT DEFAULT 0; # 收入統計的id DECLARE _newid BIGINT; # 判斷是否遍歷全部記錄的標記 DECLARE done int default 0; # 標識事務錯誤 DECLARE err INT DEFAULT 0; DECLARE i_id BIGINT; DECLARE i_num BIGINT; # 使用游標將數據存儲到數據庫中,並進行實際發放金額的統計 DECLARE cur CURSOR FOR select c.id,sum(d.numbers) from ( select a.id from sys_user a LEFT JOIN earnings_record b ON a.id = b.user_id and b.status = '0' GROUP BY a.id having count(a.id) <= ( select deduct from earnings_manage where type = 4 )) c join zxt_detail d on c.id = d.creator group by c.id; # 出現錯誤,設置為1,只要發生異常就回滾 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET err=1; # 將結束標志綁定到游標 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; set result='0'; # 查詢總金額 select IFNULL(sum(order_money),0) into _total_money from other_order where ISNULL(issue_id); # 如果為0 就退出存儲過程 if _total_money = 0 THEN set result='查詢總金額為0,不進行發放'; LEAVE label; end if; # 查詢基本配置 select deduct into _deduct from earnings_manage where type = 0; # 計算待發放金額 set _stay_out=ROUND(_total_money * _deduct /100); # 如果為0 就退出存儲過程 if _stay_out = 0 THEN set result='待發放金額金額為0,不進行發放'; LEAVE label; end if; # 查詢通寶總額 select IFNULL(sum(numbers),0) into _tb_num from zxt_detail; # 如果為0 就退出存儲過程 if _tb_num = 0 THEN set result='通寶總金額為0,不進行發放'; LEAVE label; end if; # 定時發放的時間 select deduct * 60 into _time_mi from earnings_manage where type = 3; # 開啟事務 start TRANSACTION; # 打開游標 open cur; # 開始循環 read_loop: LOOP # 提取游標的數據 FETCH cur INTO i_id,i_num; # 聲明結束的時候 IF done = 1 THEN LEAVE read_loop; END IF; # 事務的處理 # 獲取新的id set _newid = REPLACE(unix_timestamp(current_timestamp(3)),'.',''); set i_num = FLOOR( _stay_out * i_num / _tb_num); # 添加個人收益 IF i_num != 0 THEN set _amount = _amount+i_num; INSERT INTO `earnings_record` (`creator`, `user_id`, `status`, `amount`, `create_date`) VALUES ('10000',i_id,'0',i_num, NOW()); end if; end LOOP read_loop; # 添加總收益 INSERT INTO `earnings_issue` (`id`, `stay_out`, `amount`, `other_id`, `updater`, `update_date`, `creator`, `create_date`, `deduct`, `earnings_sum`, `time_out`) VALUES (_newid, _stay_out, _amount, NULL, '10000', NOW(), '10000', NOW(),_total_money - _stay_out, _total_money, _time_mi); # 給訂單表綁定任務 update other_order set issue_id = _newid where ISNULL(issue_id); # 如果事務發生錯誤,就進行回滾 IF err=1 THEN # 如果發生回滾就表示發生發生錯誤 set result='發生了回滾,不進行發放'; ROLLBACK; ELSE commit; end if; #關閉游標 CLOSE cur; END