序言:
使用存储过程后就可以记录一系列的操作并批量运行他们。如果需要多次执行相同的sql命令,就可以事先把这个处理定义为存储过程

12.1什么是存储过程

  1. 存储过程只能在sql5.0以上的版本使用<br /> ** 存储过程:**<br /> 将多个sql语句组合成只要要call xx就能执行的集合,这个集合就要存储过程,也就是说存储过程就是将一些列步骤并存储起来的集合。<br /> 注意:虽然可以自动执行许多事先准备好的命令,所以处理效率很高。但是在存储了重要的数据的数据库中,执行没有经过充分验证的存储过程是非常危险的

12.2使用存储过程

12.2.1创建存储过程

       当创建存储过程时我们需要向下面这样执行create procedure命令<br />  **  语法:**

create procedure 存储过程名() begin sql语句1; sql语句2; end

 从begin 到end 为止的内容是存储过程的主体<br />**   修改分割符设置:**<br /> 因为存储过程的内容是普通的sql语句,所以需要在命令的末尾添加分隔符“;”,但是mysql中一旦输入“;”,不   管什么内容都会执行,所以就会导致create procedure命令在存储过程不完整的状态下执行。所以我们需要在执行create procedure前修改分隔符,一般改为“//”<br />   语法:

delimiter //;

使用create procedure 之后就可再次使用delimiter将其恢复
示列:创建查询tb表和tb1表的储存过程

mysql> delimiter //  /*先修改分隔符*/
mysql> create procedure prl()  /*创建名为prl的存储过程*/
    -> begin
    -> select * from tb;
    -> select * from tb1;
    -> end
    -> //
Query OK, 0 rows affected (0.01 sec)

12.2.2执行存储过程

执行存储过程需要call <br /> ** 语法**

call 存储过程名

示列:执行prl存储过程

mysql> call prl();
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A103  |   101 |     4 |
| A103  |   101 |     4 |
| A104  |   181 |     5 |
| A101  |   184 |     4 |
| A103  |    17 |     5 |
| A101  |   300 |     5 |
| A102  |   205 |     6 |
| A104  |    93 |     5 |
| A103  |    12 |     6 |
| A107  |    87 |     6 |
+-------+-------+-------+
10 rows in set (0.00 sec)

+-------+------+------+
| empid | name | age  |
+-------+------+------+
| A101  | 佐藤 |   40 |
| A102  | 高桥 |   28 |
| A103  | 中川 |   20 |
| A104  | 渡边 |   23 |
| A105  | 西泽 |   35 |
+-------+------+------+
5 rows in set (0.02 sec)

Query OK, 0 rows affected (0.03 sec)

mysql>

12.2.3只显示大于等于指定值的记录的存储过程

我们创建带参数的存储过程,需要将处理的数据指定为()中的参数
语法;

create priocedure 存储过程名(参数名 数据类型)

示列:创建一个显示销售额大于指定值的记录的存储过程

mysql> delimiter //
mysql> create procedure pr2(d int)
    -> begin
    -> select * from tb where sales>=d;/*根据传入的参数作为条件*/
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call pr2(200);/*传入指定的参数*/
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A101  |   300 |     5 |
| A102  |   205 |     6 |
+-------+-------+-------+
2 rows in set (0.00 sec)

Query OK, 0 rows affected (0.03 sec)

12.3 显示、删除存储过程

12.3.1显示存储过程的内容

     我们可以 通过下面的命令来显示存储过程的内容<br />  语法

show create procedure 存储过程名

示列:显示pr2的存储过程


