Bon pour fêter mon inscription sur le forum et comme je me suis amusé à écrire tout ça,je le poste, même si le sujet est marqué comme résolu.
Alors comme je n'ai pas de noyau Oracle sur place, je n'ai pas testé, même pas la syntaxe, mais ça peut donner une idée; ça devrait quand même pas être trop faux, le PL c'est mon métier, même si je ne manipule pas très souvent certaines notions comme les varray utilisés ici.
set serveroutput on -- enable dbms_output
define n=5
declare
cursor csr_top_emp is
select ename, sal from emp order by sal desc;
type top_type is varray(&n) of csr_top_emp%ROWTYPE;
top_tab top_type;
top_idx pls_integer;
idx pls_integer;
prev_sal emp.sal%TYPE := -1;
exists_same_sal boolean := FALSE;
ex_n_to_low exception;
begin
top_idx := 0;
if &n <= 0 then
raise ex_n_to_low;
end if;
-- Parcours des employés par salaire décroissant
for csr_rec in csr loop
top_idx := top_idx + 1;
-- Détection salaires identiques
if csr_rec.sal = prev_sal then
exists_same_sal := TRUE;
end if;
prev_sal := csr_rec.sal;
-- collecte des top n
if top_idx <= &n then
top_tab(top_idx) := csr_rec;
end if;
end loop;
-- Affichage de la table des n top salaires
DBMS_OUTPUT.put_line(rpad('Employé', 30)||' '||lpad('Salaire', 12));
DBMS_OUTPUT.put_line(rpad(null, 30, '-')||' '||lpad(null, 12, '-'));
for idx in 1 .. top_idx loop
DBMS_OUTPUT.put_line(rpad(top_tab.ename, 30)||' '||lpad(top_tab.sal, 12));
end loop;
-- Affichage Warning si nombre demandé trop grand
if top_idx <= &n then
DBMS_OUTPUT.put_line('WARNING: Le nombre d''employés est inférieur au nombre demandé');
end if;
-- Affichage Warning si existe salaires identiques
if exists_same_sal = TRUE then
DBMS_OUTPUT.put_line('WARNING: Des employés ont un salaire identique');
end if;
exception
when ex_n_to_low then
DBMS_OUTPUT.put_line('ERROR: Le nombre d''employés demandé ne peut être négatif');
end;
/