MySQL(14) 如何创建和调用存储过程?

在 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;

带条件逻辑的存储过程

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

-- 创建 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);

带循环的存储过程

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

-- 创建 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 中创建和调用存储过程,以及存储过程中的各种逻辑控制和参数类型。存储过程是强大的数据库工具,可以帮助简化复杂操作,增强系统性能和安全性。

### 如何在 MySQL创建调用函数及存储过程 #### 创建存储过程 存储过程是一组预编译的 SQL 语句,可以在数据库中多次重用。这不仅提高了效率还减少了网络流量。 ##### 创建无参数存储过程 下面是一个简单的不带任何输入或输出参数的例子: ```sql DELIMITER // CREATE PROCEDURE simpleProcedure() BEGIN SELECT * FROM employees; END // DELIMITER ; ``` 此代码段定义了一个名为 `simpleProcedure` 的存储过程,它会从 `employees` 表中选择所有的记录[^1]。 ##### 创建带有输入参数的存储过程 当需要向存储过程中传递数据时,则可以使用 IN 参数: ```sql DELIMITER // CREATE PROCEDURE getEmployeeById(IN empId INT) BEGIN SELECT * FROM employees WHERE id = empId; END // DELIMITER ; ``` 这里展示了如何通过指定员工 ID 来获取特定员工的信息[^2]。 ##### 创建带有输出参数的存储过程 如果希望返回某个计算的结果给调用者,那么 OUT 参数就派上用场了: ```sql DELIMITER // CREATE PROCEDURE countEmployees(OUT totalEmps INT) BEGIN SELECT COUNT(*) INTO totalEmps FROM employees; END // DELIMITER ; ``` 这段脚本用于统计并返回 `employees` 表中的总人数。 #### 调用存储过程 一旦创建好了存储过程之后就可以很容易地去调用了: ```sql CALL simpleProcedure(); CALL getEmployeeById(1); CALL countEmployees(@total); SELECT @total; -- 显示总数 ``` 以上命令分别对应于上述三种类型的存储过程调用方式。 #### 创建自定义函数 除了存储过程外,在某些情况下可能还需要更灵活的操作——这就是为什么有了用户定义的功能(UDF)。它们通常用来执行一些复杂的逻辑运算或是处理字符串等操作。 ##### 定义一个基本功能 假设想要构建一个新的函数来判断一个人是否成年: ```sql DELIMITER $$ CREATE FUNCTION isAdult(age INT) RETURNS BOOLEAN DETERMINISTIC RETURN age >= 18; DELIMITER ; ``` 这个新建立起来的名字叫作 `isAdult()` 的布尔型函数将会接收年龄作为其唯一参数,并依据传入数值决定返回 true 或 false。 #### 使用已创建的函数 最后一步就是应用之前所写的 UDF 到实际场景当中去了: ```sql SELECT name, age, isAdult(age) AS adult_status FROM people; ``` 这条查询语句将展示每个人员的名字、他们的岁数以及他们是不是成年人的状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辞暮尔尔-烟火年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值