概述

介绍

存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。

优点

  1. 通过把处理封装在容易使用的单元中,简化复杂的操作。
  2. 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。 这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。
  3. 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。这一点的延伸就是安全性。通过存储过程限制对基础数据的访问减少了数据讹误(无意识的或别的原因所导致的数据讹误)的机会。
  4. 提高性能。因为使用存储过程比使用单独的SQL语句要快。
  5. 存在一些只能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码。

换句话说,使用存储过程有3个主要的好处,即简单、安全、高性能。

缺点

  1. 一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。
  2. 可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程

尽管有这些缺陷,存储过程还是非常有用的,并且应该尽可能地使用

创建和使用

无参数

获取全部学生的人数

1
2
3
4
5
6
DELIMITER //
CREATE PROCEDURE student_num_all()
BEGIN
SELECT COUNT(*) FROM t_student;
END
// DELIMITER;

SQL语句详解如下:

  1. DELIMITER //告诉命令行程序使用//作为新的语句结束分隔符,//也可以用其它的符号代替,例如:将//替换成&&
  2. CREATE PROCEDURE student_num_all()定义了一个名为student_num_all的存储过程
  3. BEGIN和END语句用来限定存储过程体

使用存储过程的SQL语句如下:

使用一个名称为student_num_all的存储过程

1
CALL student_num_all;

有参数

根据班级id获取学生数

1
2
3
4
5
6
DELIMITER //
CREATE PROCEDURE student_num_by_classId(IN classId INT)
BEGIN
SELECT COUNT(*) AS total FROM t_student WHERE class_id=classId;
END
// DELIMITER;

使用一个名称为student_num_by_classId的存储过程,传入的参数为classId

1
CALL student_num_by_classId(2);

调用产生的结果

上面的两个例子调用存储过程时都是直接显示结果并且只返回一个结果,如果存储过程中含有多条SQL语句且返回多个结果,那么就需要使用 OUT 和 INTO 关键词

返回对应班级id的学生人数、学生年龄的最大值、学生年龄的最小值

1
2
3
4
5
6
7
8
DELIMITER //
CREATE PROCEDURE student_num_by_classId2(IN classId INT,OUT stu_num INT,OUT max1 INT,OUT min1 INT)
BEGIN
SELECT COUNT(*) INTO stu_num FROM t_student WHERE class_id=classId;
SELECT MAX(age) INTO max1 FROM t_student;
SELECT MIN(age) INTO min1 FROM t_student;
END
// DELIMITER;

使用一个名为student_num_by_classId2的存储过程

1
CALL student_num_by_classId(2,@total,@max1,@min1);

使用产生的结果

1
SELECT @total AS total,@max1 AS max_age,@min1 AS min_age;

删除

删除一个名为student_num_all的存储过程

1
DROP PROCEDURE student_num_all;

检查

为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句

1
SHOW CREATE PROCEDURE student_num_all;

列出所有存储过程

1
SHOW PROCEDURE STATUS;

如果要限制输出,则使用 LIKE 关键词过滤结果,后面需要接一个完整的存储过程名称

1
SHOW PROCEDURE STATUS LIKE 'student_num_by_classId';