存储过程:为了以后的使用而保存的一条或多条MySQL语句的集合,也可以看成一个函数
版本要求: MySQL 5 添加了对存储过程的支持,所以mysql 版本要达到mysql 5 及以后的版本
使用情形:
大多数sql 都是针对一个或多个表的单挑语句。并非所有操作都这么简单,经常会有一个完整的操作需要多条语句。 1、为了处理订单,需要核对以保证库存中有相应的物品 2、如果库存有物品,这些物品需要预定以便不将他们再卖给别人,并且要减少可用物品数量以反映正确的库存量 3、库存中没有的物品需要订购,这需要与供应商进行某种交互 4、关于哪些物品入库(并且可以立即发货)和哪些物品退订,需要通知相关客户 完成上述需要,需要针对许多表的多条sql 语句,此外,需要执行的具体语句及其次序也不是固定的,他们可能会根据那些物品在库存中那些不在的而变化。 解决方式: 可以单独编写每条语句,并根据结果有条件地执行另外的语句。在每次需要这个时(以及每个需要它的应用中)都必须做这些工作,这个时候存储过程就可以丝滑的处理上述问题。
使用存储过程
一、创建存储过程 (PROCEDURE BEGIN END)
使用create procedure 名字() 语句定义,如果存储过程接收参数,就在括号里列举出来,begin 和end 语句用来限制存储过程体,过程体中一一般是select 语句。常常会和 delimiter(定义sql语句分隔符),放在一块使用,因为select 与也是用 ;结尾,不自定义就会不能创建成功存储过程。
下面先介绍一下,
ONE、无参数的存储过程
--下面的sql 开始使用 // 作为结尾 delimiter // --创建一个存储过程 关键字时 procedure 名字是 proce_product() create procedure proce_product() -- 开始存储 begin -- 一条sql 语句 select * from products; -- 结束 end //
执行调用一下
TWO、使用参数时:
一般存储过程并不显示结果,而是把结果返回给你指定的变量
变量(variable):内存中一个特定位置,用来临时存储数据。
此存储过程接收三个参数,每个参数必须指定类型,这里使用十进制,
关键字out指出相应的的参数用来从存储过程传出一个值,返回给调用者
MySQL支持in(传递给存储过程),out(从存储过程传出) 和into(对存储过程传入和传出)类型的参数
存储过程的代码位于begin 和end 语句内,一般为一系列的select 语句,用来检索值然后保存到相应的变量中
1、使用 into
mysql> delimiter $$ mysql> create procedure proce_obge_testproduct (out minp decimal(8,2),out maxp decimal(8,2),out sump decimal(8,2)) -> begin -> select min(pord_price) into minp from products; -> select max(pord_price) into maxp from products; -> select sum(pord_price) into sump from products; -> end $$
mysql> delimiter ;
注意存储过程的参数允许的数据类型与表中使用的数据类型相同。但是,字符集不是允许的类型,因此上述使用了三个参数而不是通过一个参数返回多个行和列。
调用存储过程时必须指定三个变量名
所有mysql 变量都必须以@ 开始
-- 执行 call proce_produsctstu(@pricelow,@pricehigh,@priceaverage);
没有执行的话直接查找不行,通过传入参数后,在查找这个参数就可以了
上述创建时:
decimal 的作用就是为了控制显示的位数
decimal(8,2) : 总共8位小数位占两位
2、使用 IN 和 OUT
in(传递给存储过程),out(从存储过程传出) 和into(对存储过程传入和传出)类型的参数
-- mysql> delimiter $$ mysql> create procedure proce_order (in onumber int,out ototal decimal(8,2)) -> begin -> select sum(item_price*quantity) from orderitems where order_num = onumber into ototal; -> end $$
onumber 定义为 in,因为订单号被传入存储过程,ototal 定义为out ,因为要从存储过程返回合计。select语句使用这两个参数,where 子句使用onumber 选择正确的行,into 使用ototal 存储计算出来合计。
调用时给这个存储过程,传入两个参数,一个为订单号另一个为计算出来的合计变量名,显示合计使用select 变量名
@total 由存储过程的call语句填写,select 显示它包含的值,
再次调用时如下
二、 执行存储过程 (CALL)
MySQL 称执行存储过程的执行为调用,因此执行存储过程的语句为 CALL
存储过程就像一个存储多条sql 的函数,在查看时要注意函数有()
没有参数时
-- call 创建的存储过程的名字 call proce_product();
有参数时
call 接受存储过程的名字以及传递给他的任意参数
-- call 表名 ( @字段1, @字段2, @字段3); call proce_produsctstu(@pricelow,@pricehigh,@priceaverage);
三、检查存储过程
show create procedure 存储过程名字;
show create procedure proce_product;
注意查询时不要带 ()
要是想看的舒服一些,查看在这个存储过程,时哪个库的由谁创建的、何时创建的等详细信息可以使用
-- show procedure status '存储过程名字'; show procedure status 'proce_product';
注意:show procedure statu 将会把所有的存储过程都列出来,不利于查看,一般和 like 一块使用过滤一下,只查看需要的。
四、删除存储过程 DROP PROCEDURE
存储过程在创建之后,被保存在服务器上已供使用,直至被删除。
-- drop procedure 名字; drop procedure proce_procute;
注意:删除时使用drop ,后面没有(),如果指定的存储过程不存在,就会报错,你要是过程存在想删除(不存在也不出现错误),可以使用 drop procedure if exists
drop procedure if exists
存储过程优缺点
优点:简单,安全,高性能
1、通过把处理封装在容易使用的单元中,简化复杂的操作
2、由于不要反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一存储过程,则所有的代码都相同。这一点的延伸就是防止错误。需要执行的步骤越多出错的可能性就越大,防止错误保证了数据的一致性。
3、简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码,使用它的人甚至都不需要知道这些变化,
4、安全性,通过存储过程限制对基础数据的访问减少了数据讹误(无意识或别的原因导致数据出错)的机会。
5、提到性能,使用存储过程比使用单独的sql 语句要快
6、存在一些只能用在单个请求中的MySQL 元素和特性,存储过程可以使用他们来编写功能更强更灵活的代码。
缺点: 编写比较复杂
1、存储过程的编写比基本sql 语句复杂,编写存储过程,需要更高的技能,更丰富的经验
2、创建存储过程需要有安全访问权限,不过一般可以执行存储过程,因为MySQL将编写存储过程的安全和访问与执行存储过程的安全和访问分开来了,可以保证数据库安全。