mysql - MySql 中的存储过程和游标

标签 mysql

我有两个表,Employee 和 Department。它们看起来像这样:

Employee
Name
SSN
DeptID
Salary

Department
DName
DId
Total_Sal

Department.total_sal 是属于该部门的所有员工的工资总和。我需要一个存储过程,利用游标遍历每个员工,并更新相应部门的工资。我以前从未使用过游标或存储过程,我对如何遍历一个表但更新另一个表有点困惑。任何帮助/建议表示赞赏。

另一个简单的问题,我喜欢在 SQLFIDDLE 中完成我所有的 sql 工作,有人知道它是否也支持存储过程/游标吗?

这是我的第一次尝试,我想在开始时也删除 Department.Total_sal 是个好主意吗?

DELIMITER //
DROP PROCEDURE IF EXISTS cur_sal

CREATE PROCEDURE cur_sal
  BEGIN
    DECLARE e_sal, e_dno INT;
    DECLARE d_sal, d_dno INT;
    DECLARE cur_emp CURSOR FOR SELECT salary, DeptId FROM employee;
    DECLARE cur_dep CURSOR FOR SELECT DId, Total_sal FROM department;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur_emp;
    OPEN cur_dep;


    r_loop: LOOP
      FETCH cur_emp INTO e_sal, e_dno;
      FETCH cur_dep INTO d_sal, d_dno;
      IF done THEN
        LEAVE r_loop;
      END IF;

      IF e_dno = d_dno THEN
        UPDATE department SET total_sal = total_sal + e_sal;
      END IF;
    END LOOP;

    CLOSE cur_emp;
    CLOSE cur_dep;
  END //

最佳答案

不需要使用游标来做到这一点。有多种方法可以实现相同的结果,包括连接和子选择。在下面的代码中,我使用了子选择(因为我必须回去工作而且速度很快):

将其放入构建方案部分:

-- create the tables
CREATE TABLE Employee 
    (
    Name varchar(50),
    SSN varchar(50),
    DeptID int,
    Salary float
    );

CREATE TABLE Department 
    (
    DName varchar(50),
    DId int,
    Total_Sal float
    );

-- insert default values
insert into Employee (name,ssn,deptid,salary)
values('Mr Test', '12345a', 1,10000);

insert into Employee (name,ssn,deptid,salary)
values('Mr Tester', '12345b', 1,33000);

-- notice the total_sal is 63000
insert into department (DName, DID, total_sal)
values('Test department',1,63000);

-- now we update the total_sal to be the sum of everyone in that department
update Department 
set total_sal = (SELECT SUM(Salary) FROM employee where employee.DeptID = Department.DID)

在可执行部分运行这个:

select * from department

您会注意到 total_sal 现在是 43000 而不是插入的初始值 63000。

我使用的更新语句会遍历每个部门。

这是 SQLFiddle:SQLFiddle

如果你坚持使用游标,你可以按照以下方式做一些事情:

CREATE PROCEDURE UpdateSalaries()
BEGIN

  -- Cursor Example
  declare DeptID INTEGER;
  declare TotalSalary FLOAT;

  declare SalaryCursor Cursor for select DId, 
    (SELECT SUM(Salary) FROM employee where employee.DeptID = Department.DID) from department

    DECLARE CONTINUE HANDLER 
    FOR NOT FOUND SET finished = 1;

    open SalaryCursor
      FETCH SalaryCursor INTO DeptID, TotalSalary;

    get_Salary: LOOP

      update Department 
      set total_sal = TotalSalary
      WHERE DID = DeptID

    END LOOP get_Salary;

  CLOSE SalaryCursor;
END

关于mysql - MySql 中的存储过程和游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23364461/

相关文章:

MySQL 为每行选择 N 个最接近的邮政编码

php mysqli 错误 mysql_fetch_row()

mysql - "ASDF"中的未知列 'field list' ... 但是 "ASDF"是一个值

mysql - 重命名 NATURAL JOIN 上的属性

java - 在mysql中写入波斯语或阿拉伯语字母

mysql - 使用 Phpmyadmin 中的命令使用定义的值向表结构添加新列

mysql - SELECT 字段 GROUP BY max(field) 和 GROUP BY 其他字段 MySQL

php - 获取正确的总行数和分页行号

PHP-MYSQLI : My login scripts logs direct users into the same page

mysql - 如何在mysql中索引用户名