以下是关于 MySQL 存储过程的详细教程,包含基本概念、语法、示例及注意事项:
MySQL 存储过程教程
1. 存储过程是什么?
- 定义:存储过程(Stored Procedure)是一组预先编译并存储在数据库中的 SQL 语句集合,可通过名称调用。
- 核心功能:
- 封装复杂业务逻辑。
- 减少网络传输(只需传递过程名和参数)。
- 提高代码复用性和执行效率。
2. 存储过程基本语法
2.1 创建存储过程
DELIMITER //CREATE PROCEDURE 存储过程名([参数列表])
BEGIN-- SQL 逻辑
END //DELIMITER ;
DELIMITER
:修改分隔符(默认;
),避免与 SQL 语句冲突。- 参数格式:
[IN | OUT | INOUT] 参数名 数据类型
IN
:输入参数(默认)。OUT
:输出参数。INOUT
:输入输出参数。
示例:创建简单存储过程
DELIMITER //CREATE PROCEDURE GetUserCount()
BEGINSELECT COUNT(*) FROM users;
END //DELIMITER ;
2.2 调用存储过程
CALL 存储过程名([参数]);
示例:
CALL GetUserCount();
2.3 删除存储过程
DROP PROCEDURE IF EXISTS 存储过程名;
3. 存储过程参数
3.1 输入参数(IN)
DELIMITER //CREATE PROCEDURE GetUserByName(IN userName VARCHAR(50))
BEGINSELECT * FROM users WHERE name = userName;
END //DELIMITER ;
调用:
CALL GetUserByName('Alice');
3.2 输出参数(OUT)
DELIMITER //CREATE PROCEDURE GetMaxAge(OUT maxAge INT)
BEGINSELECT MAX(age) INTO maxAge FROM users;
END //DELIMITER ;
调用:
CALL GetMaxAge(@maxAge);
SELECT @maxAge;
3.3 输入输出参数(INOUT)
DELIMITER //CREATE PROCEDURE DoubleValue(INOUT num INT)
BEGINSET num = num * 2;
END //DELIMITER ;
调用:
SET @value = 10;
CALL DoubleValue(@value);
SELECT @value; -- 输出 20
4. 变量与流程控制
4.1 变量声明
DECLARE 变量名 数据类型 [DEFAULT 默认值];
示例:
CREATE PROCEDURE CalculateTotal()
BEGINDECLARE total INT DEFAULT 0;SET total = (SELECT SUM(price) FROM orders);SELECT total;
END
4.2 条件判断(IF)
IF 条件 THEN-- 逻辑
ELSEIF 条件 THEN-- 逻辑
ELSE-- 逻辑
END IF;
示例:
CREATE PROCEDURE CheckUserStatus(IN userId INT)
BEGINDECLARE status VARCHAR(20);SELECT user_status INTO status FROM users WHERE id = userId;IF status = 'active' THENSELECT '用户活跃';ELSESELECT '用户未活跃';END IF;
END
4.3 循环(WHILE)
WHILE 条件 DO-- 逻辑
END WHILE;
示例:插入 10 条测试数据
CREATE PROCEDURE InsertTestData()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 10 DOINSERT INTO test_table (value) VALUES (i);SET i = i + 1;END WHILE;
END
5. 异常处理
MySQL 存储过程支持简单的错误处理:
DECLARE 处理动作 HANDLER FOR 错误类型
BEGIN-- 错误处理逻辑
END;
示例:
CREATE PROCEDURE SafeInsert()
BEGINDECLARE EXIT HANDLER FOR SQLEXCEPTIONBEGINSELECT '发生错误,操作回滚';ROLLBACK;END;START TRANSACTION;INSERT INTO users (name) VALUES ('Alice');INSERT INTO users (name) VALUES (NULL); -- 触发错误(假设 name 非空)COMMIT;
END
6. 存储过程优缺点
优点
- 性能优化:减少网络传输,预编译执行。
- 代码复用:统一业务逻辑。
- 安全控制:通过权限管理限制数据访问。
缺点
7. 适用场景
- 复杂查询:多表关联计算或聚合。
- 批量操作:数据迁移或定时任务。
- 权限隔离:通过存储过程限制直接表访问。
8. 示例:完整存储过程
示例:用户注册逻辑
DELIMITER //CREATE PROCEDURE RegisterUser(IN p_username VARCHAR(50),IN p_email VARCHAR(100),OUT p_message VARCHAR(100)
BEGINDECLARE userCount INT;-- 检查用户名是否存在SELECT COUNT(*) INTO userCount FROM users WHERE username = p_username;IF userCount > 0 THENSET p_message = '用户名已存在';ELSE-- 插入新用户INSERT INTO users (username, email) VALUES (p_username, p_email);SET p_message = '注册成功';END IF;
END //DELIMITER ;
调用:
CALL RegisterUser('alice', 'alice@example.com', @message);
SELECT @message;
9. 总结
- 核心操作:创建、调用、删除存储过程。
- 参数类型:
IN
、OUT
、INOUT
。 - 流程控制:变量、条件、循环、异常处理。
- 适用场景:优先用于复杂、高频的数据库操作。
通过存储过程,可以将业务逻辑封装在数据库中,但需权衡维护成本和性能收益。