mysql存储过程是预先编译并存储在数据库中的一组sql语句集合,执行存储过程可以快速完成封装好的业务逻辑,避免重复编写复杂sql。不同类型的存储过程执行方式存在一定差异,下面逐一介绍具体的执行方法。

无参数存储过程的执行
无参数的存储过程执行最为简单,直接使用call语句即可完成调用,不需要传递任何参数。首先我们创建一个无参数的存储过程用于查询所有用户信息:
-- 创建无参数存储过程,查询用户表所有数据
DELIMITER //
CREATE PROCEDURE get_all_users()
BEGIN
SELECT user_id, user_name, user_age FROM user_info;
END //
DELIMITER ;
执行这个存储过程的语句如下:
-- 调用无参数存储过程 CALL get_all_users();
执行后会直接返回user_info表中的所有用户记录,不需要额外处理参数。
带输入参数的存储过程执行
如果存储过程定义了输入参数,执行时需要在call语句中按顺序传入对应的参数值。下面创建一个带输入参数的存储过程,根据传入的年龄查询对应年龄段的用户:
-- 创建带输入参数的存储过程,传入年龄查询对应年龄的用户
DELIMITER //
CREATE PROCEDURE get_users_by_age(IN target_age INT)
BEGIN
SELECT user_id, user_name, user_age FROM user_info WHERE user_age = target_age;
END //
DELIMITER ;
执行时传入具体的年龄参数即可:
-- 调用带输入参数的存储过程,查询年龄为25的用户 CALL get_users_by_age(25);
如果需要传入字符串类型的参数,需要用单引号包裹参数值,例如查询指定用户名的用户:
-- 创建查询指定用户名的存储过程
DELIMITER //
CREATE PROCEDURE get_user_by_name(IN target_name VARCHAR(50))
BEGIN
SELECT user_id, user_name, user_age FROM user_info WHERE user_name = target_name;
END //
DELIMITER ;
-- 调用时传入字符串参数
CALL get_user_by_name('张三');
带输出参数的存储过程执行
当存储过程包含输出参数时,执行前需要先定义变量来接收输出结果,再在call语句中传入变量作为参数。下面创建一个带输出参数的存储过程,统计指定年龄的用户数量:
-- 创建带输出参数的存储过程,统计指定年龄的用户数
DELIMITER //
CREATE PROCEDURE count_users_by_age(IN target_age INT, OUT user_count INT)
BEGIN
SELECT COUNT(*) INTO user_count FROM user_info WHERE user_age = target_age;
END //
DELIMITER ;
执行该存储过程的步骤如下:
-- 定义变量接收输出结果 SET @count_result = 0; -- 调用存储过程,传入输入参数和输出变量 CALL count_users_by_age(25, @count_result); -- 查看输出结果 SELECT @count_result AS user_total;
执行后会返回统计得到的用户总数,输出参数的值会保存到对应的会话变量中。
使用EXECUTE语句执行存储过程
除了call语句,还可以使用EXECUTE语句配合PREPARE来动态执行存储过程,这种方式适合需要动态拼接存储过程调用逻辑的场景。示例如下:
-- 定义存储过程调用语句 SET @sql_str = 'CALL get_users_by_age(?)'; -- 预处理语句 PREPARE stmt FROM @sql_str; -- 设置参数值 SET @age_param = 30; -- 执行预处理语句,即执行存储过程 EXECUTE stmt USING @age_param; -- 释放预处理语句 DEALLOCATE PREPARE stmt;
执行存储过程的注意事项
- 执行存储过程需要有对应的权限,如果没有权限会提示权限不足的错误,需要联系数据库管理员授予
EXECUTE权限。 - 存储过程名称区分大小写,执行时需要和创建时的名称完全一致。
- 如果存储过程内部包含事务操作,执行时需要注意事务的提交和回滚逻辑,避免数据不一致。
- 带输出参数的存储过程,传入的变量必须是会话变量(以@开头的变量),不能使用局部变量。
注意:如果存储过程执行过程中报错,可以先使用SHOW PROCEDURE STATUS LIKE '存储过程名称'查看存储过程是否存在,再检查参数传递是否符合定义要求。