【MySQL】Event事件與遊標

MySQL的事件就像Linux系統上的定時任務,按照設置的時間或者間隔時間執行設置好的任務。html

若是用SQLyog一類的寫存儲過程、觸發器或者事件會省事一些,例如SQLyog就會生成一個大體的模板:mysql

 1 DELIMITER $$
 2 CREATE EVENT `report`.`monitor_user4cx` ON SCHEDULE EVERY 15 MINUTE  DO 
 3 BEGIN
 4 DECLARE cx_id INT(10);
 5 DECLARE t_query VARCHAR(500);
 6 DECLARE done INT DEFAULT FALSE;
 7 DECLARE cur CURSOR FOR SELECT id FROM information_schema.PROCESSLIST WHERE `USER`='cx' AND `TIME` > 600 AND `Command`='Query';
 8 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 9 OPEN cur;
10 read_loop:LOOP
11 FETCH cur INTO cx_id;
12 IF done THEN
13 LEAVE read_loop;
14 END IF;
15 SELECT t.trx_query,t.trx_started,p.`USER` FROM information_schema.PROCESSLIST p INNER JOIN information_schema.innodb_trx t ON p.id=t.trx_mysql_thread_id WHERE p.id=cx_id INTO @t_query,@t_time,@p_user;
16 INSERT INTO test.monitor_user4cx(`p_id`,`start_time`,`user`,`time`,`query`) VALUES (cx_id,@t_time,@p_user,NOW(),@t_query);
17 KILL cx_id;
18 END LOOP;
19 CLOSE cur;
20 END$$
21 DELIMITER ;
View Code

遊標的寫法:sql

CREATE PROCEDURE `test`.`new_procedure` ()
BEGIN
  -- 須要定義接收遊標數據的變量 
  DECLARE a CHAR(16);
  -- 聲明遊標的結束標誌
  DECLARE done INT DEFAULT FALSE;
  -- 將所需數據賦予遊標,遊標必須定義在變量/條件後,handler前;不然會報錯。
 -- ERROR 1337 (42000): Variable or condition declaration after cursor or handler declaration
DECLARE cur CURSOR FOR SELECT i FROM test.t; -- 將結束標誌綁定到遊標,若是捕獲到not found異常時就會將變量done設置爲TRUE,done=TRUE能夠看成循環跳出條件 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 打開遊標 OPEN cur; -- 開始循環 read_loop: LOOP -- 提取遊標裏的數據,這裏只有一個,也能夠有多個,例如fetch <遊標名> into <變量1>,<變量2> FETCH cur INTO a; -- 聲明結束的時候 IF done THEN LEAVE read_loop; END IF; -- 這裏作你想作的循環的事件 sql; END LOOP; -- 關閉遊標 CLOSE cur; END

遊標示例:ide

一、repeat循環(該循環用do while,先執行後判斷)oop

drop procedure if exists test_proce2;  
create procedure test_proce2()  
begin  
    declare temp_id int(11);  
    declare temp_time datetime;  
    declare isFinished boolean default false;  
    declare test_cursor cursor for select id,time from test;  
    declare continue handler for not found set isFinished=true;  
    open test_cursor;  
    repeat  
        fetch test_cursor into temp_id,temp_time;  
        if not isFinished then  
            select concat(concat(temp_id,":"),temp_time);  
        end if;  
    until isFinished end repeat;  
   close test_cursor;  
  end  

二、loop循環fetch

 drop procedure if exists test_proce3;  
create procedure test_proce3()  
begin  
    declare temp_id int(11);  
    declare temp_time datetime;  
    declare isFinished boolean default false;  
    declare test_cursor cursor for select id,time from test;  
    declare continue handler for not found set isFinished=true;  
    open test_cursor;  
    test_loop:loop  
        fetch test_cursor into temp_id,temp_time;  
        if isFinished then  
            leave test_loop;  
        end if;  
        //若該if語句放在fetch後面,該循環爲while型;若該if語句緊接在end loop前該循環爲do while型。  
        select concat(concat(temp_id,":"),temp_time);  
    end loop test_loop;  
  close test_cursor;  
 end  

 

示例:spa

按期檢查長時間執行的查詢,記錄並殺掉.net

DELIMITER $$
CREATE EVENT `report`.`monitor_user4cx` ON SCHEDULE EVERY 15 MINUTE  DO 
BEGIN
DECLARE cx_id INT(10);
DECLARE t_query VARCHAR(500);
DECLARE done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR SELECT id FROM information_schema.PROCESSLIST WHERE `USER`='cx' AND `TIME` > 600 AND `Command`='Query';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop:LOOP
FETCH cur INTO cx_id;
IF done THEN
LEAVE read_loop;
END IF;
SELECT t.trx_query,t.trx_started,p.`USER` FROM information_schema.PROCESSLIST p INNER JOIN information_schema.innodb_trx t ON p.id=t.trx_mysql_thread_id WHERE p.id=cx_id INTO @t_query,@t_time,@p_user;
INSERT INTO test.monitor_user4cx(`p_id`,`start_time`,`user`,`time`,`query`) VALUES (cx_id,@t_time,@p_user,NOW(),@t_query);
KILL cx_id;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;

 

語法中變量的使用方法:code

### 能夠直接用set賦值
set @a=1;
set @b=(select count(*) from information_schema.processlist);
insert into test_db.table1 select @a,@b,now();

### 能夠用into將結果集賦值給變量
select id,name,create_time from test_db.table2 into @u_id,@u_name,@u_addtime;
同
select id,name,create_time into @u_id,@u_name,@u_addtime from test_db.table2;
select @u_id,@u_name,@u_addtime;

 

刪除事件:orm

drop event event_name;

 

部份內容轉自:

http://www.cnblogs.com/trying/p/3296793.html

http://blog.csdn.net/willchyis/article/details/7943467

相關文章
相關標籤/搜索