MySQL必知必会——第23章 使用存储过程 读书笔记

本章介绍了什么是存储过程, 为什么要使用存储过程,如何使用存储过程,介绍了创建和使用存储过程的基本语法。

1 什么是存储过程?
存储过程适合MySQL5及以后的版本。
目前为止,使用的大多数SQL语句都是针对一个或多个表的单条语句。并非所有操作都这么简单,经常会有一个完整的操作需要多条语句才能完成。**需要执行的具体语句及其次序也不是固定的。**可以创建存储过程(为以后的使用而保存一条或多条MySQL语句的集合),可以将其视为批文件,但存储过程的作用不仅限于批处理
2 为什么要使用存储过程?
①通过把处理封装在容易使用的单元中,简化复杂的操作。
②防止错误:需要执行的步骤越多,出错的可能性越大
③简化对变动的管理:只需要修改存储过程的代码
④安全性:通过存储过程限制对基础数据的访问减少了数据讹误。
⑤提高性能:使用存储过程比使用单独的SQL语句要快。
总之,存储过程有三个主要优点:简单、安全、高性能。
存储过程的缺陷:
①存储过程的编写需要更高的技能,更丰富的经验;
②可能没有创建存储过程的安全访问权限,许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程。
尽管存在上述缺陷,存储过程还是非常有用的,应尽可能使用存储过程。
不能编写存储过程, 依然可以使用。 MySQL将编写存储过程的安全和访问区分开来。即使你不能编写自己的存储过程, 也可以执行别的存储过程。
3 使用存储过程
使用存储过程需要知道如何执行存储过程。执行存储过程比定义存储过程更常用到。
(1)执行存储过程
MySQL执行存储过程的语句是CALL。CALL接受存储过程名称及传递给它的任意参数。

call productpricing(@pricelow,
                              @pricehigh.
                              @priceaverage);

上述语句执行名为productpricing存储过程,计算并返回产品的最低、最高、平均价格。
存储过程可以显示结果,也可以不显示结果。
(2)创建存储过程
下面是一个返回产品平均价格的存储过程:

create procedure productpricing()
begin
  select avg(prod_price) as priceaverage
  from products
end;

此存储过程名为productpricing,用create procedure productpricing()语句创建。如果存储过程接受参数,将参数在()中列举出来。如果没有参数,存储过程名后面仍然要跟()。begin和end语句来限定存储过程体,上述例子过程体本身只是一个简单的select语句。
上述代码只是创建存储过程,并没有调用或执行它,所以不会返回数据。
使用上述创建的存储过程:

call productpricing();

执行刚创建的存储过程并显示结果。
因为存储过程本身也是一种函数,所以即使没有参数传递,存储过程名后面也需要加()
(3)删除存储过程
删除上述创建的存储过程:

drop procedure productpricing;

上述语句删除创建的存储过程, 注意没有使用后面的()。
如果指定的存储过程不存在,则drop procedure会产生一个错误。
当过程存在想删除它时(如果过程不存在也不产生错误)可使用drop procedure if exists
(4)使用参数
上述存储过程简单显示select语句的结果。一般存储过程并不显示结果,而是把结果返回给你指定的变量。
以下是productpricing的修改版本(如果不先删除此存储过程, 则不能再次创建它):

create procedure productpricing(
  OUT pl decimal(8,2),
  OUT ph decimal(8,2),
  OUT pa decimal(8,2)
  )
begin
   select min(prod_price)
   into pl
   from products;
   select max(prod_price)
   into ph
   from products;
   select avg(prod_price)
   into pa
   from products;
end;

补充:decimal是十进制,第一个参数表示最大数字位数,第二个参数表示小数点后位数。
此存储过程有三个参数:pl存储产品最低价格,ph存储最高价格,pa存储平均价格。
关键字OUT指出相应的参数用来从存储过程传出一个值(返回给调用者)。MySQL支持IN(传递给存储过程),OUT(从存储过程传出)和INOUT(对存储过程传入和传出)类型的参数。
存储的代码位于begin和end之间。存储过程是一系列select语句,用来检索值,然后保存到相应的变量(通过INTO关键字)。
为调用此修改过的存储过程,必须指定3个变量名:

call productpricing(@pricelow,
                              @pricehigh,
                              @priceaverage);

由于此存储过程传递出3个参数,所以执行该存储过程也必须指定3个变量。
在调用这个存储过程时,不显示任何数据,而是返回以后可以显示的变量。

select @priceaverage,@pricelow,@pricehigh;

下面是另一个例子,这次使用了IN和OUT参数。存储过程名为ordertotal,其功能是接受订单号并返回该订单的合计:

create procedure ordertotal(
  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语句使用这两个参数,使用onumber选择正确的行,into使用ototal存储计算出来的合计。
调用上述存储过程:

call ordertotal(20005,@total);

为了显示合计:

select @total;

4 建立智能存储过程
迄今为止使用所有的存储过程基本上都是封装MySQL简单的select语句,虽然它们都是有效的存储过程例子,但它们所完成的工作你直接用这些被封装的语句就都能完成。只有在存储过程内包含业务规则和智能处理时,它们的威力才显现出来。
考虑这个场景,你需要获得与以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客。那么你需要做以下几件事情:
①获得合计;
②把营业税有条件地添加到合计;
③返回合计。
存储过程的完整工作过程如下:

--Name:ordertotal
--Parameters:onumber=order number
--                    taxable=0 if not taxable,1 if taxable
--                    ototal=order total variable
create produceure ordertotal(
in onumber int,
in taxable boolean,
out ototal decimal(8,2)
)comment 'obtain order total,optionally adding tax'
begin
  --declare variable for total
  declare total decimal(8,2);
  --declare tax percentage
  declare taxrate int default 6;
  --get the order total
  select sum(item_price*quantity)
  from orderitems
  where order_num=onumber
  into total;
  --is this taxable?
  if taxable then
     --yes,so add taxrate to the total
     select total+(total/100*taxrate) into total;
 end if;
 --and finally,save to out variable
 select total into ototal;
end;                    

前面放置–增加了注释,在存储过程复杂性增加时,这样做特别重要。
添加了另一个参数taxable,它是一个布尔值。
comment值不是必须的,如果给出,将在show procedure status的结果中显示。
在存储过程体中,用declare语句定义了两个局部变量, declare要求指定变量名和数据类型,也支持可选的默认值。
select语句改变,因此其结果存储到局部变量total而不是ototal。
if语句检查taxable语句是否为真,如果为真,则将另一select语句增加营业税到局部变量total。最后,用另一select语句将total保存到ototal。
这是一个更高级,功能更强的存储过程。

call ordertotal(20005,0,@total);
select @total;

这个例子给出了MySQL的IF语句的基本用法。IF语句还支持ELSEIF和ELSE子句。
5 检查存储过程
为了显示用来创建一个存储过程的create语句,使用show create procedure语句:

show create procedure ordertotal;

可以包括何时,由谁创建等详细信息的存储过程列表,使用show procedure status。
show procedure status 列出所有存储过程。为限制其输出,可使用like指定一个过滤模式,例如show procedure status like ‘ordertotal’;

小结:
本章介绍了什么是存储过程,为什么要使用存储过程。介绍了存储过程的执行和创建的语法以及使用存储过程的一些方法。

发布了90 篇原创文章 · 获赞 8 · 访问量 8228

猜你喜欢

转载自blog.csdn.net/weixin_43854189/article/details/104023803