2017-10-13 17 views
1

Pour ce problème, j'ai besoin d'augmenter les employés.salaire de 20% en commençant par les salaires les plus bas (ordre asc) jusqu'à 100 000 $ est épuisé. J'ai de la difficulté à trouver une solution pour économiser le montant mis à jour jusqu'à 100 000 $. C'est ce que j'ai jusqu'ici. MerciOracle SQL Cursor pour augmenter les salaires jusqu'à ce que le montant maximum soit atteint

declare 
cursor mancur is 
    select salary from employees order by salary asc; 
tempcur  mancur%ROWTYPE; 
profits  number := 100000; 
tempsalary employees.salary%type; 
tempinc  number(8,2); 
begin 
open mancur; 
loop 
    fetch mancur into tempcur; 
    tempinc := tempcur.salary * 1.20; 
    tempsalary := profits - tempcur.salary; 
    dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || tempsalary); 
    exit when mancur%notfound; --when 100,000 has been used 
    --update employees set salary = salary * 1.20 where employee_id = tempcur.employee_id; 
end loop; 
close mancur; 
end; 
/
+0

Est-ce un problème de production ou un problème de devoirs? Si c'est un devoir, est-ce pour un cours PL/SQL? Cette exigence peut être résolue beaucoup plus efficacement avec une seule instruction SQL. – mathguy

+2

Aussi, comment gérez-vous les cravates? Supposons que vous ayez gravi la liste, et maintenant les prochains employés (dont le salaire n'a pas encore été augmenté) sont TROIS employés avec le même salaire. Leur salaire actuel est de 30 000 $ chacun, alors ils devraient recevoir 6 000 $ chacun, mais il ne reste plus que 12 000 $. Qui obtient combien? – mathguy

Répondre

1
begin 
open mancur; 
    loop 
    fetch mancur into tempcur; 
    tempinc := tempcur.salary * 1.20; 
    profits := profits - (tempinc-tempcur.salary); -- You have to keep subtracting the increment amount to find if bonus is exhausted or not 
     if profits <=0 Then --When all your funds are exhausted 
     Exit 
     End if 
       dbms_output.put_line(tempcur.salary || ' increased by 20% ' || tempinc || ', Bonus amount left ' || profits); 
     exit when mancur%notfound; --when 100,000 has been used 
    --update employees set salary = salary * 1.20 where employee_id = 
     tempcur.employee_id; 
    end loop; 
close mancur; 
end; 
/
+0

Merci! Idk comment je ne pouvais pas obtenir ça. Il est temps de faire une pause à l'écran – namesjj

0
declare 
profits  number := 100000; 
tempinc  number(8,2); 
begin 
for hike_loop in (select employee_id,salary from employees order by salary asc) loop 
if profits <= 0 then 
break; 
end if; 
tempinc := hike_loop.salary * 0.20; 
if (tempinc <= profits) then 
update employees set salary = salary * 1.20 where employee_id = hike_loop.employee_id; 
profits := profits - tempinc; 
else 
break; 
end if; 
end loop; 
end; 
/
0

Juste pour le plaisir: voici comment cela devrait se faire en SQL. Il n'y a pas besoin de fonctions ou de procédures pour cette tâche, à moins qu'il ne s'agisse de devoirs dans une classe PL/SQL. Et même dans ce cas, la même instruction MERGE doit être exécutée à partir du code PL/SQL, de sorte que le traitement soit effectué au niveau défini, pas ligne par ligne.

Cela résout également pour le "petit montant restant" différemment des solutions postées jusqu'à présent. S'il n'y en a pas assez pour augmenter le «dernier» salaire de 20%, il est augmenté, mais il reste jusqu'à 100 000 $. Et si deux employés ou plus avec le même salaire sont «les premiers à être exclus», alors le «montant restant» est divisé également entre ces employés.

merge into employees e 
    using (select employee_id, 
       sum (salary) over (order by salary)  as sum_salary, 
       count(salary) over (partition by salary) as cnt 
      from employees 
     ) x 
    on (e.employee_id = x.employee_id) 
when matched then update 
    set salary = 1.2 * salary + case when sum_salary <= 100000/0.2 then 0 
            else (100000 - 0.2 * sum_salary)/cnt end 
    where sum_salary - cnt * salary <= 100000/0.2 
;