• admin
  • 239
  • 2025-08-14 03:41:35

在 MySQL 中,存储过程(Stored Procedure)是一组预编译的 SQL 语句,可以通过名称和参数进行调用。存储过程可以简化复杂的数据库操作,提高代码的复用性和性能,并增强安全性。以下详细介绍如何创建和调用存储过程,并展示一些具体的代码示例。

创建存储过程

使用 CREATE PROCEDURE 语句创建存储过程。存储过程可以包含输入参数(IN)、输出参数(OUT)和输入输出参数(INOUT),可以包含多条 SQL 操作,包含条件逻辑、循环等。

语法

CREATE PROCEDURE procedure_name ([parameter_list])

BEGIN

-- SQL 语句

END;

示例:简单存储过程

下面创建一个简单的存储过程 AddEmployee,用于插入新员工记录。

-- 创建数据库

CREATE DATABASE company;

-- 选择数据库

USE company;

-- 创建 employees 表

CREATE TABLE employees (

emp_id INT AUTO_INCREMENT PRIMARY KEY,

emp_name VARCHAR(100) NOT NULL,

emp_position VARCHAR(100),

emp_salary DECIMAL(10, 2),

hire_date DATE

);

-- 创建 AddEmployee 存储过程

DELIMITER //

CREATE PROCEDURE AddEmployee (

IN name VARCHAR(100),

IN position VARCHAR(100),

IN salary DECIMAL(10, 2),

IN hire_date DATE

)

BEGIN

INSERT INTO employees (emp_name, emp_position, emp_salary, hire_date)

VALUES (name, position, salary, hire_date);

END;

//

DELIMITER ;

调用存储过程

使用 CALL 语句调用存储过程。

示例:调用 AddEmployee 存储过程

CALL AddEmployee('John Doe', 'Manager', 75000.00, '2023-10-01');

带输出参数的存储过程

存储过程可以包含输出参数,用于返回结果。下面是一个带输出参数的存储过程示例:

-- 创建 CalculateAnnualSalary 存储过程

DELIMITER //

CREATE PROCEDURE CalculateAnnualSalary (

IN emp_id INT,

OUT annual_salary DECIMAL(10, 2)

)

BEGIN

SELECT emp_salary * 12 INTO annual_salary

FROM employees

WHERE employees.emp_id = emp_id;

END;

//

DELIMITER ;

调用带输出参数的存储过程:

CALL CalculateAnnualSalary(1, @annual_salary);

SELECT @annual_salary;

带条件逻辑的存储过程

存储过程可以包含条件逻辑,如 IF、CASE 等语句。

-- 创建 AdjustSalary 存储过程,调整员工薪水

DELIMITER //

CREATE PROCEDURE AdjustSalary (

IN emp_id INT,

IN adjustment DECIMAL(10, 2)

)

BEGIN

DECLARE current_salary DECIMAL(10, 2);

-- 获取当前薪水

SELECT emp_salary INTO current_salary

FROM employees

WHERE employees.emp_id = emp_id;

-- 调整薪水

IF current_salary IS NOT NULL THEN

UPDATE employees

SET emp_salary = current_salary + adjustment

WHERE employees.emp_id = emp_id;

END IF;

END;

//

DELIMITER ;

调用带条件逻辑的存储过程:

CALL AdjustSalary(1, 5000.00);

带循环的存储过程

存储过程还可以包含循环语句,如 LOOP、WHILE 等。

-- 创建 BatchAdjustSalaries 存储过程,批量增加员工薪水

DELIMITER //

CREATE PROCEDURE BatchAdjustSalaries (

IN adjustment DECIMAL(10, 2)

)

BEGIN

DECLARE done INT DEFAULT 0;

DECLARE emp_id INT;

DECLARE cur CURSOR FOR SELECT emp_id FROM employees;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN cur;

read_loop: LOOP

FETCH cur INTO emp_id;

IF done THEN

LEAVE read_loop;

END IF;

-- 调用 AdjustSalary 存储过程

CALL AdjustSalary(emp_id, adjustment);

END LOOP;

CLOSE cur;

END;

//

DELIMITER ;

调用带循环的存储过程:

CALL BatchAdjustSalaries(1000.00);

完整的存储过程示例

以下是一个完整的存储过程示例,从创建表到定义和调用存储过程的完整过程。

-- 创建数据库

CREATE DATABASE company;

-- 选择数据库

USE company;

-- 创建 employees 表

CREATE TABLE employees (

emp_id INT AUTO_INCREMENT PRIMARY KEY,

emp_name VARCHAR(100) NOT NULL,

emp_position VARCHAR(100),

emp_salary DECIMAL(10, 2),

hire_date DATE

);

-- 创建 AddEmployee 存储过程

DELIMITER //

CREATE PROCEDURE AddEmployee (

IN name VARCHAR(100),

IN position VARCHAR(100),

IN salary DECIMAL(10, 2),

IN hire_date DATE

)

BEGIN

INSERT INTO employees (emp_name, emp_position, emp_salary, hire_date)

VALUES (name, position, salary, hire_date);

END;

//

DELIMITER ;

-- 调用 AddEmployee 存储过程

CALL AddEmployee('John Doe', 'Manager', 75000.00, '2023-10-01');

-- 创建 CalculateAnnualSalary 存储过程

DELIMITER //

CREATE PROCEDURE CalculateAnnualSalary (

IN emp_id INT,

OUT annual_salary DECIMAL(10, 2)

)

BEGIN

SELECT emp_salary * 12 INTO annual_salary

FROM employees

WHERE employees.emp_id = emp_id;

END;

//

DELIMITER ;

-- 调用 CalculateAnnualSalary 存储过程

CALL CalculateAnnualSalary(1, @annual_salary);

SELECT @annual_salary;

-- 创建 AdjustSalary 存储过程

DELIMITER //

CREATE PROCEDURE AdjustSalary (

IN emp_id INT,

IN adjustment DECIMAL(10, 2)

)

BEGIN

DECLARE current_salary DECIMAL(10, 2);

-- 获取当前薪水

SELECT emp_salary INTO current_salary

FROM employees

WHERE employees.emp_id = emp_id;

-- 调整薪水

IF current_salary IS NOT NULL THEN

UPDATE employees

SET emp_salary = current_salary + adjustment

WHERE employees.emp_id = emp_id;

END IF;

END;

//

DELIMITER ;

-- 调用 AdjustSalary 存储过程

CALL AdjustSalary(1, 5000.00);

-- 创建 BatchAdjustSalaries 存储过程

DELIMITER //

CREATE PROCEDURE BatchAdjustSalaries (

IN adjustment DECIMAL(10, 2)

)

BEGIN

DECLARE done INT DEFAULT 0;

DECLARE emp_id INT;

DECLARE cur CURSOR FOR SELECT emp_id FROM employees;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN cur;

read_loop: LOOP

FETCH cur INTO emp_id;

IF done THEN

LEAVE read_loop;

END IF;

-- 调用 AdjustSalary 存储过程

CALL AdjustSalary(emp_id, adjustment);

END LOOP;

CLOSE cur;

END;

//

DELIMITER ;

-- 调用 BatchAdjustSalaries 存储过程

CALL BatchAdjustSalaries(1000.00);

通过以上代码示例,展示了如何在 MySQL 中创建和调用存储过程,以及存储过程中的各种逻辑控制和参数类型。存储过程是强大的数据库工具,可以帮助简化复杂操作,增强系统性能和安全性。