1. 存储过程概述
存储过程是一种在数据库中存储复杂程序,以便外部程序调用的数据库对象。
存储过程经编译创建并保存在数据库中,用户可通过指定存储过程的名字和给定参数来调用执行。存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用。
作个形象的比喻,存储过程也可以看作是一个"加工厂",它接收"原料"(in参数)然后将这些原料加工处理成"产品"(out/inout参数),再把"产品"交付给"调用者"。
存储过程的优点
减少网络流量的使用
将重复性很高的一系列操作,封装到一个存储过程中,简化了SQL的调用
批量处理: 通过循环减少流量,也就是“跑批”
统一接口,确保数据安全。
存储过程的缺点
存储过程往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
存储过程的性能调校与撰写受限于具体的数据库系统。
2. 创建存储过程 create procedure
创建存储过程的语法如下:
create [definer = {user|current_user}] procedure [过程名] ( [参数1],[参数2],...,[参数n] ) [[特征1],[特征2],...,[特征n]] [SQL代码]; -- definer 用于指定存储过程由哪个用户定义,默认是当前用户,注意不是指定存储过程的使用权限 -- [过程名] 该过程名用于指定存储过程,分别用户调用 -- [参数] 参数的形式为:[in|out|inout] [参数名] [参数类型],例如:in pcd_id int、inout pcd_username varchar(3) -- -- -- in 表示该参数为输入参数,即调用时传入 -- -- -- out 表示该参数为输出参数,即存储过程的返回值 -- -- -- inout 表示该参数即可输入也可输出 -- -- -- 参数类型 可以是 int或者varchar() -- [特征] 特征是存储过程的属性,它包括了如下几个可选特征 -- -- -- comment '' 注释信息,例如:commet '这是一个存储过程' -- -- -- language sql 指定存储过程使用的语言为sql -- -- -- [not] deterministic 是否指定一个输入仅对应一个输出(映射),包含下面2个可选参数 -- -- -- -- -- not deterministic(默认),表示不指定映射关系; -- -- -- -- -- deterministic,表示指定映射关系 -- -- -- [contains sql | no sql | reads sql data | modifies sql data] 明确子程序对数据的操作,包含下面4个可选参数 -- -- -- -- -- contains sql(默认),表示子程序不包含读或者写数据的语句 -- -- -- -- -- no sql,表示子程序不包含sql -- -- -- -- -- reads sql data,表示子程序包含读数据的语句,但是不包含写数据的语句 -- -- -- -- -- modifies sql data,表示子程序包含写数据的语句 -- -- -- sql security [definer|invoker] 指定调用权限,包含下面两个可选参数 -- -- -- -- -- sql security definer(默认),使用创建者权限调用存储过程,不受限制 -- -- -- -- -- sql security invoker,使用调用者权限调用存储过程,只有被赋予权限的调用者才能调用
例如:
-- 将tab_sale表中sale_name字段值等于传入参数的记录删除 create procedure delete_sale(in pcd_sale_name varchar(3)) begin delete from tab_table where tab_table.sale_name= pcd_sale_name ; end
2.1. 参数 in、out、inout
下面三段代码是对存储过程的参数in、out和inout的代码说明:
-- 创建一个存储过程,参数为in create procedure test(in i int) begin select i; -- 返回结果i,i=1 set i=2; select i; -- 返回结果i,i=2 end -- 调用存储过程test,并传入一个参数i=1 set @i = 1; -- 定义全局变量i call test(@i); select @i; -- 返回结果i,i=1 -- 由以上代码可知当存储过程的参数为in时,会传入变量的值,并且存储过程内部的赋值不会影响到外部传入的变量
-- 创建一个存储过程,参数为out create procedure test(out i int) begin select i; -- 返回结果i,i=Null set i=2; select i; -- 返回结果i,i=2 end -- 调用存储过程test,并传入一个参数i=1 set @i=1; -- 定义全局变量i call test(@i); select @i; -- 返回结果i,i=2 -- 由以上代码可知当存储过程的参数为out时,变量的值不会被传入,并且存储过程内部的赋值运算可以影响到外部传入的变量
-- 创建一个存储过程,参数为inout create procedure test(inout i int) begin select i; -- 返回结果i,i=1 set i=2; select i; -- 返回结果i,i=2 end -- 调用存储过程test,并传入一个参数i=1 set @i=1; -- 定义全局变量i call test6(@i); select @i; -- 返回结果i,i=2 -- 由以上代码可知当存储过程的参数为out时,会传入变量的值,并且存储过程内部的赋值运算可以影响到外部传入的变量
3. 调用存储过程 call
存储过程的调用使用call关键字
例如:
-- 将tab_sale表中sale_name字段值等于'辣条'的记录删除 create procedure delete_sale(in pcd_sale_name varchar(3)) delete from tab_table where tab_table.sale_name= pcd_sale_name ; -- 调用存储过程delete_sale call delete_sale('辣条');
4. 查看存储过程
4.1. 查看存储过程的状态
语法如下:
show procedure status like '[状态名]';
[状态名]可以查看博客:show status 查看各种状态
例如:
--查看查询时间超过long_query_time秒的查询的个数。 show procedure status like 'slow_queries';
4.2. 查看存储过程的定义
语法如下:
show create procedure '[过程名]'
例如:
-- 查看存储过程delete_sale的定义 show create procedure delete_sale
结果如下:
4.2. 从information_schema.Routines表查看存储过程的信息 mysql
MySQL数据库的所有存储过程的信息都保存在information_ schema数据库中的routines表中,因此可以使用select语句查询存储过程的相关信息。
语法为:
select * from information_schema.ROUTINES where routine_name='[过程名]'
例如下面的SQL语句是查看存储过程delete_sale相关信息的语句。
select * from information_schema.ROUTINES where routine_name='delete_sale'
执行结果如下:
5. 修改存储过程 alter procedure
修改存储过程的特性可以使用alter procedure关键字,语法如下:
alter procedure [存储过程名] [特性]
例如:
-- 修改存储过程delete_sale,使它可以写数据(modifies sql data) alter procedure delete_sale modifies sql data;
6. 删除存储过程 drop procedure
语法:
drop procedure [if exists] [存储过程名]
例如:
-- 如果存储过程delete_sale存在,则删除它 drop procedure if exists delete_sale;