目录
三、相对于sql操纵语句(select、insert等)存储过程的好处
一、概述
MySQL的存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集合。用户通过指定的存储过程名和参数(如果有的话)来调用并执行它。存储过程可以在数据库中预编译并存储,这样它们可以被多次调用而无需重新编写或解析SQL语句。
可以用如下图表示存储过程:
二、存储过程的作用
1、代码重用
存储过程允许编写一次代码并在多个地方重用它。
2、简化复杂操作
对于复杂的数据库操作,可以将其封装在存储过程中,从而简化应用程序代码。
3、提高性能
存储过程在第一次执行时会被编译并存储在数据库中,后续调用时无需再次编译,从而提高性能。
4、安全性和数据完整性
通过限制对基础表的直接访问,可以只通过存储过程来访问数据,从而确保数据的安全性和完整性。
三、相对于sql操纵语句(select、insert等)存储过程的好处
在MySQL中使用存储过程(Stored Procedures)相比直接使用SQL基本操作语句(如SELECT, INSERT, UPDATE等)来处理数据表,具有以下好处:
1、代码重用和封装
(1)概述
- 存储过程允许将复杂的SQL逻辑封装在一个可重用的单元中。这样,可以多次调用这个存储过程,而不需要重复编写相同的SQL代码。
- 通过封装,可以隐藏复杂的SQL逻辑,只向用户或应用程序提供简单的接口。
(2)举例
假设有一个复杂的查询,用于计算员工的总工资(包括基本工资、奖金、津贴等)。可以将这个查询封装成一个存储过程:
DELIMITER //
CREATE PROCEDURE CalculateEmployeeTotalSalary(IN emp_id INT, OUT total_salary DECIMAL(10, 2))
BEGIN
SELECT
SUM(salary.amount + bonus.amount + allowance.amount)
INTO
total_salary
FROM
employees e
JOIN
salaries salary ON e.id = salary.employee_id
LEFT JOIN
bonuses bonus ON e.id = bonus.employee_id
LEFT JOIN
allowances allowance ON e.id = allowance.employee_id
WHERE
e.id = emp_id;
END //
DELIMITER ;
这个存储过程可以被多次调用,传入不同的员工ID,并返回他们的总工资。
2. 简化应用程序逻辑
(1)概述
- 应用程序可以通过调用存储过程来执行复杂的数据库操作,而不需要在应用程序代码中编写大量的SQL语句。这有助于简化应用程序的逻辑,并使其更易于维护。
(2)举例
在应用程序中,可能需要经常获取员工的总工资。通过使用上面的存储过程,可以简化应用程序中的逻辑:
# 伪源代码
employee_id = 123
total_salary = call_stored_procedure('CalculateEmployeeTotalSalary', employee_id)
print(f"Employee's total salary is: {total_salary}")
3. 提高性能
- 存储过程在首次执行时会被编译并存储在数据库中,因此后续调用时不需要再次编译,从而提高了执行速度。
- 存储过程可以优化查询计划,因为MySQL优化器在存储过程创建时会为其生成一个执行计划,并在后续调用时重复使用。
4. 安全性
(1)概述
- 存储过程允许限制对基础数据表的直接访问,从而提高了数据的安全性。可以通过存储过程来验证和过滤用户输入,防止SQL注入等安全漏洞。
- 可以使用MySQL的权限系统来限制对存储过程的访问,只允许特定的用户或角色执行特定的存储过程。
(2)举例
可以通过存储过程来验证和过滤用户输入,防止SQL注入。例如,可以创建一个存储过程来插入新用户,并在过程中验证用户名和密码的格式:
DELIMITER //
CREATE PROCEDURE InsertNewUser(IN username VARCHAR(50), IN password VARCHAR(50))
BEGIN
-- 验证用户名和密码的格式(例如,确保密码足够长或包含特定字符)
IF LENGTH(password) < 8 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Password must be at least 8 characters long';
END IF;
INSERT INTO users (username, password_hash) VALUES (username, SHA2(password, 256));
END //
DELIMITER ;
5. 事务处理
(1)概述
存储过程可以包含多个SQL语句,并且这些语句可以作为一个事务来执行。这意味着要么所有语句都成功执行,要么在发生错误时回滚到事务开始之前的状态。这有助于确保数据的完整性和一致性。
(2)举例
假设需要在一个存储过程中同时插入一条订单记录和多个订单项记录,并且希望它们要么都成功,要么都失败(回滚):
DELIMITER //
CREATE PROCEDURE InsertOrderWithItems(IN order_data ..., IN item_data_list ...)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 发生异常时回滚事务
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
-- 插入订单记录
INSERT INTO orders ...;
-- 插入订单项记录(循环遍历item_data_list)
-- ...
COMMIT;
END //
DELIMITER ;
6. 集中管理和维护
存储过程都存储在数据库中,可以通过数据库管理工具进行集中管理和维护。可以轻松地查看、修改或删除存储过程,而不需要在多个应用程序文件中搜索和修改SQL代码。
7. 版本控制
由于存储过程存储在数据库中,可以使用数据库的版本控制系统(如MySQL的备份和恢复功能)来跟踪和管理存储过程的更改。这有助于确保在数据库升级或迁移时不会丢失或破坏重要的业务逻辑。
8. 增强可读性
通过为复杂的SQL逻辑命名并提供描述性的参数,存储过程可以增强代码的可读性。这使得其他开发人员更容易理解代码意图和目的。
9. 日志和审计
存储过程的执行可以被记录在日志中,以便于后续的审计和跟踪。这有助于在出现问题时快速定位原因,并采取相应的措施进行修复。
10. 支持复杂的业务逻辑
存储过程支持条件语句、循环结构等控制流语句,可以处理复杂的业务逻辑。这可以将复杂的业务规则封装在存储过程中,并通过简单的接口调用它们。
四、存储过程实战
1. 存储过程的实战环境
(1)命令行模式
在安装好mysql的linux或window计算机,启动mysql,输入root账号和密码,就可以进入命令行模式。
(2)navicat工具
- 打开 Navicat 并连接到 MySQL 数据库。
- 在左侧的数据库列表中,找到想要操作的数据库,并双击它。
- 在打开的界面中,找到“函数”或“存储过程”部分(这取决于 Navicat 的版本和设置),右键点击它,选择“新建函数”或“新建存储过程”。
- 在打开的 SQL 编辑器中,输入存储过程定义,如上面的例子所示。
- 点击执行按钮(通常是一个绿色的三角形图标)来创建存储过程。
2. 创建存储过程
使用CREATE PROCEDURE语句来创建存储过程。以下是一个简单的示例:
DELIMITER //
CREATE PROCEDURE SimpleProcedure()
BEGIN
SELECT 'Hello, World!';
END //
DELIMITER ;
DELIMITER用于更改命令提示符,以便在存储过程中使用多个语句。在上述示例中,我们将分隔符更改为//,以便在存储过程中使用多个语句,并在存储过程定义结束后将其恢复为;。
CREATE PROCEDURE后面是存储过程的名称和参数列表(如果有的话)。
BEGIN和END之间的部分是存储过程的主体,其中包含了要执行的SQL语句。
3. 调用存储过程
使用CALL语句来调用存储过程。例如,要调用上面创建的SimpleProcedure,可以这样做:
CALL SimpleProcedure();
4. 参数
存储过程可以接受参数,这些参数可以是输入参数(IN)、输出参数(OUT)或输入/输出参数(INOUT)。以下是一个带有输入参数的存储过程示例:
DELIMITER //
CREATE PROCEDURE GreetUser(IN userName VARCHAR(50))
BEGIN
SELECT CONCAT('Hello, ', userName, '!');
END //
DELIMITER ;
调用这个存储过程时,需要提供一个参数值:
CALL GreetUser('John Doe');
5. 错误处理
在存储过程中,可以使用DECLARE语句来声明条件处理程序,以便在发生错误时执行特定的操作。例如,可以使用DECLARE CONTINUE HANDLER来定义一个在发生错误时继续执行的错误处理程序。
6. 修改和删除存储过程
使用ALTER PROCEDURE语句可以修改存储过程。但是,请注意,直接修改存储过程可能不是一个好主意,因为这可能会导致意外的副作用。通常,更好的做法是先删除旧的存储过程,然后创建一个新的。
使用DROP PROCEDURE语句可以删除存储过程。例如,要删除上面创建的SimpleProcedure,可以这样输入如下命令:
DROP PROCEDURE SimpleProcedure;
7. 注意事项
在编写存储过程时,要确保不会与现有的SQL语句或函数名称冲突。
在存储过程中使用变量时,要确保正确地声明和初始化。
始终测试存储过程以确保按预期工作,并处理所有可能的错误情况。
五、SQL中的存储过程和编程语言中的函数
1、概述
MySQL中的存储过程(Stored Procedure)与许多编程语言中的函数(Function)在概念上有很多相似之处。虽然它们在具体实现和使用细节上可能有所不同,但它们的基本原理和目标是一致的:封装一段可重用的代码逻辑,并通过特定的名称和参数(如果有的话)来调用这段逻辑。
2、相似点
以下是MySQL存储过程和编程语言函数之间的一些相似之处:
(1)封装代码逻辑:存储过程和函数都允许将复杂的逻辑封装在一个可重用的单元中。这样,可以在其他地方多次调用这个单元,而不需要重复编写相同的代码。
(2)接受参数:存储过程和函数都可以接受参数,这些参数可以是输入参数(用于传递数据给存储过程或函数),也可以是输出参数(用于从存储过程或函数返回值)。
(3)返回值:虽然存储过程通常不直接返回值(但可以通过输出参数或结果集来传递数据),但函数通常有一个返回值,该值表示函数执行的结果。
(4)可调用:存储过程和函数都可以从应用程序或其他数据库对象中调用。可以通过指定的名称和参数(如果有的话)来调用它们。
(5)可维护性:由于存储过程和函数封装了复杂的逻辑,因此它们可以提高代码的可维护性。当需要修改逻辑时,只需要修改存储过程或函数的定义,而不需要修改所有调用该逻辑的地方。
3、差异
MySQL的存储过程和编程语言中的函数也有一些不同之处:
(1)返回类型:存储过程通常不直接返回一个值(尽管它们可以通过输出参数或结果集来传递数据),而函数通常有一个明确的返回类型,并返回一个值。
(2)调用方式:在MySQL中,使用CALL语句来调用存储过程,而函数可以在SQL查询中直接作为表达式使用。
(3)错误处理:存储过程通常包含更复杂的错误处理逻辑,因为它们可能执行多个操作并需要确保数据的一致性和完整性。而函数通常只关注单个操作的结果。
(4)存储位置:存储过程和函数都存储在数据库中,但它们在数据库中的表示方式和管理方式可能有所不同。
总的来说,MySQL的存储过程和编程语言中的函数在概念和用法上有所不同,但它们的原理和目标是一致的:封装可重用的代码逻辑并提高代码的可维护性和可重用性。
文章正下方可以看到我的联系方式:鼠标“点击” 下面的 “威迪斯特-就是video system 微信名片”字样,就会出现我的二维码,欢迎沟通探讨。