内容简介:本文主要介绍MariaDB存储过程与函数的开发方法与实践,包括存储过程的基本概念、函数的基本概念、存储过程与函数的区别等内容。通过实际案例讲解存储过程和函数的开发过程,帮助读者掌握存储过程与函数开发的技能。风哥教程参考MariaDB官方文档Stored Procedures、Functions等相关内容。
Part01-基础概念与理论知识
1.1 存储过程的基本概念
存储过程(Stored Procedure)是一组预编译的SQL语句,存储在数据库中,可以通过名称调用。它可以接受参数,执行一系列操作,并返回结果。
存储过程的主要特点:
- 预编译:存储过程在创建时被编译,执行时不需要重新编译
- 可重用:可以被多次调用
- 模块化:将复杂的业务逻辑封装在一个单元中
- 安全性:可以控制对数据的访问权限
1.2 函数的基本概念
函数(Function)是一种特殊的存储过程,它返回一个值。函数可以在SQL语句中使用,就像内置函数一样。
函数的主要特点:
- 返回值:必须返回一个值
- 可在SQL语句中使用:可以在SELECT、INSERT、UPDATE等语句中使用
- 参数:可以接受参数
- 预编译:与存储过程一样,函数在创建时被编译
1.3 存储过程与函数的区别
存储过程与函数的主要区别:
- 返回值:函数必须返回一个值,而存储过程可以返回多个值或不返回值
- 使用方式:函数可以在SQL语句中使用,而存储过程必须通过CALL语句调用
- 参数类型:函数的参数只能是IN类型,而存储过程的参数可以是IN、OUT或INOUT类型
- 事务控制:存储过程可以包含事务控制语句,而函数不能
更多视频教程www.fgedu.net.cn
Part02-生产环境规划与建议
2.1 存储过程与函数规划
存储过程与函数规划建议:
- 业务逻辑分析:分析业务逻辑,确定哪些逻辑适合封装在存储过程或函数中
- 命名规范:使用有意义的名称,遵循命名规范
- 参数设计:合理设计参数,确保参数类型和长度正确
- 错误处理:添加错误处理逻辑,确保存储过程和函数的稳定性
2.2 开发规范
开发规范建议:
- 命名规范:使用前缀区分存储过程和函数,如sp_前缀表示存储过程,fn_前缀表示函数
- 缩进规范:使用一致的缩进,提高代码可读性
- 注释规范:添加适当的注释,解释复杂的逻辑
- 代码风格:使用一致的代码风格,如关键字大写、变量名小写等
2.3 性能优化建议
性能优化建议:
- 避免使用游标:游标会降低性能,尽量使用集合操作
- 合理使用临时表:对于复杂的查询,可以使用临时表提高性能
- 优化SQL语句:存储过程和函数中的SQL语句也需要优化
- 避免长时间事务:尽量减少事务的长度,避免锁定资源
学习交流加群风哥微信: itpux-com
Part03-生产环境项目实施方案
3.1 存储过程开发
更多学习教程公众号风哥教程itpux_com
# 存储过程开发
MariaDB [(none)]> # 1. 创建存储过程
DELIMITER //
CREATE PROCEDURE sp_get_user(IN user_id INT)
BEGIN
SELECT id, username, email FROM fgedu_users WHERE id = user_id;
END //
DELIMITER;
# 2. 调用存储过程
CALL sp_get_user(1);
# 3. 创建带OUT参数的存储过程
DELIMITER //
CREATE PROCEDURE sp_get_user_count(OUT count INT)
BEGIN
SELECT COUNT(*) INTO count FROM fgedu_users;
END //
DELIMITER;
# 4. 调用带OUT参数的存储过程
CALL sp_get_user_count(@count);
SELECT @count AS user_count;
# 5. 创建带INOUT参数的存储过程
DELIMITER //
CREATE PROCEDURE sp_increment(INOUT value INT)
BEGIN
SET value = value + 1;
END //
DELIMITER;
# 6. 调用带INOUT参数的存储过程
SET @value = 10;
CALL sp_increment(@value);
SELECT @value AS incremented_value;
MariaDB [(none)]> # 1. 创建存储过程
DELIMITER //
CREATE PROCEDURE sp_get_user(IN user_id INT)
BEGIN
SELECT id, username, email FROM fgedu_users WHERE id = user_id;
END //
DELIMITER;
# 2. 调用存储过程
CALL sp_get_user(1);
# 3. 创建带OUT参数的存储过程
DELIMITER //
CREATE PROCEDURE sp_get_user_count(OUT count INT)
BEGIN
SELECT COUNT(*) INTO count FROM fgedu_users;
END //
DELIMITER;
# 4. 调用带OUT参数的存储过程
CALL sp_get_user_count(@count);
SELECT @count AS user_count;
# 5. 创建带INOUT参数的存储过程
DELIMITER //
CREATE PROCEDURE sp_increment(INOUT value INT)
BEGIN
SET value = value + 1;
END //
DELIMITER;
# 6. 调用带INOUT参数的存储过程
SET @value = 10;
CALL sp_increment(@value);
SELECT @value AS incremented_value;
3.2 函数开发
# 函数开发
MariaDB [(none)]> # 1. 创建函数
DELIMITER //
CREATE FUNCTION fn_get_user_count() RETURNS INT
BEGIN
DECLARE count INT;
SELECT COUNT(*) INTO count FROM fgedu_users;
RETURN count;
END //
DELIMITER;
# 2. 调用函数
SELECT fn_get_user_count() AS user_count;
# 3. 创建带参数的函数
DELIMITER //
CREATE FUNCTION fn_get_user_by_id(user_id INT) RETURNS VARCHAR(50)
BEGIN
DECLARE username VARCHAR(50);
SELECT username INTO username FROM fgedu_users WHERE id = user_id;
RETURN username;
END //
DELIMITER;
# 4. 调用带参数的函数
SELECT fn_get_user_by_id(1) AS username;
# 5. 在SQL语句中使用函数
SELECT id, fn_get_user_by_id(id) AS username FROM fgedu_users;
MariaDB [(none)]> # 1. 创建函数
DELIMITER //
CREATE FUNCTION fn_get_user_count() RETURNS INT
BEGIN
DECLARE count INT;
SELECT COUNT(*) INTO count FROM fgedu_users;
RETURN count;
END //
DELIMITER;
# 2. 调用函数
SELECT fn_get_user_count() AS user_count;
# 3. 创建带参数的函数
DELIMITER //
CREATE FUNCTION fn_get_user_by_id(user_id INT) RETURNS VARCHAR(50)
BEGIN
DECLARE username VARCHAR(50);
SELECT username INTO username FROM fgedu_users WHERE id = user_id;
RETURN username;
END //
DELIMITER;
# 4. 调用带参数的函数
SELECT fn_get_user_by_id(1) AS username;
# 5. 在SQL语句中使用函数
SELECT id, fn_get_user_by_id(id) AS username FROM fgedu_users;
3.3 调试与测试
# 调试与测试
MariaDB [(none)]> # 1. 查看存储过程和函数
SHOW PROCEDURE STATUS WHERE Db = ‘fgedudb’;
SHOW FUNCTION STATUS WHERE Db = ‘fgedudb’;
# 2. 查看存储过程和函数的定义
SHOW CREATE PROCEDURE sp_get_user;
SHOW CREATE FUNCTION fn_get_user_count;
# 3. 修改存储过程
DELIMITER //
ALTER PROCEDURE sp_get_user(IN user_id INT)
BEGIN
SELECT id, username, email, created_at FROM fgedu_users WHERE id = user_id;
END //
DELIMITER;
# 4. 修改函数
DELIMITER //
ALTER FUNCTION fn_get_user_count() RETURNS INT
BEGIN
DECLARE count INT;
SELECT COUNT(*) INTO count FROM fgedu_users WHERE status = ‘active’;
RETURN count;
END //
DELIMITER;
# 5. 删除存储过程和函数
DROP PROCEDURE IF EXISTS sp_get_user;
DROP FUNCTION IF EXISTS fn_get_user_count;
MariaDB [(none)]> # 1. 查看存储过程和函数
SHOW PROCEDURE STATUS WHERE Db = ‘fgedudb’;
SHOW FUNCTION STATUS WHERE Db = ‘fgedudb’;
# 2. 查看存储过程和函数的定义
SHOW CREATE PROCEDURE sp_get_user;
SHOW CREATE FUNCTION fn_get_user_count;
# 3. 修改存储过程
DELIMITER //
ALTER PROCEDURE sp_get_user(IN user_id INT)
BEGIN
SELECT id, username, email, created_at FROM fgedu_users WHERE id = user_id;
END //
DELIMITER;
# 4. 修改函数
DELIMITER //
ALTER FUNCTION fn_get_user_count() RETURNS INT
BEGIN
DECLARE count INT;
SELECT COUNT(*) INTO count FROM fgedu_users WHERE status = ‘active’;
RETURN count;
END //
DELIMITER;
# 5. 删除存储过程和函数
DROP PROCEDURE IF EXISTS sp_get_user;
DROP FUNCTION IF EXISTS fn_get_user_count;
学习交流加群风哥QQ113257174
Part04-生产案例与实战讲解
4.1 存储过程开发案例
场景描述:开发一个存储过程,用于处理用户注册逻辑。
# 创建存储过程
MariaDB [(none)]> DELIMITER //
CREATE PROCEDURE sp_register_user(IN p_username VARCHAR(50), IN p_email VARCHAR(100), IN p_password VARCHAR(100), OUT p_user_id INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Error registering user’;
END;
START TRANSACTION;
# 检查用户名是否已存在
IF EXISTS (SELECT 1 FROM fgedu_users WHERE username = p_username) THEN
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Username already exists’;
END IF;
# 检查邮箱是否已存在
IF EXISTS (SELECT 1 FROM fgedu_users WHERE email = p_email) THEN
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Email already exists’;
END IF;
# 插入用户
INSERT INTO fgedu_users(username, email, password, created_at, updated_at)
VALUES(p_username, p_email, p_password, NOW(), NOW());
# 获取用户ID
SET p_user_id = LAST_INSERT_ID();
COMMIT;
END //
DELIMITER;
# 调用存储过程
CALL sp_register_user(‘testuser’, ‘test@fgedu.net.cn’, ‘password123’, @user_id);
SELECT @user_id AS user_id;
# 验证结果
SELECT * FROM fgedu_users WHERE id = @user_id;
MariaDB [(none)]> DELIMITER //
CREATE PROCEDURE sp_register_user(IN p_username VARCHAR(50), IN p_email VARCHAR(100), IN p_password VARCHAR(100), OUT p_user_id INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Error registering user’;
END;
START TRANSACTION;
# 检查用户名是否已存在
IF EXISTS (SELECT 1 FROM fgedu_users WHERE username = p_username) THEN
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Username already exists’;
END IF;
# 检查邮箱是否已存在
IF EXISTS (SELECT 1 FROM fgedu_users WHERE email = p_email) THEN
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Email already exists’;
END IF;
# 插入用户
INSERT INTO fgedu_users(username, email, password, created_at, updated_at)
VALUES(p_username, p_email, p_password, NOW(), NOW());
# 获取用户ID
SET p_user_id = LAST_INSERT_ID();
COMMIT;
END //
DELIMITER;
# 调用存储过程
CALL sp_register_user(‘testuser’, ‘test@fgedu.net.cn’, ‘password123’, @user_id);
SELECT @user_id AS user_id;
# 验证结果
SELECT * FROM fgedu_users WHERE id = @user_id;
执行结果:
# 调用存储过程
Query OK, 0 rows affected (0.00 sec)
# 获取用户ID
+———+
| user_id |
+———+
| 6 |
+———+
# 验证结果
+—-+———-+——————+————-+———————+———————+
| id | username | email | password | created_at | updated_at |
+—-+———-+——————+————-+———————+———————+
| 6 | testuser | test@fgedu.net.cn | password123 | 2023-01-01 10:00:00 | 2023-01-01 10:00:00 |
+—-+———-+——————+————-+———————+———————+
Query OK, 0 rows affected (0.00 sec)
# 获取用户ID
+———+
| user_id |
+———+
| 6 |
+———+
# 验证结果
+—-+———-+——————+————-+———————+———————+
| id | username | email | password | created_at | updated_at |
+—-+———-+——————+————-+———————+———————+
| 6 | testuser | test@fgedu.net.cn | password123 | 2023-01-01 10:00:00 | 2023-01-01 10:00:00 |
+—-+———-+——————+————-+———————+———————+
4.2 函数开发案例
场景描述:开发一个函数,用于计算订单的总金额。
# 创建函数
MariaDB [(none)]> DELIMITER //
CREATE FUNCTION fn_calculate_order_total(order_id INT) RETURNS DECIMAL(10,2)
BEGIN
DECLARE total DECIMAL(10,2);
SELECT SUM(quantity * price) INTO total
FROM fgedu_order_items
WHERE order_id = order_id;
RETURN IFNULL(total, 0);
END //
DELIMITER;
# 调用函数
SELECT fn_calculate_order_total(1) AS order_total;
# 在SQL语句中使用函数
SELECT o.id, o.order_no, fn_calculate_order_total(o.id) AS total_amount
FROM fgedu_orders o;
MariaDB [(none)]> DELIMITER //
CREATE FUNCTION fn_calculate_order_total(order_id INT) RETURNS DECIMAL(10,2)
BEGIN
DECLARE total DECIMAL(10,2);
SELECT SUM(quantity * price) INTO total
FROM fgedu_order_items
WHERE order_id = order_id;
RETURN IFNULL(total, 0);
END //
DELIMITER;
# 调用函数
SELECT fn_calculate_order_total(1) AS order_total;
# 在SQL语句中使用函数
SELECT o.id, o.order_no, fn_calculate_order_total(o.id) AS total_amount
FROM fgedu_orders o;
执行结果:
# 调用函数
+————+
| order_total |
+————+
| 150.00 |
+————+
# 在SQL语句中使用函数
+—-+—————+————–+
| id | order_no | total_amount |
+—-+—————+————–+
| 1 | ORD20230101001 | 150.00 |
| 2 | ORD20230101002 | 200.00 |
| 3 | ORD20230101003 | 100.00 |
+—-+—————+————–+
+————+
| order_total |
+————+
| 150.00 |
+————+
# 在SQL语句中使用函数
+—-+—————+————–+
| id | order_no | total_amount |
+—-+—————+————–+
| 1 | ORD20230101001 | 150.00 |
| 2 | ORD20230101002 | 200.00 |
| 3 | ORD20230101003 | 100.00 |
+—-+—————+————–+
4.3 复杂业务逻辑实现案例
场景描述:开发一个存储过程,用于处理订单的完整流程,包括创建订单、添加订单项、计算总金额等。
# 创建存储过程
MariaDB [(none)]> DELIMITER //
CREATE PROCEDURE sp_process_order(IN p_user_id INT, IN p_items JSON, OUT p_order_id INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Error processing order’;
END;
DECLARE v_order_no VARCHAR(50);
DECLARE v_total DECIMAL(10,2) DEFAULT 0;
DECLARE v_item JSON;
DECLARE v_product_id INT;
DECLARE v_quantity INT;
DECLARE v_price DECIMAL(10,2);
DECLARE i INT DEFAULT 0;
DECLARE item_count INT;
START TRANSACTION;
# 生成订单号
SET v_order_no = CONCAT(‘ORD’, DATE_FORMAT(NOW(), ‘%Y%m%d’), LPAD((SELECT COUNT(*) + 1 FROM fgedu_orders), 3, ‘0’));
# 插入订单
INSERT INTO fgedu_orders(user_id, order_no, status, created_at, updated_at)
VALUES(p_user_id, v_order_no, ‘pending’, NOW(), NOW());
SET p_order_id = LAST_INSERT_ID();
# 处理订单项
SET item_count = JSON_LENGTH(p_items);
WHILE i < item_count DO
SET v_item = JSON_EXTRACT(p_items, CONCAT(‘$[‘, i, ‘]’));
SET v_product_id = JSON_EXTRACT(v_item, ‘$.product_id’);
SET v_quantity = JSON_EXTRACT(v_item, ‘$.quantity’);
# 获取产品价格
SELECT price INTO v_price FROM fgedu_products WHERE id = v_product_id;
# 插入订单项
INSERT INTO fgedu_order_items(order_id, product_id, quantity, price)
VALUES(p_order_id, v_product_id, v_quantity, v_price);
# 计算总金额
SET v_total = v_total + (v_quantity * v_price);
SET i = i + 1;
END WHILE;
# 更新订单总金额
UPDATE fgedu_orders SET total_amount = v_total WHERE id = p_order_id;
COMMIT;
END //
DELIMITER;
# 调用存储过程
CALL sp_process_order(1, ‘[{“product_id”: 1, “quantity”: 2}, {“product_id”: 2, “quantity”: 1}]’, @order_id);
SELECT @order_id AS order_id;
# 验证结果
SELECT * FROM fgedu_orders WHERE id = @order_id;
SELECT * FROM fgedu_order_items WHERE order_id = @order_id;
MariaDB [(none)]> DELIMITER //
CREATE PROCEDURE sp_process_order(IN p_user_id INT, IN p_items JSON, OUT p_order_id INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SIGNAL SQLSTATE ‘45000’ SET MESSAGE_TEXT = ‘Error processing order’;
END;
DECLARE v_order_no VARCHAR(50);
DECLARE v_total DECIMAL(10,2) DEFAULT 0;
DECLARE v_item JSON;
DECLARE v_product_id INT;
DECLARE v_quantity INT;
DECLARE v_price DECIMAL(10,2);
DECLARE i INT DEFAULT 0;
DECLARE item_count INT;
START TRANSACTION;
# 生成订单号
SET v_order_no = CONCAT(‘ORD’, DATE_FORMAT(NOW(), ‘%Y%m%d’), LPAD((SELECT COUNT(*) + 1 FROM fgedu_orders), 3, ‘0’));
# 插入订单
INSERT INTO fgedu_orders(user_id, order_no, status, created_at, updated_at)
VALUES(p_user_id, v_order_no, ‘pending’, NOW(), NOW());
SET p_order_id = LAST_INSERT_ID();
# 处理订单项
SET item_count = JSON_LENGTH(p_items);
WHILE i < item_count DO
SET v_item = JSON_EXTRACT(p_items, CONCAT(‘$[‘, i, ‘]’));
SET v_product_id = JSON_EXTRACT(v_item, ‘$.product_id’);
SET v_quantity = JSON_EXTRACT(v_item, ‘$.quantity’);
# 获取产品价格
SELECT price INTO v_price FROM fgedu_products WHERE id = v_product_id;
# 插入订单项
INSERT INTO fgedu_order_items(order_id, product_id, quantity, price)
VALUES(p_order_id, v_product_id, v_quantity, v_price);
# 计算总金额
SET v_total = v_total + (v_quantity * v_price);
SET i = i + 1;
END WHILE;
# 更新订单总金额
UPDATE fgedu_orders SET total_amount = v_total WHERE id = p_order_id;
COMMIT;
END //
DELIMITER;
# 调用存储过程
CALL sp_process_order(1, ‘[{“product_id”: 1, “quantity”: 2}, {“product_id”: 2, “quantity”: 1}]’, @order_id);
SELECT @order_id AS order_id;
# 验证结果
SELECT * FROM fgedu_orders WHERE id = @order_id;
SELECT * FROM fgedu_order_items WHERE order_id = @order_id;
执行结果:
# 调用存储过程
Query OK, 0 rows affected (0.00 sec)
# 获取订单ID
+———-+
| order_id |
+———-+
| 4 |
+———-+
# 验证订单
+—-+———+—————+————–+———+———————+———————+
| id | user_id | order_no | total_amount | status | created_at | updated_at |
+—-+———+—————+————–+———+———————+———————+
| 4 | 1 | ORD20230101004 | 250.00 | pending | 2023-01-01 10:00:00 | 2023-01-01 10:00:00 |
+—-+———+—————+————–+———+———————+———————+
# 验证订单项
+—-+———-+————+———-+——-+
| id | order_id | product_id | quantity | price |
+—-+———-+————+———-+——-+
| 1 | 4 | 1 | 2 | 50.0 |
| 2 | 4 | 2 | 1 | 150.0 |
+—-+———-+————+———-+——-+
Query OK, 0 rows affected (0.00 sec)
# 获取订单ID
+———-+
| order_id |
+———-+
| 4 |
+———-+
# 验证订单
+—-+———+—————+————–+———+———————+———————+
| id | user_id | order_no | total_amount | status | created_at | updated_at |
+—-+———+—————+————–+———+———————+———————+
| 4 | 1 | ORD20230101004 | 250.00 | pending | 2023-01-01 10:00:00 | 2023-01-01 10:00:00 |
+—-+———+—————+————–+———+———————+———————+
# 验证订单项
+—-+———-+————+———-+——-+
| id | order_id | product_id | quantity | price |
+—-+———-+————+———-+——-+
| 1 | 4 | 1 | 2 | 50.0 |
| 2 | 4 | 2 | 1 | 150.0 |
+—-+———-+————+———-+——-+
风哥提示:安全开发是防止SQL注入的第一道防线
Part05-风哥经验总结与分享
5.1 存储过程与函数开发最佳实践
风哥提示:在开发存储过程和函数时,应遵循最佳实践,提高代码的质量、性能和可维护性。
- 合理使用存储过程和函数:将复杂的业务逻辑封装在存储过程和函数中,提高代码的可重用性
- 添加错误处理:使用异常处理机制,确保存储过程和函数的稳定性
- 优化SQL语句:存储过程和函数中的SQL语句也需要优化,提高性能
- 使用事务:对于涉及多个操作的存储过程,使用事务确保数据一致性
- 定期维护:定期检查和优化存储过程和函数,确保其性能
5.2 性能优化技巧
- 避免使用游标:游标会降低性能,尽量使用集合操作
- 合理使用临时表:对于复杂的查询,可以使用临时表提高性能
- 优化循环:尽量减少循环的次数,优化循环体内的操作
- 使用索引:确保存储过程和函数中使用的SQL语句能够利用索引
- 减少网络传输:尽量在存储过程和函数中完成所有操作,减少网络传输
5.3 常见问题与解决方案
- 性能问题:优化SQL语句,避免使用游标,合理使用索引
- 错误处理:添加异常处理机制,确保存储过程和函数的稳定性
- 参数传递:合理设计参数,确保参数类型和长度正确
- 事务管理:合理使用事务,确保数据一致性
- 调试困难:添加日志记录,便于调试和排查问题
# 存储过程与函数开发示例
— 创建存储过程
DELIMITER //
CREATE PROCEDURE sp_get_order_details(IN order_id INT)
BEGIN
SELECT o.id, o.order_no, o.total_amount, o.status, o.created_at,
u.username, u.email
FROM fgedu_orders o
INNER JOIN fgedu_users u ON o.user_id = u.id
WHERE o.id = order_id;
SELECT oi.id, oi.product_id, p.name, oi.quantity, oi.price
FROM fgedu_order_items oi
INNER JOIN fgedu_products p ON oi.product_id = p.id
WHERE oi.order_id = order_id;
END //
DELIMITER;
— 创建函数
DELIMITER //
CREATE FUNCTION fn_format_currency(amount DECIMAL(10,2)) RETURNS VARCHAR(20)
BEGIN
RETURN CONCAT(‘¥’, FORMAT(amount, 2));
END //
DELIMITER;
— 调用存储过程
CALL sp_get_order_details(1);
— 调用函数
SELECT fn_format_currency(100.50) AS formatted_amount;
— 创建存储过程
DELIMITER //
CREATE PROCEDURE sp_get_order_details(IN order_id INT)
BEGIN
SELECT o.id, o.order_no, o.total_amount, o.status, o.created_at,
u.username, u.email
FROM fgedu_orders o
INNER JOIN fgedu_users u ON o.user_id = u.id
WHERE o.id = order_id;
SELECT oi.id, oi.product_id, p.name, oi.quantity, oi.price
FROM fgedu_order_items oi
INNER JOIN fgedu_products p ON oi.product_id = p.id
WHERE oi.order_id = order_id;
END //
DELIMITER;
— 创建函数
DELIMITER //
CREATE FUNCTION fn_format_currency(amount DECIMAL(10,2)) RETURNS VARCHAR(20)
BEGIN
RETURN CONCAT(‘¥’, FORMAT(amount, 2));
END //
DELIMITER;
— 调用存储过程
CALL sp_get_order_details(1);
— 调用函数
SELECT fn_format_currency(100.50) AS formatted_amount;
通过以上措施,可以有效提高MariaDB存储过程与函数开发的质量和性能,确保系统稳定运行。
from MariaDB视频:www.itpux.com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
