在工做中遇到要程序根據時間自動增長工齡的需求。php
php沒辦法本身發起請求,又不想在服務器上寫計劃任務crontab,經過用戶請求來更改又不能保證用戶會去操做。mysql
用數據庫的存儲過程和事件來完成。sql
數據庫裏有建立時間字段(created)和工齡(working_years)字段。數據庫
存儲過程:服務器
DROP PROCEDURE if EXISTS auto_working_years; CREATE PROCEDURE auto_working_years() BEGIN DECLARE ns INT DEFAULT 1; DECLARE myuid INT DEFAULT 0; DECLARE cur1 CURSOR FOR SELECT uid FROM `user` WHERE (role='ganger' OR role='worker') AND (DATEDIFF(CURRENT_DATE(),created)>365); DECLARE EXIT HANDLER FOR NOT FOUND SET ns = 0; OPEN cur1; WHILE ns <> 0 DO FETCH cur1 into myuid; UPDATE `user` SET working_years = working_years+1 , created = DATE_ADD(created,INTERVAL 365 DAY) WHERE uid = myuid; END WHILE; CLOSE cur1; END; call auto_working_years();
首先定義遊標,查詢語句篩選出user表裏角色是工人和工長的建立時間大於365天的記錄。函數
開啓遊標ui
更新這些記錄的表字段工齡+1,同時修改建立時間加一年,這裏能夠另建立一個字段用於對已經增長了工齡的記錄作標記。把建立時間這一列複製過去。用新的字段來作判斷就不會影響到建立時間。spa
這裏用了兩個mysql的系統時間函數 分別是DATEDIFF和DATE_ADD,一個獲取時間差,一個增長時間間隔,間隔時間能夠本身定義單位。code
參數ns用於作是否執行循環的判斷。blog
關閉遊標
call用於調用存儲過程。
還有個問題是存儲過程執行事後記錄已經更改可是顯示的受影響行數是0
存儲過程寫完了接下來就是定時器了。我定義這個存儲過程每週執行一次。
drop event if exists workingyearsEvent; create event workingyearsEvent on schedule every 7 day starts '2019-1-16 0:0:0' on completion PRESERVE do call auto_working_years();
剩下的就是須要打開mysql裏面的一些設置
檢查事件任務是否開啓 SHOW VARIABLES LIKE 'event_scheduler';
set GLOBAL event_scheduler = 1;
ALTER EVENT workingyearsEvent ENABLE;
保證定時任務能正常執行了。