详解MySQL存储过程参数有三种类型(in、out、inout)


在MySQL中,存储过程是一种为了完成特定功能的SQL语句集,它允许用户定义一组SQL语句,然后通过调用存储过程来执行这些语句。存储过程的参数类型主要有三种:`IN`、`OUT` 和 `INOUT`,每种类型在存储过程调用时扮演着不同的角色。

### 1. IN 参数

`IN` 参数是存储过程的输入参数。当调用存储过程时,需要为 `IN` 类型的参数提供值,这些值在存储过程内部被读取,但不可以被修改(即,存储过程内部对这些参数的修改不会影响到存储过程外部)。

**示例**:


DELIMITER //

CREATE PROCEDURE GetEmployeeSalary(IN emp_id INT)
BEGIN
    SELECT salary FROM employees WHERE id = emp_id;
END //

DELIMITER ;

-- 调用存储过程
CALL GetEmployeeSalary(1);

在这个例子中,`emp_id` 是一个 `IN` 类型的参数,用于从 `employees` 表中查询指定ID的员工薪水。

### 2. OUT 参数

`OUT` 参数用于从存储过程向调用者返回数据。在存储过程执行前,不需要为 `OUT` 类型的参数指定值,因为存储过程内部会对其进行赋值。调用者可以通过 `OUT` 参数获取存储过程内部产生的结果。

**示例**:


DELIMITER //

CREATE PROCEDURE GetEmployeeNameByID(IN emp_id INT, OUT emp_name VARCHAR(100))
BEGIN
    SELECT name INTO emp_name FROM employees WHERE id = emp_id;
END //

DELIMITER ;

-- 调用存储过程并获取OUT参数的值
CALL GetEmployeeNameByID(1, @empName);
SELECT @empName;

在这个例子中,`emp_name` 是一个 `OUT` 类型的参数,用于存储从 `employees` 表中查询到的员工名字。

### 3. INOUT 参数

`INOUT` 参数结合了 `IN` 和 `OUT` 参数的特性。它既可以作为输入参数向存储过程传递值,也可以在存储过程内部被修改,并作为输出参数返回给调用者。

**示例**:


DELIMITER //

CREATE PROCEDURE UpdateEmployeeSalary(INOUT emp_id INT, INOUT new_salary DECIMAL(10, 2))
BEGIN
    -- 假设这里有一个复杂的逻辑来决定是否更新薪水
    -- 为了简化,我们直接更新薪水并返回新的ID(实际中可能不需要)
    SET emp_id = emp_id + 1; -- 假设只是为了演示INOUT的使用
    UPDATE employees SET salary = new_salary WHERE id = emp_id;
    -- 注意:实际场景中,更新后可能不会改变emp_id,这里只是为了演示
END //

DELIMITER ;

-- 调用存储过程并准备接收INOUT参数的值
SET @empID = 1;
SET @newSalary = 50000.00;
CALL UpdateEmployeeSalary(@empID, @newSalary);
SELECT @empID, @newSalary; -- 注意:这里的@empID变化仅为了演示,实际中可能不变

在这个例子中,`emp_id` 和 `new_salary` 都是 `INOUT` 类型的参数,它们在存储过程内部被读取并可能被修改,然后返回给调用者。

### 总结

- `IN` 参数用于向存储过程传递数据,数据在存储过程内部被读取但不能被修改。

- `OUT` 参数用于从存储过程返回数据,数据在存储过程执行前不需要被初始化,在存储过程内部被赋值。

- `INOUT` 参数结合了 `IN` 和 `OUT` 的特性,既可以作为输入也可以作为输出。