MySql Процедура расчета бонуса Обновление всей таблицы - PullRequest
0 голосов
/ 09 декабря 2018

Попытка написать простую процедуру в MySQL для расчета бонуса на основе идентификатора отдела.Вот что я делаюПроблема в том, что когда я назначаю своей процедуре определенный идентификатор отдела, он обновляет зарплату для всей таблицы с тем же значением зарплаты, а не ограничивается указанным идентификатором отдела.Потратил на это много времени, но не смог разобраться в проблеме.

create table employees(emp_id integer,dept_id int(4),emp_name varchar(10), salary float(11));
alter table employees add primary key (emp_id);
insert into employees values(1, 1,'A1',30);
insert into employees values(2, 2,'R1', 40);
insert into employees values(3, 3,'A2', 50);
insert into employees values(4, 4,'S1', 60);
insert into employees values(5, 1,'A3', 700);


delimiter $$
create procedure calculate_bonus(in in_dept_id int)
begin
declare done int default false;
declare emp_id integer;
declare dept_id int(4);
declare emp_name varchar(10); 
declare new_salary float(11);
declare hike float(11);
declare c1 cursor for
select * from employees;
Declare continue handler for not found set done = TRUE;

open c1;
read_cursor: LOOP
fetch c1 into emp_id, dept_id, emp_name, new_salary;
if done then
leave read_cursor;
end if;


if(dept_id = in_dept_id) then
select case dept_id
when 1 then 10
when 2 then 20
when 3 then 30
else 40
end
into hike;

set new_salary = new_salary + (new_salary*hike/100);
select concat("salary",new_salary);

update employees
set salary = new_salary where dept_id = in_dept_id;
select concat("dept_id",dept_id, in_dept_id);
end if;
end LOOP read_cursor;
close c1;
end
$$

call calculate_bonus(3);
select * from employees;

Вывод, который я получаю:

salary65
dept_id33
1   1   A1  65
2   2   R1  65
3   3   A2  65
4   4   S1  65
5   1   A2  65

1 Ответ

0 голосов
/ 10 декабря 2018
DROP TABLE IF EXISTS T;
create table t(emp_id integer,dept_id int(4),emp_name varchar(10), salary float(11));
alter table t add primary key (emp_id);
insert into t values(1, 1,'A1',30);
insert into t values(2, 2,'R1', 40);
insert into t values(3, 3,'A2', 50);
insert into t values(4, 4,'S1', 60);
insert into t values(5, 1,'A3', 700);

drop procedure if exists p;
delimiter $$

create procedure p(in in_dept_id int)
begin
declare done int default false;
declare vemp_id integer;
declare vdept_id int(4);
declare vemp_name varchar(10); 
declare vnew_salary float(11);
declare vhike float(11);
declare c1 cursor for select * from t where dept_id = in_dept_id;
Declare continue handler for not found set done = TRUE;

open c1;
read_cursor: LOOP
fetch c1 into vemp_id, vdept_id, vemp_name, vnew_salary;
if done then
    leave read_cursor;
end if;


select case vdept_id
    when 1 then 10
    when 2 then 20
    when 3 then 30
    else 40
    end
    into vhike;

    set vnew_salary = vnew_salary + (vnew_salary*vhike/100);
    select concat("salary",vnew_salary);

    update t
        set salary = vnew_salary where dept_id = in_dept_id;
    select concat("dept_id",vdept_id, in_dept_id);


end LOOP read_cursor;
close c1;
end $$

call p(3);
call p(1);
select * from t;

+--------+---------+----------+--------+
| emp_id | dept_id | emp_name | salary |
+--------+---------+----------+--------+
|      1 |       1 | A1       |     33 |
|      2 |       2 | R1       |     40 |
|      3 |       3 | A2       |     65 |
|      4 |       4 | S1       |     60 |
|      5 |       1 | A3       |    770 |
+--------+---------+----------+--------+
5 rows in set (0.00 sec)

Примечание. Я назвал объявленные переменные уникальным образом, изменил курсор, чтобы выбрать только интересующий меня dept_id, удалил теперь избыточный оператор if и уточнил оператор обновления для идентификатора сотрудника.Процедура (возможно) и курсор (определенно) не нужны (если вам специально не было сказано сделать это таким образом), и тот же результат может быть достигнут с помощью одного оператора обновления, например

update t
    set salary = salary + (salary * case dept_id
            when 1 then 10
            when 2 then 20
            when 3 then 30
            else 40
            end / 100)
        where dept_id = 3;

Спростое изменение для принятия значения параметра вместо жестко заданного кода 3 - это весь код, который вам понадобится в вашей процедуре.

...