1. 什么是存储过程
我们常用的关系型数据库是MySQL,操作数据库的语言一般为SQL语句,SQL在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成某种特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对面向对象方法的模拟,它允许控制数据的访问方式。
存储过程就像我们编程语言中的函数一样,封装了我们的代码(PLSQL、T-SQL)。
2. 存储过程的优缺点
-
存储过程的优点:
- 能够将代码封装起来保存在数据库之中,让编程语言进行调用
- 存储过程是一个预编译的代码块,执行效率比较高
- 一个存储过程替代大量T_SQL语句 ,可以降低网络通信量,提高通信速率
- 存储过程可被作为一种安全机制来充分利用:系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全
-
存储过程的缺点:
- 每个数据库的存储过程语法几乎都不一样,十分难以维护(不通用)
- 业务逻辑放在数据库上,难以迭代
3. 实现存储过程
## 创建存储过程 ##
CREATE PROCEDURE PROCEDURE_NAME ()
BEGIN #此存储过程的正文开始
SELECT Avg(pro_price) AS priceaverage
FROM products;
END; #此存储过程的正文结束
## 创建带参数的存储过程 ##
## 三种参数类型:
#IN 输入参数
#表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
#OUT 输出参数
#该值可在存储过程内部被改变,并可返回
#INOUT 输入输出参数
#调用时指定,并且可被改变和返回
CREATE PROCEDURE ordertotal(
IN onumber INT,
OUT ototal DECIMAL(8,2) # OUT用于表明此值是用于从存储过程里输出的
)
BEGIN
SELECT Sum(item_price*quantity)
FROM orderitems
WHERE order_num = onumber
INTO ototal;
END;
## 调用带参数的存储过程 ##
CALL ordertotal(20005, @total);
## 查询结果
SELECT @total;
## 删除存储过程的方法是 ##
DROP PROCUDURE productpricing;
实例
## 这里需要注意的是DELIMITER // 和 DELIMITER ;
## DELIMITER是分割符的意思,因为MySQL默认以";"为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将";"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。
mysql> delimiter // # 将分隔符设置为//
mysql> create procedure t(OUT ot decimal(4,2))
-> begin
-> set ot=3;
-> select * from user;
-> end;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ; # 还原分隔符为;
mysql> call t(@ot);
+----------+--------+----+
| username | salary | id |
+----------+--------+----+
| lili | 2000 | 0 |
| mimi | 5000 | 1 |
| zhao by | 2000 | 2 |
+----------+--------+----+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.01 sec)
mysql> select @ot;
+------+
| @ot |
+------+
| 3.00 |
+------+
1 row in set (0.00 sec)