我有两个表,员工和部门。他们看起来像这样:
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 //
答案 0 :(得分:2)
没有必要使用游标来执行此操作。有多种方法可以实现相同的结果,包括连接和子选择。在下面的代码中,我使用了一个子选择(因为我必须回去工作并且很快):
将其放入Build Scheme部分:
-- 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
答案 1 :(得分:1)
CREATE PROCEDURE cur_sal
BEGIN
DECLARE e_sal, e_dno INT;
DECLARE sum_sal INT
DECLARE d_sal, d_dno INT;
DECLARE cur_emp CURSOR FOR SELECT salary, Dno FROM employee;
DECLARE cur_dep CURSOR FOR SELECT Dno, 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
SET sum_sal = sum_sal + e_sal;
END IF;
END LOOP;
UPDATE department SET total_sal = sum_sal where DId = Dno;
CLOSE cur_emp;
CLOSE cur_dep;
END //
这里你非常接近我认为,你想使用一个临时变量来保存所有事务的总和,直到你到达循环结束。当您到达最后时,您将使用总计值更新部门薪资。我刚刚使用了sum_sal。
更新语句需要一个where子句,你基本上会把你的光标充满你的
答案 2 :(得分:0)
您可以从中获得帮助: