mysql触发器+事件+存储过程+临时表

目录

 

一. MySQL事件Event

二. MySQL触发器trigger

三. MySQL存储过程Stored Procedure

四. MySQL临时表


一. MySQL事件Event

1. 事件简介

事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。

事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。

事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。

2. 事件的优缺点
2.1 优点

 一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能。

可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用了。

2.2 缺点
定时触发,不可以调用。

3. 创建事件

一条create event语句创建一个事件。每个事件由两个主要部分组成

第一部分是事件调度(event schedule),表示事件何时启动以及按什么频率启动

第二部分是事件动作(event action ),这是事件启动时执行的代码

事件的动作包含一条SQL语句,它可能是一个简单地insert或者update语句,也可以使一个存储过程或者 benin...end语句块,这两种情况允许我们执行多条SQL。

一个事件可以是活动(打开)的或停止(关闭)的,活动意味着事件调度器检查事件动作是否必须调用,停止意味着事件的声明存储在目录中,但调度器不会检查它是否应该调用。在一个事件创建之后,它立即变为活动的,一个活动的事件可以执行一次或者多次。

3.1 创建语法如下

CREATE 

    [DEFINER = { user | CURRENT_USER }] 

    EVENT 

    [IF NOT EXISTS] 

    event_name 

    ON SCHEDULE schedule 

    [ON COMPLETION [NOT] PRESERVE] 

    [ENABLE | DISABLE | DISABLE ON SLAVE] 

    [COMMENT 'comment'] 

    DO event_body; 

   

schedule: 

    AT timestamp [+ INTERVAL interval] ... 

  | EVERY interval 

    [STARTS timestamp [+ INTERVAL interval] ...] 

    [ENDS timestamp [+ INTERVAL interval] ...] 

   

interval: 

    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | 

              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE | 

              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND} 

 名词解释:

    event_name :创建的event名字(唯一确定的)。
    ON SCHEDULE:计划任务。
    schedule: 决定event的执行时间和频率(注意时间一定要是将来的时间,过去的时间会出错),有两种形式 AT和EVERY。
    [ON COMPLETION [NOT] PRESERVE]: 可选项,默认是ON COMPLETION NOT PRESERVE 即计划任务执行完毕后自动drop该事件;ON COMPLETION  PRESERVE则不会drop掉。
    [COMMENT 'comment'] :可选项,comment 用来描述event;相当注释,最大长度64个字节。
    [ENABLE | DISABLE] :设定event的状态,默认ENABLE:表示系统尝试执行这个事件, DISABLE:关闭该事情,可以用alter修改
    DO event_body: 需要执行的sql语句(可以是复合语句)。CREATE EVENT在存储过程中使用时合法的。

3.2 开启关闭事件调度器

3.2.1 MySQL事件调度器event_scheduler负责调用事件,它默认是关闭的。这个调度器不断地监视一个事件是否要调用, 要创建事件,必须打开调度器。

mysql> show variables like '%event_scheduler%'; 

+-----------------+-------+ 

| Variable_name   | Value | 

+-----------------+-------+ 

| event_scheduler | OFF   | 

+-----------------+-------+ 

3.2.2 开启事件调度器

通过命令行 可通过如下任何一个命令行  重启mysql后恢复,事件不执行,重新设置

SET GLOBAL event_scheduler = ON; 

SET @@global.event_scheduler = ON; 

SET GLOBAL event_scheduler = 1; 

SET @@global.event_scheduler = 1;  

通过配置文件my.cnf   

event_scheduler = 1 #或者ON

3.2.3查看调度器线程

mysql> show processlist; 

+----+-----------------+-----------+------+---------+------+------------------------+------------------+ 

| Id | User            | Host      | db   | Command | Time | State                  | Info             | 

+----+-----------------+-----------+------+---------+------+------------------------+------------------+ 

|  2 | root            | localhost | NULL | Query   |    0 | NULL                   | show processlist | 

|  3 | event_scheduler | localhost | NULL | Daemon  |    6 | Waiting on empty queue | NULL             | 

+----+-----------------+-----------+------+---------+------+------------------------+------------------+  

3.2.4 关闭事件调度器

通过命令行 可通过如下任何一个命令行

SET GLOBAL event_scheduler = OFF; 

SET @@global.event_scheduler = OFF; 

SET GLOBAL event_scheduler = 0; 

SET @@global.event_scheduler = 0; 

通过配置文件my.cnf

event_scheduler = 0 #或者OFF,DISABLED 

3.3 创建

3.3.1 立即启动事件

create event event_now on schedule every 1 second do INSERT INTO event_list values('', now(), '111');

3.3.2 每秒钟调用存储过程

CREATE DEFINER=`root`@`localhost` EVENT `eventUpdateStatus` ON SCHEDULE EVERY 1 SECOND STARTS '2017-11-21 00:12:44' ON COMPLETION PRESERVE ENABLE DO call updateStatus()

4. 查看事件

查看当前所在库的事件mysql> show events; 

查看所有事件mysql> select * from mysql.event;

5. 修改事件

一条alter event语句可以修改事件的定义和属性。我们可以让一个事件成为停止的或者再次让它活动,也可以修改一个事件的名字或者整个调度。然而当一个使用 ON COMPLETION NOT PRESERVE 属性定义的事件最后一次执行后,事件直接就不存在了,不能修改。

5.1 语法如下:

ALTER 

    [DEFINER = { user | CURRENT_USER }] 

    EVENT event_name 

    [ON SCHEDULE schedule] 

    [ON COMPLETION [NOT] PRESERVE] 

    [RENAME TO new_event_name] 

    [ENABLE | DISABLE | DISABLE ON SLAVE] 

    [COMMENT 'comment'] 

    [DO event_body] 

6.删除事件

如果一个事件不再需要,我们可以使用一条drop event 语句删除它。使用这条语句我们不需要等到最后一次事件调用。

6.1 基本语法DROP EVENT [IF EXISTS] event_name;

 

二. MySQL触发器trigger

1. 触发器是与表有关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。

2. 触发器的特性:

1、有begin end体,begin end;之间的语句可以写的简单或者复杂

2、什么条件会触发:I、D、U

3、什么时候触发:在增删改前或者后

4、触发频率:针对每一行执行

5、触发器定义在表上,附着在表上。

触发器尽量少的使用,因为不管如何,它还是很消耗资源,如果使用的话要谨慎的使用,确定它是非常高效的:触发器是针对每一行的;对增删改非常频繁的表上切记不要使用触发器,因为它会非常消耗资源。 

3. 创建触发器

CREATE

    [DEFINER = { user | CURRENT_USER }]

TRIGGER trigger_name

trigger_time trigger_event

ON tbl_name FOR EACH ROW

[trigger_order]

trigger_body

 

trigger_time: { BEFORE | AFTER }

trigger_event: { INSERT | UPDATE | DELETE }

trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

BEFORE和AFTER参数指定了触发执行的时间,在事件之前或是之后。

FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器,也就是说触发器的触发频率是针对每一行数据触发一次。

4. tigger_event详解:

INSERT型触发器:插入某一行时激活触发器,可能通过INSERT、LOAD DATA、REPLACE 语句触发(LOAD DAT语句用于将一个文件装入到一个数据表中,相当与一系列的INSERT操作);

UPDATE型触发器:更改某一行时激活触发器,可能通过UPDATE语句触发;

DELETE型触发器:删除某一行时激活触发器,可能通过DELETE、REPLACE语句触发。

trigger_order是MySQL5.7之后的一个功能,用于定义多个触发器,使用follows(尾随)或precedes(在…之先)来选择触发器执行的先后顺序。 

5. 创建只有一个执行语句的触发器

CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件 ON 表名 FOR EACH ROW 执行语句;

CREATE TRIGGER event_list_insert BEFORE INSERT ON event_list

FOR EACH ROW

insert into trigger_list values('', NOW(), NEW.time);

创建有多个执行语句的触发器

CREATE TRIGGER 触发器名 BEFORE|AFTER 触发事件

ON 表名 FOR EACH ROW

BEGIN

        执行语句列表

END;

6. NEW与OLD详解

MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据,来引用触发器中发生变化的记录内容,具体地:

  在INSERT型触发器中,NEW用来表示将要(BEFORE)或已经(AFTER)插入的新数据;

  在UPDATE型触发器中,OLD用来表示将要或已经被修改的原数据,NEW用来表示将要或已经修改为的新数据;

  在DELETE型触发器中,OLD用来表示将要或已经被删除的原数据;

使用方法:

NEW.columnName (columnName为相应数据表某一列名)

另外,OLD是只读的,而NEW则可以在触发器中使用 SET 赋值,这样不会再次触发触发器,造成循环调用。

7. 查看触发器

7.1 SHOW TRIGGERS语句查看触发器信息

mysql> SHOW TRIGGERS;

结果,显示所有触发器的基本信息;无法查询指定的触发器。

7.2 在information_schema.triggers表中查看触发器信息

mysql> SELECT * FROM information_schema.triggers

7.3 除触发器

DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

如果不需要某个触发器时一定要将这个触发器删除,以免造成意外操作,

 

三. MySQL存储过程Stored Procedure

1. 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

1.1 优点

存储过程可封装,并隐藏复杂的商业逻辑。

