存储函数 | 存储过程
一、 异同点
MySQL的存储过程和函数都是一系列SQL语句的集合,调用时一次性执行这些SQL语句。但是它们有一些不同之处:
- 存储过程没有返回值,而函数有一个返回值.
- 存储过程可以在单个存储过程中执行一系列SQL语句,而自定义函数有诸多限制.
- 存储过程可以返回多个值,而函数只能有一个返回值.
- 存储过程实现较为复杂,自定义函数针对性强
- 存储函数只能有输入参数,而且不能带in, 而存储过程可以有多个in,out,inout参数。
- 存储过程可以调用存储函数、但函数不能调用存储过程。
名称 | 创建 | 调用 | 返回 | 应用 |
---|---|---|---|---|
存储函数 | create function | select | 只能是一个 | 计算字段值、处理数据、触发器(一般用于查询结果为一个值并有返回结果的) |
存储过程 | create procedure | call | 可以是多个也可以为空 | 1.复杂的业务逻辑,例如银行转账、订单处理;2.批量操作,例如批量插入、更新、删除数据;3.安全性控制,例如限制用户访问某些数据或执行某些操作(一般用于更新) |
二、 存储函数
语法
创建
示例:
delimiter $$
CREATE FUNCTION avg_salary(p_name VARCHAR(50))
RETURNS FLOAT
BEGIN
DECLARE avg_age FLOAT;
DECLARE total_salary FLOAT;
DECLARE num_employees INT;
DECLARE cur CURSOR FOR SELECT age FROM employees WHERE name = p_name;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET num_employees = 0;
OPEN cur;
FETCH cur INTO avg_age;
CLOSE cur;
SELECT AVG(salary) INTO total_salary FROM employees WHERE name = p_name;
RETURN total_salary / avg_age;
end $$
delimiter ;
上述示例存储函数接受一个参数p_name,表示要查询的员工姓名。它首先声明了三个变量:avg_age、total_salary和num_employees。然后,它使用游标遍历employees表中与指定名称匹配的所有行,并计算这些行中的平均年龄。最后,它返回总薪水除以平均年龄的结果。
> delimiter 是分隔符的意思 DELIMITER xx
> -- 示例:
> DELIMITER $$ -- 指定 $$ 为分隔符
> DELIMITER // -- 指定 // 为分隔符
> DELIMITER ; -- 指定 ; 为分隔符
调用
调用函数名。
查看
修改
删除
删除函数的语法只需写上函数名即可,函数的参数可以不用写出来。
三、 存储过程
语法
创建
存储过程的创建步骤需要以下几步:
- 声明存储过程的名称和参数列表。
- 编写存储过程的主体部分,包括一系列SQL语句。
- 结束存储过程的主体部分,并指定返回值类型。
- 调用存储过程,传递参数并获取返回结果。
示例:
CREATE PROCEDURE GetEmployeeDetails(IN employeeID INT)
BEGIN
SELECT * FROM employees WHERE ID = employeeID;
END;
上述示例为一个名为GetEmployeeDetails的存储过程,接受一个整型参数employeeID,用于查询员工详情。在存储过程中,使用SELECT语句从employees表中查询employeeID对应的记录。最后,通过END关键字结束存储过程的主体部分。
调用
使用 call 关键字来调用存储过程
查看
修改
删除
其中characteristic的取值为:
值 | 说明 |
---|---|
language sql | 说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL |
[not] deterministic | 指明存储过程执行的结果是否确定。DETERMINISTIC 表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。 |
{contains sql / no sql / reads sql data / modifies sql data} | 指明子程序使用SQL语句的限制。CONTAINS SQL表明子程序包含SQL语句,但是不包含读写数据的语句;NO SQL表明子程序不包含SQL语句;READS SQL DATA:说明子程序包含读数据的语句;MODIFIES SQL DATA表明子程序包含写数据的语句。默认情况下,系统会指定为CONTAINS SQL。 |
sql_security{definer/invoker} | 指明谁有权限来执行。DEFINER 表示只有定义者才能执行;INVOKER 表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER。 |
comment ‘string’ | 注释信息,可以用来描述存储过程或函数 |