mysql> show create procedure pr2;/*不用加括号*/
+-----------+----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Procedure | sql_mode                                                       | Create Procedure                                                                                    | character_set_client | collation_connection | Database Collation |
+-----------+----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| pr2       | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` PROCEDURE `pr2`(d int)
begin
select * from tb where sales>=d;
end | gbk                  | gbk_chinese_ci       | latin1_swedish_ci  |
+-----------+----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

12.3.2删除存储过程

 和删除数据库,表格,视图一样<br />   ** 语法:**

drop procedure 存储过程名

示列:删除存储过程prl

mysql> drop procedure prl;
Query OK, 0 rows affected (0.01 sec)

mysql>

12.4存储函数

12.4.1什么是存储函数

      存储函数也只能在mysql5.0以上的版本使用<br />        **  存储函数:**储存函数的操作方法与存储过程基本相同。但是,存储函数会在执行后返回一个值,该值可以用在select、update命令中<br />**  创建储存函数语法:**

create function 存储函数名(参数 数据类型) returns 返回值的数据类型 begin sql 语句.. return 返回值·表达式 end

和存储过程一样。我们可以在()内指定参数。即使完全没有指定参数,也必须加上()。

12.5使用存储函数

12.5.1使用存储函数之前

       ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622600455850-ef0842b8-f4ea-437e-a587-6fafa00f802e.png#clientId=u8ce3a651-6e27-4&from=paste&height=96&id=u0b389563&margin=%5Bobject%20Object%5D&name=image.png&originHeight=192&originWidth=1342&originalType=binary&size=267029&status=done&style=none&taskId=u8b1f4447-0e1e-49b5-81d4-8ec91c6fa3b&width=671)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622600468488-a8ecbaf5-4632-4a9e-96db-4a99f54250bf.png#clientId=u8ce3a651-6e27-4&from=paste&height=219&id=ua987ff44&margin=%5Bobject%20Object%5D&name=image.png&originHeight=438&originWidth=1234&originalType=binary&size=509492&status=done&style=none&taskId=ue3f43b76-4e4b-418f-90b5-af81ded2a12&width=617)    <br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622600483666-563c71ad-a31f-433d-b35d-70fa8393abec.png#clientId=u8ce3a651-6e27-4&from=paste&height=308&id=uf00c0bd1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=615&originWidth=1328&originalType=binary&size=725811&status=done&style=none&taskId=ud3892c4a-6d7b-4fa1-8c7b-d4a34f36e9f&width=664)

12.5.2创建并使用存储函数

示列一:创建计算体重存储函数f1,并使用;

mysql> create function f1(h int) returns double
    -> begin
    -> return h*h*23/10000;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> select f1(174);
+---------+
| f1(174) |
+---------+
| 69.6348 |
+---------+
1 row in set (0.00 sec)

mysql>

示列二:返回记录平局值的储存函数

mysql> create function f2() returns double
    -> begin
    -> declare r double;/*使用 declare 变量名 数据类型 定义了变量r*/
    -> select avg(sales) into r from tb;/*into r 表示把avg(sales)的值赋值给 r*/
    -> return r;
    -> end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> select f2();
+-------+
| f2()  |
+-------+
| 128.1 |
+-------+
1 row in set (0.00 sec)

mysql>

示列详解:
上述程序中使用了定义变量的语法,变量要在使用前定义
定义变量:

declare 变量名 数据类型

15.5.3显示和删除储存函数

删除存储函数:

drop function 存储函数名

显示存储内容

show create function 储存函数名

12.6触发器

12.6.1什么是触发器

       触发器是一种对表执行某些操作后会触发执行其他命令的机制,当执行insert、update和delete等命令时,作为触发器提前设置好的操作也会执行。<br />         列如:创建一个触发器,当某表的记录发生更新时,就以此为契机将更新的内容记录到另一个表中。<br />      触发器也常作为处理的记录或者失败时备份使用<br />     ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622603195309-10faf10a-cece-4bf4-b14f-602a4b6751f8.png#clientId=u8ce3a651-6e27-4&from=paste&height=287&id=u96bc43e7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=383&originWidth=1288&originalType=binary&size=475236&status=done&style=none&taskId=ub050fb74-9b41-4428-918d-555c0b8a944&width=966)

12.7创建触发器

12.7.1触发器被触发的时机

触发器被触发的时机包含以下两种:
image.png
同时,对表处理之前的列值和对表处理之后的列值,可以通过以下命令获得
image.png
也就是说执行insert、update和delete命令之前的列值可以通过OLD.列名获得,执行这些命令只会的列名可以通过new.列名获得,但是根据命令的不同,有的列的值可以取出,有的不能取出(见下图)↓
xia image.png

12.7.2创建触发器

 创建触发器的具体命令如下↓<br />    ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12862216/1622603626358-67d10b9a-c5d6-4cd2-a31a-14c5b45dedfc.png#clientId=u8ce3a651-6e27-4&from=paste&height=132&id=u06390e71&margin=%5Bobject%20Object%5D&name=image.png&originHeight=264&originWidth=1228&originalType=binary&size=279800&status=done&style=none&taskId=u5ea4a57a-887a-4a0f-89cd-5f6590ce81a&width=614)<br />      在触发器主体的描述中,各个命令的末尾需要加上“;”。与创建存储过程时相同,我们需要先使用delimiter将分隔符变为“//”;<br />**示列:创建将表tb1中删除的记录插入到表tb1_from的触发器**
mysql>  delimiter //
mysql> create trigger tr1 before delete on tb1 for each row
    -> begin
    -> insert into tb1_from values(old.empid,old.name,old.age);
    -> end
    -> //
Query OK, 0 rows affected (0.02 sec)
mysql>  delimiter ;
mysql> delete from tb1;/*删除tb1表中的所有内容*/
mysql> select*from tb1;
Empty set (0.00 sec)
Query OK, 5 rows affected (0.01 sec)
mysql> select*from tb1_from;/*被触发器自动添加到tb1_from表中*/
+-------+------+------+
| empid | name | age  |
+-------+------+------+
| A101  | 佐藤 |   40 |
| A102  | 高桥 |   28 |
| A103  | 中川 |   20 |
| A104  | 渡边 |   23 |
| A105  | 西泽 |   35 |
+-------+------+------+
5 rows in set (0.00 sec)

示列详解:
image.png

12.8确认和删除触发器

12.8.1确认设置的触发器

  我看可以使用show triggers命令确认当前设置的触发器<br />   **语法:**

show triggers;

示列:查看触发器

mysql> show triggers;
+---------+--------+-------+--------------------------------------------------------------------+--------+------------------------+----------------------------------------------------------------+----------------+----------------------+----------------------+--------------------+
| Trigger | Event  | Table | Statement                                                          | Timing | Created                | sql_mode                                                       | Definer        | character_set_client | collation_connection | Database Collation |
+---------+--------+-------+--------------------------------------------------------------------+--------+------------------------+----------------------------------------------------------------+----------------+----------------------+----------------------+--------------------+
| tr1     | DELETE | tb1   | begin
insert into tb1_from values(old.empid,old.name,old.age);
end | BEFORE | 2021-06-02 11:30:14.03 | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | root@localhost | gbk                  | gbk_chinese_ci       | latin1_swedish_ci  |
+---------+--------+-------+--------------------------------------------------------------------+--------+------------------------+----------------------------------------------------------------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)

12.8.2删除触发器

 通过drop来删除触发器<br /> ** 语法:**

drop trigger 触发器名

示列:删除触发器tr1

mysql> drop trigger tr1;
Query OK, 0 rows affected (0.01 sec)

mysql> show triggers;
Empty set (0.00 sec)

mysql>