MySql中的存储过程和游标

MySql中的存储过程和游标,mysql,Mysql,我有两张桌子,员工桌和部门桌。他们看起来是这样的: Employee Name SSN DeptID Salary Department DName DId Total_Sal Department.total_sal是属于该部门的所有员工工资的总和。我需要一个存储过程,它利用游标遍历每个员工,并更新相应部门的工资。我以前从未使用过游标或存储过程,我对如何遍历一个表而更新另一个表感到有点困惑。欢迎提供任何帮助/建议 另一个简短的问题是,我喜欢用SQLFIDLE完成所有sql工作,有人知道它是

我有两张桌子,员工桌和部门桌。他们看起来是这样的:

Employee
Name
SSN
DeptID
Salary

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

另一个简短的问题是,我喜欢用SQLFIDLE完成所有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
您会注意到,现在的总值是43000,而不是插入的初始值63000

我使用的update语句将遍历每个部门

以下是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

没有必要使用游标来执行此操作。实现相同结果的方法有多种,包括联接和子选择。在下面的代码中,我使用了一个子选择(因为我必须回去工作,而且速度很快):

将其放入“生成方案”部分:

-- 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
您会注意到,现在的总值是43000,而不是插入的初始值63000

我使用的update语句将遍历每个部门

以下是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

没有必要使用游标来执行此操作。实现相同结果的方法有多种,包括联接和子选择。在下面的代码中,我使用了一个子选择(因为我必须回去工作,而且速度很快):

将其放入“生成方案”部分:

-- 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
您会注意到,现在的总值是43000,而不是插入的初始值63000

我使用的update语句将遍历每个部门

以下是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

没有必要使用游标来执行此操作。实现相同结果的方法有多种,包括联接和子选择。在下面的代码中,我使用了一个子选择(因为我必须回去工作,而且速度很快):

将其放入“生成方案”部分:

-- 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
您会注意到,现在的总值是43000,而不是插入的初始值63000

我使用的update语句将遍历每个部门

以下是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
在这里,我认为您非常接近,您希望使用一个临时变量来保存所有事务的总和,直到到达循环的末尾。当你到达终点时,你用你的总结值更新部门工资。我刚刚用了sum_sal

Update语句需要一个where子句,您的游标基本上会充满您需要的值

在这里,我认为您非常接近,您希望使用一个临时变量来保存所有事务的总和,直到到达循环的末尾。当你到达终点时,你用你的总结值更新部门工资。我刚刚用了sum_sal

Update语句需要一个where子句,您的游标基本上会充满您需要的值

在这里,我认为您非常接近,您希望使用一个临时变量来保存所有事务的总和,直到到达循环的末尾。当你到达终点时,你用你的总结值更新部门工资。我刚刚用了sum_sal

Update语句需要一个where子句,您的游标基本上会充满您需要的值

在这里,我认为您非常接近,您希望使用一个临时变量来保存所有事务的总和,直到到达循环的末尾。当你到达终点时,你用你的总结值更新部门工资。我刚刚用了sum_sal



Update语句需要一个where子句,您的游标基本上将充满您需要的值

您需要显示您首先尝试的内容为什么要使用游标进行迭代?带有联接的单个更新查询可以满足您的需要。您需要显示您首先尝试的内容为什么要使用光标进行迭代?带有联接的单个更新查询可以满足您的需要。您需要显示您首先尝试的内容为什么要使用光标进行迭代?带有联接的单个更新查询可以满足您的需要。您需要显示您首先尝试的内容为什么要使用光标进行迭代?一个带有连接的更新查询可以满足您的需要。PaulG,谢谢您的建议。我知道在这里有更容易和更有效的方法来实现这一目标。但是,我的任务是专门使用存储过程/游标来完成这项工作lol@Hituptony是的,我知道游标效率很低,但是我在这项作业中没有选择。PaulG,谢谢你的建议。我知道在这里有更容易和更有效的方法来实现这一目标。但是,我的任务是专门使用存储过程/游标来完成它