存储过程可以回传值,并可以接受参数。

存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。

存储过程可以用在数据检验,强制实行商业逻辑等。

1.2 缺点

存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。

存储过程的性能调校与撰写,受限于各种数据库系统。

2. 创建存储过程

CREATE

    [DEFINER = { user | CURRENT_USER }]

PROCEDURE sp_name ([proc_parameter[,...]])

    [characteristic ...] routine_body

proc_parameter:

    [ IN | OUT | INOUT ] param_name type

characteristic:

    COMMENT 'string'

  | LANGUAGE SQL

  | [NOT] DETERMINISTIC

  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }

  | SQL SECURITY { DEFINER | INVOKER }

routine_body:

Valid SQL routine statement

[begin_label:] BEGIN

[statement_list]

……

END [end_label]

3. MYSQL 存储过程中的关键语法

声明语句结束符,可以自定义:

DELIMITER $$  DELIMITER //

使用 DELIMITER \$\$ 命令将语句的结束符号从分号 ; 临时改为两个 \$\$,

使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。

 

声明存储过程:

CREATE PROCEDURE demo_in_parameter(IN p_in int)     

存储过程开始和结束符号:

BEGIN .... END    

 

变量赋值:

SET @p_in=1  

 

变量定义:

DECLARE l_int int unsigned default 4000000;

 

创建mysql存储过程、存储函数:

create procedure 存储过程名(参数)

 

存储过程体:

create function 存储函数名(参数)

 

调用:

call sp_name[(传参)];

 

4. 查看存储过程

SHOW PROCEDURE STATUS  [where db='数据库名'];

SELECT *  FROM mysql.proc

show create procedure 数据库.存储过程名

select name from mysql.proc where db='数据库名';

5. 修改、删除存储过程

ALTER PROCEDURE

DROP PROCEDURE 存储过程名;

6. 存储过程的参数

三种参数类型 IN  OUT  INOUT

CREATE PROCEDURE 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形...])

IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)

OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)

INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理

7. 变量

7.1 定义变量

DECLARE variable_name [,variable_name...] datatype [DEFAULT value];

datatype  -> int, float, date,varchar(length)

Eg: DECLARE int1 int unsigned default 1;

7.2 变量赋值

SET 变量名 = 表达式值 [,variable_name = expression ...]

7.3用户变量

用户变量名一般以@开头

滥用用户变量会导致程序难以理解及管理

CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World');

mysql > SET @greeting='Hello';

mysql > CALL GreetWorld( );  -> Hello World

8. 控制语句

8.1 变量作用域

内部的变量优先,对外不可见。

8.2 条件语句

8.2.1 if语句

if 条件 then

    语句

else

    语句

end if;

8.2.2 case语句

case 变量

    when 期望值1 then

    语句

    when 期望值2 then

    语句

else

    语句

end case;

 

case

    when var=0 then

        insert into t values(30);

    when var>0 then

        when var<0 then

    else

end case;

8.2.3 循环

while 条件 do

    --循环体

end while

 

repeat

    --循环体

    until 循环条件  

end repeat;

 

loop 循环不需要初始条件,这点和 while 循环相似,同时和 repeat 循环一样不需要结束条件, leave 语句的意义是离开循环。

LOOP_LABLE:loop

    语句

    leave LOOP_LABLE;  --if var>2 then leave LOOP_LABLE; end if;

    语句

end loop;

8.2.4 LABLES 标号:

标号可以用在 begin repeat while 或者 loop 语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。

8.2.5 ITERATE迭代

ITERATE 通过引用复合语句的标号,来从新开始复合语句

LOOP_LABLE:loop

    语句

    ITERATE LOOP_LABLE; --if var>2 then ITERATE LOOP_LABLE; end if;

    语句

    leave LOOP_LABLE;  --if var>2 then leave LOOP_LABLE; end if;

    语句

end loop;

9. 实例

delimiter $$

create procedure procedure_list_delete(in list_id integer)

begin

delete from procedure_list where id = list_id;

end$$

delimiter ;

 

调用

call procedure_list_delete(1);

 

四. MySQL临时表

临时表:表建在内存里,数据在内存里 临时表主要是为了放一些中间结果集
内存表:表建在磁盘里,数据在内存里 存储引擎为MEMORY

 

MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。每当PHP脚本执行完成后,该临时表也会自动销毁。MySQL客户端程序连接MySQL数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,也可以手动销毁。临时表默认的是Mysql指定的默认Engine。

SHOW TABLES不可见,SHOW CREATE TABLE 表名可见。

 

1. 建表

create temporary table 表名;

drop table 表名;

create temporary table tests(id VARCHAR(50) NOT NULL);

你可能感兴趣的:(mysql)