1、什么是存储过程
预先编译
的SQL的封装2、存储过程的优缺点
3、和视图、函数的差别
4、存储过程的创建
CREATE PROCEDURE 存储过程名称(IN|OUT|INOUT 参数名 参数类型,...)
[characteristics...]
BEGIN
存储过程体
END
如何理解存储过程名称后面的形参列表
characteristics
表示创建存储过程时指定的特性
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
LANGUAGE SQL
:表明存储过程执行体所用语言是SQL[NOT] DETERMINISTIC
:入参相同时,如果存储过程执行后得到的结果不会发生改变。那么存储过程就是确定性
的,即DETERMINISTIC
。否则就是不确定性NOT DETERMINISTIC
。在没有显式指定DETERMINISTIC的情况下,存储过程默认是不确定性NOT DETERMINISTIC
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
:指明子程序使用SQL的限制
SQL SECURITY { DEFINER | INVOKER }
:当前存储过程哪些用户可以执行。如果是DEFINER,就是只有创建者才能执行。INVOKER就是拥有访问权限的用户就可以执行COMMENT string
:注释信息,用于描述存储过程5、使用DELIMITER
设置新的结束标记
如果我们不将MySQL默认的语句结束符由;
改为自定义的标记
那么下面的存储过程执行到SELECT语句结束后,就不会继续往下走了,这显然是错误的
所以我们在这里将$
或者//
定义为语句执行结束的标记
并且在执行完存储过程之后,再将结束标记改回;
DELIMITER $
CREATE PROCEDURE SELECT_all_emp()
BEGIN
SELECT * FROM t_emp;
END $
DELIMITER ;
6、存储过程的调用,使用关键字CALL
1)无参数类型的调用
DELIMITER $
CREATE PROCEDURE select_AVG_salary()
BEGIN
SELECT AVG(salary) FROM t_emp;
END $
DELIMITER $
CALL select_AVG_salary();
2)带OUT类型
的调用,注意输出变量的类型需要和表中字段的类型相同
假设我们要查询当前员工表中最低的工资,并且把将最低薪资通过参数ms输出
DELIMITER $
CREATE PROCEDURE show_min_salary(OUT ms DOUBLE(8,2))
BEGIN
SELECT MIN(salary) INTO ms #使用INTO将最低薪资写入到ms变量
FROM t_emp;
END $
DELIMITER ;
#调用,使用@自定义ms变量
CALLL show_min_salary(@ms);
#查看此变量值
SELECT @ms;
3)带IN类型
的调用,注意输入变量的类型需要和表中字段的类型相同
假设我们要查询当前员工表中某个员工的薪资,并使用IN参数empname输入员工姓名
DELIMITER $
CREATE PROCEDURE show_someony_salary(IN empname VARCHAR(20))
BEGIN
SELECT salary
FROM t_emp WHERE last_name = empname;
END $
DELIMITER ;
# 调用方式一:直接传
CALL show_someony_salary('Decade');
# 调用方式二:定义变量,然后调用的时候传入变量
SET @name = 'Decade';
CALL show_someony_salary(@name);
4)带IN和OUT类型的调用
假设我们要查询当前员工表中某个员工的薪资,并使用IN参数empname输入员工姓名,使用OUT参数empsalary输出薪资
DELIMITER $
CREATE PROCEDURE show_someone_salary2(IN empname VARCHAR(20),OUT empsalary DOUBLE(10,2))
BEGIN
SELECT salary FROM t_emp INTO empsalary
WHERE last_name = empname;
END $
DELIMITER ;
# 调用
CALL show_someone_salary2('Decade', @empsalary);
# 或者
SET @empname = 'Decade';
CALL show_someone_salary2(@empname, @empsalary);
#查看此变量值
SELECT @empsalary;
5)带INOUT类型的调用
DELIMITER $
CREATE PROCEDURE show_mgr_name(INOUT empname VARCHAR(20))
BEGIN
SELECT last_name INTO empname
FROM t_emp
where emp_id = (
SELECT manager_id FROM t_emp
where last_name = empname
);
END $
DELIMITER ;
# 调用
SET @empname = 'Decade';
CALL show_mgr_name(@empname);
# 查看输出参数
SELECT @empname;
前面已经学习过一些系统提供的函数,包括单行函数和聚合函数
1、存储函数的创建
CREATE FUNCTION 存储函数名称(参数名 参数类型,...)
RETURNS 返回值类型
[characteristics...]
BEGIN
函数体 #函数体中肯定有 return语句
END
2、使用SELECT
进行存储函数的调用
SELECT 函数名(参数列表);
3、如果创建存储函数时,没有指明characteristics
,可能会出现you *might* want to use the less safe log_bin_trust_function_creators variable
这个报错,我们推荐以下两种方式进行解决
[NOT] DETERMINISTIC
和{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
DELIMITER $
CREATE FUNCTION show_email_by_name()
RETURNS VARCHAR(20)
DETERMINISTIC
CONTAINS SQL
READS SQL DATA
BEGIN
RETURN (SELECT eamil FROM t_emp WHERE last_name = 'Decade');
END $
DELIMITER ;
SET GLOBAL log_bin_trust_function_creators = 1;
4、存储函数也要用到DELIMITER
,下面我们就了解一下存储函数的几种使用方式
1)不传参数
DELIMITER $
CREATE FUNCTION show_email_by_name()
RETURNS VARCHAR(20)
DETERMINISTIC
CONTAINS SQL
READS SQL DATA
BEGIN
RETURN (SELECT eamil FROM t_emp WHERE last_name = 'Decade');
END $
DELIMITER ;
# 调用存储函数
SELECT show_email_by_name();
2)传入参数
SET GLOBAL log_bin_trust_function_creators = 1;
DELIMITER $
CREATE FUNCTION show_email_by_name(empname VARCHAR(15))
RETURNS VARCHAR(20)
BEGIN
RETURN (SELECT eamil FROM t_emp WHERE last_name = empname);
END $
DELIMITER ;
# 调用存储函数
SELECT show_email_by_name('Decade');
# 或者
SET @empname = 'Decade';
SELECT show_email_by_name(@empname);
5、存储函数和存储过程的比较
FUNCTION
,存储过程是PROCEDURE
只有一个返回值
,存储过程可以输出0个或者多个参数
SELECT
,存储过程用CALL
用于查询
,存储过程用于更新数据
1、存储过程、函数的查看
1)查看存储过程和函数的创建信息
SHOW CREATE PROCEDURE 存储过程名称;
SHOW CREATE FUNCTION 存储函数名称;
2)查看存储过程和函数的状态信息
SHOW PROCEDURE/FUNCTION STATUS; #会展示所有存储过程/函数
SHOW PROCEDURE STATUS LIKE '%模糊查询%';
SHOW FUNCTION STATUS LIKE '%模糊查询%';
3)从information_schema.Routines查看存储过程和函数的状态信息
SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME = '存储过程名称' AND ROUTINE_TYPE = PROCEDURE;
SELECT * FROM information_schema.Routines
WHERE ROUTINE_NAME = '存储函数名称' AND ROUTINE_TYPE = FUNCTION;
2、存储过程、函数的修改
存储过程、函数的修改不能修改过程体/函数体,只能通过ALTER对特性characteristics进行修改
ALTER PROCEDURE/FUNCTION 存储过程或者函数的名称 [characteristics...];
注意,只能修改以下特性
COMMENT 'string'
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
假设我们要修改上面的存储过程show_someone_salary2,修改执行权限和备注
ALTER PROCEDURE show_someone_salary2
SQL SECURITY INVOKER
COMMENT '测试修改';
3、存储过程、函数的删除
DROP PROCEDURE/FUNCTION IF EXISTS 存储过程/函数名称;
如有错误,欢迎指正!!!