内容简介:本文主要介绍MySQL存储过程参数与返回值的相关知识,包括参数类型、使用方法和最佳实践等内容。风哥教程参考MySQL官方文档MySQL Stored Procedures、MySQL Server Administration。 01 更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 流程控制结构
MySQL存储过程支持多种流程控制结构,包括条件判断、循环、跳转等,用于实现复杂的业务逻辑。 02 学习交流加群风哥微信: itpux-com
1. 条件判断
– IF语句
– CASE语句
2. 循环结构
– WHILE循环
– REPEAT循环
– LOOP循环
3. 跳转语句
– LEAVE语句
– ITERATE语句
– RETURN语句
Part02-生产环境规划与建议
2.1 IF语句使用
IF语句用于根据条件执行不同的代码块。 03 学习交流加群风哥QQ113257174
1. 简单IF语句
DELIMITER //
CREATE PROCEDURE check_user_status(IN user_id INT)
BEGIN
DECLARE user_status INT;
SELECT status INTO user_status
FROM users
WHERE id = user_id;
IF user_status = 1 THEN
SELECT ‘用户状态正常’ AS result;
ELSE
SELECT ‘用户状态异常’ AS result;
END IF;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 调用存储过程
CALL check_user_status(1);
输出示例:
+—————-+
| result |
+—————-+
| 用户状态正常 |
+—————-+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
3. IF-ELSEIF-ELSE语句
DELIMITER //
CREATE PROCEDURE get_user_level(IN user_id INT)
BEGIN
DECLARE total_orders INT;
SELECT COUNT(*) INTO total_orders
FROM orders
WHERE user_id = user_id;
IF total_orders < 10 THEN
SELECT ‘普通用户’ AS user_level;
ELSEIF total_orders < 50 THEN
SELECT ‘银牌用户’ AS user_level;
ELSEIF total_orders < 100 THEN
SELECT ‘金牌用户’ AS user_level;
ELSE
SELECT ‘钻石用户’ AS user_level;
END IF;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 调用存储过程
CALL get_user_level(1);
输出示例:
+————–+
| user_level |
+————–+
| 金牌用户 |
+————–+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Part03-生产环境项目实施方案
3.1 CASE语句使用
CASE语句提供了更简洁的多条件判断方式。 04 风哥提示:
1. 简单CASE语句
DELIMITER //
CREATE PROCEDURE get_order_status_text(IN status_code INT)
BEGIN
CASE status_code
WHEN 0 THEN SELECT ‘待支付’ AS status_text;
WHEN 1 THEN SELECT ‘已支付’ AS status_text;
WHEN 2 THEN SELECT ‘已发货’ AS status_text;
WHEN 3 THEN SELECT ‘已完成’ AS status_text;
WHEN 4 THEN SELECT ‘已取消’ AS status_text;
ELSE SELECT ‘未知状态’ AS status_text;
END CASE;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 调用存储过程
CALL get_order_status_text(2);
输出示例:
+————–+
| status_text |
+————–+
| 已发货 |
+————–+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
3. 搜索CASE语句
DELIMITER //
CREATE PROCEDURE calculate_discount_rate(IN total_amount DECIMAL(10,2))
BEGIN
DECLARE discount_rate DECIMAL(5,2);
CASE
WHEN total_amount < 100 THEN SET discount_rate = 0;
WHEN total_amount < 500 THEN SET discount_rate = 5;
WHEN total_amount < 1000 THEN SET discount_rate = 10;
WHEN total_amount < 5000 THEN SET discount_rate = 15;
ELSE SET discount_rate = 20;
END CASE;
SELECT total_amount, discount_rate,
total_amount * discount_rate / 100 AS discount_amount,
total_amount * (100 – discount_rate) / 100 AS final_amount;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 调用存储过程
CALL calculate_discount_rate(1200.00);
输出示例:
+————–+—————+—————-+————–+
| total_amount | discount_rate | discount_amount| final_amount |
+————–+—————+—————-+————–+
| 1200.00 | 15.00 | 180.00 | 1020.00 |
+————–+—————+—————-+————–+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Part04-生产案例与实战讲解
4.1 WHILE循环使用
WHILE循环在条件为真时重复执行代码块。
1. 简单WHILE循环
DELIMITER //
CREATE PROCEDURE generate_numbers(IN count INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= count DO
SELECT i AS number;
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 调用存储过程
CALL generate_numbers(5);
输出示例:
+——–+
| number |
+——–+
| 1 |
+——–+
1 row in set (0.00 sec)
+——–+
| number |
+——–+
| 2 |
+——–+
1 row in set (0.00 sec)
+——–+
| number |
+——–+
| 3 |
+——–+
1 row in set (0.00 sec)
+——–+
| number |
+——–+
| 4 |
+——–+
1 row in set (0.00 sec)
+——–+
| number |
+——–+
| 5 |
+——–+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
3. WHILE循环插入数据
DELIMITER //
CREATE PROCEDURE insert_test_data(IN count INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= count DO
INSERT INTO test_data (name, value, created_at)
VALUES (CONCAT(‘test_’, i), i * 10, NOW());
SET i = i + 1;
END WHILE;
SELECT CONCAT(‘成功插入’, count, ‘条数据’) AS result;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 调用存储过程
CALL insert_test_data(10);
输出示例:
+————————-+
| result |
+————————-+
| 成功插入10条数据 |
+————————-+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Part05-风哥经验总结与分享
5.1 REPEAT循环使用
REPEAT循环至少执行一次,直到条件为真时退出。 05更多学习教程公众号风哥教程itpux_com
1. 简单REPEAT循环
DELIMITER //
CREATE PROCEDURE countdown(IN start_num INT)
BEGIN
DECLARE i INT DEFAULT start_num;
REPEAT
SELECT i AS countdown;
SET i = i – 1;
UNTIL i = 0 END REPEAT;
SELECT ‘发射!’ AS message;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 调用存储过程
CALL countdown(3);
输出示例:
+———–+
| countdown |
+———–+
| 3 |
+———–+
1 row in set (0.00 sec)
+———–+
| countdown |
+———–+
| 2 |
+———–+
1 row in set (0.00 sec)
+———–+
| countdown |
+———–+
| 1 |
+———–+
1 row in set (0.00 sec)
+———+
| message |
+———+
| 发射! |
+———+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
3. REPEAT循环处理数据
DELIMITER //
CREATE PROCEDURE process_orders(IN max_retries INT)
BEGIN
DECLARE retry_count INT DEFAULT 0;
DECLARE processed_count INT DEFAULT 0;
REPEAT
UPDATE orders
SET status = 2
WHERE status = 1
LIMIT 100;
SET processed_count = processed_count + ROW_COUNT();
SET retry_count = retry_count + 1;
SELECT CONCAT(‘第’, retry_count, ‘次处理,已处理’, processed_count, ‘条订单’) AS progress;
SLEEP(1);
UNTIL retry_count >= max_retries OR ROW_COUNT() = 0 END REPEAT;
SELECT CONCAT(‘处理完成,共处理’, processed_count, ‘条订单’) AS result;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 调用存储过程
CALL process_orders(5);
输出示例:
+———————————–+
| progress |
+———————————–+
| 第1次处理,已处理100条订单 |
+———————————–+
1 row in set (0.00 sec)
+———————————–+
| progress |
+———————————–+
| 第2次处理,已处理200条订单 |
+———————————–+
1 row in set (1.00 sec)
+———————————–+
| progress |
+———————————–+
| 第3次处理,已处理200条订单 |
+———————————–+
1 row in set (1.00 sec)
+———————————–+
| result |
+———————————–+
| 处理完成,共处理200条订单 |
+———————————–+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
6. LOOP循环
6.1 LOOP循环使用
LOOP循环需要配合LEAVE语句使用,可以创建无限循环。 06 from mysql视频:www.itpux.com
1. 简单LOOP循环
DELIMITER //
CREATE PROCEDURE loop_example(IN max_count INT)
BEGIN
DECLARE i INT DEFAULT 1;
loop_label: LOOP
SELECT i AS current_number;
IF i >= max_count THEN
LEAVE loop_label;
END IF;
SET i = i + 1;
END LOOP;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
2. 调用存储过程
CALL loop_example(3);
输出示例:
+—————-+
| current_number |
+—————-+
| 1 |
+—————-+
1 row in set (0.00 sec)
+—————-+
| current_number |
+—————-+
| 2 |
+—————-+
1 row in set (0.00 sec)
+—————-+
| current_number |
+—————-+
| 3 |
+—————-+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
3. LOOP循环配合ITERATE
DELIMITER //
CREATE PROCEDURE iterate_example(IN max_count INT)
BEGIN
DECLARE i INT DEFAULT 1;
loop_label: LOOP
IF i > max_count THEN
LEAVE loop_label;
END IF;
IF i % 2 = 0 THEN
SET i = i + 1;
ITERATE loop_label;
END IF;
SELECT i AS odd_number;
SET i = i + 1;
END LOOP;
END //
DELIMITER ;
输出示例:
Query OK, 0 rows affected (0.01 sec)
4. 调用存储过程
CALL iterate_example(10);
输出示例:
+————+
| odd_number |
+————+
| 1 |
+————+
1 row in set (0.00 sec)
+————+
| odd_number |
+————+
| 3 |
+————+
1 row in set (0.00 sec)
+————+
| odd_number |
+————+
| 5 |
+————+
1 row in set (0.00 sec)
+————+
| odd_number |
+————+
| 7 |
+————+
1 row in set (0.00 sec)
+————+
| odd_number |
+————+
| 9 |
+————+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
7. 最佳实践
7.1 流程控制最佳实践
存储过程流程控制的最佳实践:
1. 选择合适的控制结构
– 简单条件使用IF
– 多条件判断使用CASE
– 已知循环次数使用WHILE
– 至少执行一次使用REPEAT
– 复杂循环使用LOOP
2. 避免无限循环
– 确保循环有退出条件
– 设置循环次数限制
– 添加超时机制
3. 性能优化
– 减少循环内的数据库操作
– 使用批量操作
– 避免嵌套过深
4. 代码可读性
– 使用有意义的标签名
– 添加适当的注释
– 保持代码简洁
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
