1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
/* TABLAS empleados y departamentos (script cargatablas1.sql) Ejercicio 20: Escribir un procedimiento que suba el sueldo de todos los empleados que ganen menos que el salario medio de su oficio. La subida será del 50% de la diferencia entre el salario del empleado y la media de su oficio. La transacción no deberá quedarse a medias. */ delimiter $$ drop procedure if exists 1x20 $$ create procedure 1x20() begin declare id int; declare ofi1, ofi2 tinytext; declare sal, med, aumento double; declare finCursor boolean default false; declare transaccionOk boolean default true; -- Se guarda en un cursor el oficio y la media de sueldos de los empleados. -- Y en otro el id del empleado y su oficio: declare c_oficios cursor for select oficio, avg(salario) as media from empleados group by oficio order by oficio; declare c_empleados cursor for select emp_no, oficio, salario from empleados order by oficio; -- Si hay un error en la lectura el testigo se podra a true: declare continue handler for not found set finCursor = true; -- Se comienza una transacción: start transaction; -- Se abre y se hace la primera lectura de los Cursores: open c_oficios; open c_empleados; fetch c_oficios into ofi1, med; fetch c_empleados into id, ofi2, sal; while finCursor = false do -- Como ambos Cursores tienen ordenados sus campos por oficio, se leeran tantos usuarios iguales al oficio actual -- cuando dejen de coincidir terminara el while2 y se leera un nuevo oficio de c_oficios para tratar los siguientes empleados con ese oficio. while ofi1 like ofi2 && finCursor = false do set aumento = if( sal < med, (med-sal)/2+sal, sal ); update empleados set salario = aumento where emp_no = id; if truncate((select salario from empleados where emp_no = id),0) != truncate(aumento,0) then set transaccionOk = false; end if; fetch c_empleados into id, ofi2, sal; -- Se recoge un nuevo empleado. end while; fetch c_oficios into ofi1, med; -- Se recoge un nuevo oficio. end while; close c_oficios; close c_empleados; if transaccionOk = true then commit; select 'Salarios actualizados correctamente'; else rollback; select 'Error en la actualizacion de los salarios'; end if; end $$ delimiter ; -- call 1x20; |