GBSE存储过程

假设我们有一个员工表employees,包含字段employee_id(员工ID)、employee_name(员工姓名)、salary(工资)和department(部门)。现在我们希望创建一个存储过程,根据输入的部门名称,计算每个部门的平均工资

CREATE PROCEDURE calculate_average_salary(IN dept_name VARCHAR(255), OUT avg_salary DECIMAL(10, 2))
BEGIN
  DECLARE total_salary DECIMAL(10, 2) DEFAULT 0;
  DECLARE emp_count INT DEFAULT 0;
  DECLARE done INT DEFAULT 0;
  DECLARE cur CURSOR FOR SELECT salary FROM employees WHERE department = dept_name;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur;

  read_loop: LOOP
    FETCH cur INTO total_salary;

    IF done THEN
      LEAVE read_loop;
    END IF;

    SET emp_count = emp_count + 1;
    SET total_salary = total_salary + salary;
  END LOOP;

  CLOSE cur;

  IF emp_count > 0 THEN
    SET avg_salary = total_salary / emp_count;
  ELSE
    SET avg_salary = 0;
  END IF;
END;

在这个示例中,我们创建了一个名为calculate_average_salary的存储过程。这个过程接收一个输入参数dept_name(部门名称),并返回一个输出参数avg_salary(平均工资)。存储过程中使用了以下控制结构:

声明变量:用于存储计算过程中的中间值。
声明游标:用于遍历满足条件的员工记录。
声明处理器:用于处理游标读取结束的情况。
循环结构:遍历满足条件的员工记录,并计算总工资和员工数量。
条件结构:根据员工数量计算平均工资,避免除数为零的情况。
要调用这个存储过程,可以使用以下语句:

DECLARE @average_salary DECIMAL(10, 2);
CALL calculate_average_salary('IT', @average_salary);
SELECT @average_salary;

下面就是详细解释每句话

创建存储过程:

CREATE PROCEDURE calculate_average_salary(IN dept_name VARCHAR(255), OUT avg_salary DECIMAL(10, 2))
BEGIN

这部分代码定义了存储过程的名称calculate_average_salary,并声明了两个参数:输入参数dept_name和输出参数avg_salary。

声明变量:

DECLARE total_salary DECIMAL(10, 2) DEFAULT 0;
DECLARE emp_count INT DEFAULT 0;
DECLARE done INT DEFAULT 0;

这部分代码声明了三个变量:total_salary用于存储部门的总工资,emp_count用于存储员工数量,done用于标记游标读取结束。

声明游标:

DECLARE cur CURSOR FOR SELECT salary FROM employees WHERE department = dept_name;

这部分代码声明了一个游标cur,用于遍历员工表employees中属于指定部门(dept_name)的记录。

声明处理器:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

这部分代码声明了一个处理器,用于处理游标读取结束的情况。当游标没有更多记录时,将done变量设置为1。

打开游标:

OPEN cur;

这部分代码打开游标,准备开始读取记录。

循环结构:

read_loop: LOOP
    FETCH cur INTO total_salary;

    IF done THEN
      LEAVE read_loop;
    END IF;

    SET emp_count = emp_count + 1;
    SET total_salary = total_salary + salary;
  END LOOP;

这部分代码使用LOOP循环结构遍历满足条件的员工记录。FETCH语句用于从游标中获取当前记录的salary字段值,并将其累加到total_salary变量中。emp_count变量用于统计员工数量。

当游标读取结束时,done变量被设置为1,循环将跳出。

关闭游标:

CLOSE cur;

这部分代码关闭游标,释放相关资源。

计算平均工资:

IF emp_count > 0 THEN
    SET avg_salary = total_salary / emp_count;
ELSE
    SET avg_salary = 0;
END IF;

这部分代码使用IF条件结构判断是否有员工记录。如果员工数量大于0,则计算平均工资(总工资除以员工数量),否则将平均工资设置为0。

结束存储过程:

END;

这部分代码表示存储过程的结束。