MySQL存储过程和函数使用总结
作者:BuleSky 发布时间:[ 2016/11/17 11:20:09 ] 推荐标签:MySQL 数据库
什么是存储过程和函数
存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。
存储过程和函数的区别在于函数必须有返回值,而存储过程没有,存储过程的参数可以使用IN、OUT、INOUT类型,而函数的参数只能是IN类型的。如果有函数从其他类型的数据库迁移到MySQL,那么可能因此需要将函数改造成存储过程。
为什么使用存储过程和函数
在完成一个逻辑操作时,有时会执行多条SQL语句,此外这些SQL语句的执行顺序也不是固定的,它会根据条件的变化而变化。在执行过程中,这些需要根据前面SQL语句的执行结果有选择的执行后面的SQL语句。为了解决该问题,MySQL软件提供了数据库对象存储过程和函数。
存储过程和函数的优点
<1> 存储过程和函数允许标准组件式编程提高了SQL语句的重用性、共享性和可移植性。
<2> 存储过程和函数能够实现较快的执行速度,减少网络流量。
<3> 存储过程和函数可以被作为一种安全机制来利用
存储过程和函数的缺点
<1> 存储过程和函数的编写比单句SQL语句复杂,需要用户具有更高的技能和更丰富的经验。
<2> 在编写存储过程和函数时,需要创建这些数据库对象的权限。
存储过程和函数的相关操作 创建、修改存储过程或者函数
创建、修改存储过程或者函数的语法如下:
CREATE
[DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE
[DEFINER = { user | CURRENT_USER }]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
proc_parameter:[IN|OUT|INOUT]param_name type
func_parameter:param_name type
type:Any valid MySQL data type(支持MySQL中的所有数据类型)
调用语法:
CALL sp_name([parameter[,…]])
MySQL的存储过程或者函数中允许包含DDL语句,也允许在存储过程中执行提交(Commit,即确认之前的修改)或者回滚(Rollback,即放弃之前的修改),但是存储过程或者函数中不允许执行LOAD DATA INFILE语句。此外,存储过程和函数中可以调用其他的过程或者函数。
示例1:在员工姓名模糊查询时,可能需要匹配不同的查询条件,有时需要查询名字中带有“李”的,有时需要查询以“梅”结尾的,此时可以创建一个存储过程根据不同的传入参数,返回不同的结果:
mysql>DELIMITER $$
->CREATE PROCEDURE emp_in_hire(IN emp_name_reg VARCHAR(10),OUT emp_count INT)
->READS SQL DATA
->BEGIN
->SELECT id FROM emp WHERE ename REGEXP emp_name_reg;
->SELECT FOUND_ROWS() INTO emp_count;
->END $$
mysql>DELIMITER ;
mysql>CALL emp_in_hire ('^李',@emp_count);
+----+
| id |
+----+
| 2 |
+----+
1 row in set (0.00 sec)
Query OK, 1 row affected (0.00 sec)
mysql>SELECT @emp_count;
+------------+
| @emp_count |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
示例中可以根据传入的第一个参数指定员工姓名匹配的正则表达式,第二个参数用来接收存储过程的输出参数。达到了一段SQL多次使用的目的,不用在业务逻辑中多次编写SQL语句。
但是在进行上面的例子中可以这样尝试一下,将IN类型的参数emp_name_reg 的类型定义为VARCHAR,也是不指定长度,这样的情况在MySQL5.6版本中会创建失败。但是INT类型的参数不需要指定长度。使用VARCHAR指定传入参数的类型时,没有指定长度,创建时总是提示检查语法。
还有需要注意的是,在参数命名时,存储过程的参数名不要跟字段名一样。将会导致参数的值将不会是传入的值,而是变成每条记录中对应字段的值。这样的后果,是非常严重的。比如执行单个删除操作:
DELIMITER $$
CREATE PROCEDURE delete_one_emp(IN ename VARCHAR(10))
BEGIN
DELETE FROM EMP WHERE ename=ename;
END $$
调用上面的存储过程时,传入’李四’,意图是删除姓名为李四的员工信息,但是执行后发现,整张表的数据被清空了,即便是字段名是大写,参数名是小写也会如此,因为MySQL对大小写不敏感。
示例2:创建函数将指定员工的工资增加指定的值,然后返回工资的大值。
DELIMITER $$
CREATE FUNCTION add_salary(raise_count int(5),e_name_reg varchar(10))
RETURNS int(10)
COMMENT ’涨工资’
BEGIN
UPDATE EMP SET SALARY = SALARY+raise_count WHERE ENAME RLIKE e_name_reg;
RETURN (SELECT max(SALARY) FROM EMP);
END $$
DELIMITER;
SELECT add_salary(5000,'^李');
存储过程和函数的CREATE语法不支持使用CREATEOR REPLACE对存储过程和函数进行修改,如果需要对已有的存储过程或者函数进行修改需要执行ALTER语法。
在存储过程和函数的创建语法中有characteristic特性,下面对该特性值的部分进行说明。
<1>LANGUAGE SQL:说明下面过程的BODY是使用SQL语言编写,这条是系统默认的,为以后除SQL外的其他语言支持的存储过程而准备。
<2>[NOT]DETERMINISTIC:DETERMINISTIC确定的,即每次输入一样输出也一样的程序,NOT DETERMINISTIC非确定的,默认的是非确定的。当前,这个特征值还没有被优化程序使用。
<3>{CONTAINS SQL|NOT SQL|READS SQL DATA|MODIFIES SQL DATA}:这些特征值提供子程序使用数据的内在信息,这些特征值目前只是提供给服务器,并没有根据这些特征值来约束过程实际使用数据的情况。CATAINS SQL表示子程序不包含读或写的语句。NOT SQL表示子程序不包含SQL语句。READS SQL DATA表示子程序包含读数据的语句,但是不包含写数据的语句。MODIFIES SQL DATA表示子程序包含写数据的语句。如果这些特征值没有明确给定,默认使用的值CONTAINS SQL。
<4>SQL SECURITY{DEFINER|INVOKER}:可以用来指定子程序该用创建子程序者的许可来执行,还是使用调用者的许可来执行。默认是DEFINER。
<5>COMMENT :存储过程或者函数的注释信息。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11