共计 1955 个字符,预计需要花费 5 分钟才能阅读完成。
存储过程是存储在数据库服务器中的一组 sql 语句,通过在查询中调用一个指定的名称来执行这些 sql 语句命令。
简介
SQL 语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
存储过程是可编程的函数,在数据库中创建并保存,可以由 SQL 语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。
MySQL 存储过程的优点
通常存储过程有助于提高应用程序的性能。当创建,存储过程被编译之后,就存储在数据库中。但是,MySQL 实现的存储过程略有不同。MySQL 存储过程按需编译。在编译存储过程之后,MySQL 将其放入缓存中。MySQL 为每个连接维护自己的存储过程高速缓存。如果应用程序在单个连接中多次使用存储过程,则使用编译版本,否则存储过程的工作方式类似于查询。
存储过程有助于减少应用程序和数据库服务器之间的流量,因为应用程序不必发送多个冗长的 SQL 语句,而只能发送存储过程的名称和参数。
存储的程序对任何应用程序都是可重用的和透明的。存储过程将数据库接口暴露给所有应用程序,以便开发人员不必开发存储过程中已支持的功能。
存储的程序是安全的。数据库管理员可以向访问数据库中存储过程的应用程序授予适当的权限,而不向基础数据库表提供任何权限。
MySQL 存储过程的缺点
如果使用大量存储过程,那么使用这些存储过程的每个连接的内存使用量将会大大增加。此外,如果您在存储过程中过度使用大量逻辑操作,则 CPU 使用率也会增加,因为数据库服务器的设计不当于逻辑运算。
存储过程的构造使得开发具有复杂业务逻辑的存储过程变得更加困难。
很难调试存储过程。只有少数数据库管理系统允许您调试存储过程。不幸的是,MySQL 不提供调试存储过程的功能。
开发和维护存储过程并不容易。开发和维护存储过程通常需要一个不是所有应用程序开发人员拥有的专业技能。这可能会导致应用程序开发和维护阶段的问题。
过程体
过程体的开始与结束使用 BEGIN 与 END 进行标识。
存储过程分为有参和无参
无参存储过程:
DELIMITER ;;
CREATE PROCEDURE `select_students_count`()
BEGIN
SELECT count(id) from students;
END;;
DELIMITER ;
call select_students_count();
有参存储过程:
MySQL 支持 IN(传递给存储过程),OUT(从存储过程传出) 和 INOUT(对存储过程传入和传出) 类型的参数。存储过程的代码位于 BEGIN 和 END 语句内,如前所见,它们是一系列 SELECT 语句,用来检索值,然后保存到相应的变量 (通过指定 INTO 关键字)
存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用 ”,” 分割开。MySQL 存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT
IN:仅带入参的存储过程
参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
DELIMITER //
CREATE PROCEDURE in_param(IN p_in int)
BEGIN
SELECT p_in;
SET p_in=2;
SELECT p_in;
END//
DELIMITER ;
# 调用
SET @p_in=1;
CALL in_param(@p_in);
SELECT @p_in;
结果:
OUT: 仅带出参的存储过程
该值可在存储过程内部被改变,并可返回
# 存储过程 OUT 参数
DELIMITER //
CREATE PROCEDURE out_param(OUT p_out int)
BEGIN
SELECT p_out;
SET p_out=2;
SELECT p_out;
END//
DELIMITER ;
# 调用
SET @p_out=1;
CALL out_param(@p_out);
SELECT @p_out;
结果:
INOUT: 带入参和出参的存储过程
调用时指定,并且可被改变和返回
# 存储过程 INOUT 参数
DELIMITER //
CREATE PROCEDURE inout_param(INOUT p_inout int)
BEGIN
SELECT p_inout;
SET p_inout=2;
SELECT p_inout;
END//
DELIMITER ;
# 调用
SET @p_inout=1;
CALL inout_param(@p_inout) ;
SELECT @p_inout;
结果: