Sunteți pe pagina 1din 10

Cursori expliciţi

 Atribute cursor
 Cursori cu parametru
 Cursori de tip FOR
 Cursori multipli

Realizaţi blocuri anonime cu următoarele funcţionalităţi

1. Afişaţi salariul mediu al reprezentanţilor de vânzări din cadrul tabelei ANGAJATI


2. Afişaţi numele, prenumele şi salariul reprezentanţilor de vânzări. Se vor utiliza variabile scalare
pentru fiecare element ce trebuie afişat din cadrul fiecărei linii returnate. La finalul listei se va
afişa şi salariul lor mediu
3. Pe exemplul anterior, testaţi toate atributele cursorului – %ISOPEN, %NOTFOUND, %FOUND,
%ROWCOUNT – în etape diferite din ciclul de viaţă al cursorului
4. Rezolvaţi problema de la punctul anterior prin utilizarea variabilelor tip înregistrare
5. Simplificaţi problema folosind cursori de tip FOR
6. Dar dacă nu utilizaţi în mod explicit cursori cu nume, ci folosiţi o subinterogare?
7. Se va rezolva aceeaşi problemă ca la punctul 2, însă denumirea funcţiei (JOB_ID) va fi transmisă
ca parametru. Testaţi funcţionalitatea pentru 2-3 funcţii
8. Modificaţi exemplul anterior prin adăugarea unui nou parametru. Cel de-al doilea (p_vechime)
se referă la vechimea angajaţului la actualul loc de muncă. Astfel, va trebui să afişaţi angajaţii ce
ocupă o anumită funcţie şi au vechime de cel mult valoarea lui p_vechime
9. Cu ajutorul unui cursor cu parametri multipli se va parcurge tabela pentru fiecare funcţie, iar în
cadrul acesteia angajaţii vor fi afişaţi alfabetic după nume, apoi prenume. Începutul unei noi
funcţii va fi marcat vizual corespunzător, la finalul fiecăreia apărând informaţii statistice precum
salariul mediu lunar şi fondul de salarii lunar al fiecărei funcţii. Funcţiile vor fi trecute în ordine
alfabetică
10. Realizaţi un cursor care să permită scădere cu 5% a salariului vânzătorilor, inclusiv a şefului lor.
Rezolvarea trebuie să ţină cont că e posibil să interacţioneze operaţiunile mai multor utilizatori
asupra aceluiaşi set de date. În caz de concurenţă se va aştepta 5 secunde.

 1.      Afişaţi salariul mediu al reprezentanţilor de vânzări din cadrul tabelei ANGAJATI 

  DECLARE

    v_functie angajati.job_id%TYPE:='SA_REP';

    v_salariu_mediu NUMBER(15);

BEGIN
    SELECT AVG(salary) INTO v_salariu_mediu

    FROM angajati

    WHERE job_id =v_functie;

    DBMS_OUTPUT.PUT_LINE(' salariul mediu pentru functia ' || v_functie || ' este '||
v_salariu_mediu);

END;

2.      Afişaţi numele, prenumele şi salariul reprezentanţilor de vânzări. Se vor utiliza variabile scalare
pentru fiecare element ce trebuie afişat din cadrul fiecărei linii returnate. La finalul listei se va
afişa şi salariul lor mediu

DECLARE

   v_functia angajati.job_id%TYPE := 'SA_REP';

   CURSOR angajati_cursor IS

   SELECT first_name, last_name, salary FROM angajati WHERE job_id = v_functia ;

   v_nume angajati.last_name%TYPE;

   v_prenume angajati.first_name%TYPE;

   v_salariu angajati.salary%TYPE;

   v_salariu_mediu NUMBER(10);

BEGIN

   OPEN angajati_cursor;

   LOOP 

     FETCH angajati_cursor INTO v_nume, v_prenume, v_salariu;

     EXIT WHEN angajati_cursor%NOTFOUND;

     DBMS_OUTPUT.PUT_LINE(v_nume || ' ' || v_prenume || ' ' || v_salariu);

   END LOOP;

   CLOSE angajati_cursor;

   SELECT AVG(salary) INTO v_salariu_mediu FROM angajati WHERE job_id = v_functia;

   DBMS_OUTPUT.PUT_LINE('');

   DBMS_OUTPUT.PUT_LINE('Salariul mediu al angajatilor este: ' ||  v_salariu_mediu);


END;

3.      Pe exemplul anterior, testaţi toate atributele cursorului – %ISOPEN, %NOTFOUND, %FOUND,
%ROWCOUNT –  în etape diferite din ciclul de viaţă al cursorului

DECLARE

CURSOR sa_rep_cursor IS

SELECT last_name, first_name

FROM angajati

WHERE job_id = 'SA_REP';

v_nume angajati.last_name%TYPE;

v_prenume angajati.first_name%TYPE;

v_salariu_mediu angajati.salary%TYPE;

BEGIN

SELECT AVG(salary)

INTO v_salariu_mediu FROM angajati

WHERE job_id = 'SA_REP';

IF NOT sa_rep_cursor%ISOPEN THEN

OPEN sa_rep_cursor;

END IF;

LOOP

FETCH sa_rep_cursor INTO v_nume, v_prenume;

EXIT WHEN sa_rep_cursor%NOTFOUND OR sa_rep_cursor%ROWCOUNT > 5;

DBMS_OUTPUT.PUT_LINE('Reprezentant vanzari: ' || v_nume || ' ' || v_prenume);

END LOOP;

CLOSE sa_rep_cursor;

DBMS_OUTPUT.PUT_LINE('Salariul mediu al reprezentantilor de vanzari este ' ||


v_salariu_mediu);
END;

4.      Rezolvaţi problema de la punctul anterior prin utilizarea variabilelor tip înregistrare

DECLARE

 v_salariu_mediu employees.salary%TYPE;

 v_job_id employees.job_id%TYPE := 'SA_REP';

 CURSOR c_employees IS

  SELECT *

  FROM employees

  WHERE job_id = v_job_id;

 v_employees c_employees%ROWTYPE;

BEGIN

OPEN c_employees;

LOOP

 FETCH c_employees INTO v_employees;

 EXIT WHEN c_employees%NOTFOUND;

 DBMS_OUTPUT.PUT_LINE('Nume: ' || v_employees.last_name || ' Prenume: ' ||


v_employees.first_name || ' Salariu: ' || v_employees.salary);

END LOOP;

DBMS_OUTPUT.PUT_LINE('Return ' || c_employees%ROWCOUNT || ' inregistrari.');

CLOSE c_employees;

 SELECT AVG(salary)

 INTO v_salariu_mediu

 FROM employees

 WHERE job_id = v_job_id;

DBMS_OUTPUT.PUT_LINE('Salariul mediu al angajatilor este: ' || v_salariu_mediu);


END;

5.      Simplificaţi problema folosind cursori de tip FOR

DECLARE

   v_functia angajati.job_id%TYPE:='SA_REP';

   v_salar_mediu angajati.salary%TYPE;

   CURSOR c_angajati IS

   SELECT * FROM angajati

   WHERE job_id=v_functia;

BEGIN

   FOR v_angajati IN c_angajati 

   LOOP

   DBMS_OUTPUT.PUT_LINE('Nume: '||v_angajati.last_name||' Prenume: '||v_angajati.first_name||'


Salar: '||v_angajati.salary);

   END LOOP;

   SELECT AVG(salary) INTO v_salar_mediu

   FROM angajati

   WHERE job_id=v_functia;

   DBMS_OUTPUT.PUT_LINE('Salariul mediu al reprezentantilor de vanzari este '||v_salar_mediu);

END;

6.      Dar dacă nu utilizaţi în mod explicit cursori cu nume, ci folosiţi o subinterogare?

DECLARE

v_salariu_mediu angajati.salary%TYPE;

v_functie angajati.job_id%TYPE := 'SA_REP';

BEGIN
SELECT AVG(salary)

INTO v_salariu_mediu FROM angajati

WHERE job_id = v_functie;

FOR v_angajati_record IN (SELECT last_name, first_name, salary

FROM angajati WHERE job_id = v_functie)

LOOP

DBMS_OUTPUT.PUT_LINE(v_angajati_record.last_name || ' ' || v_angajati_record.first_name ||


' are salariul: ' ||  v_angajati_record.salary);

END LOOP;

DBMS_OUTPUT.PUT_LINE('Salariul mediu pentru ' || v_functie || ‘ este ‘  || v_salariu_mediu);

END;

7.      Se va rezolva aceeaşi problemă ca la punctul 2, însă denumirea funcţiei (JOB_ID) va fi


transmisă ca parametru. Testaţi funcţionalitatea pentru 2-3 funcţii

DECLARE

v_median_wage employees.salary%TYPE;

v_job_id employees.job_id%TYPE:='SA_REP';

CURSOR c_employees(p_job_id employees.job_id%TYPE) IS 

SELECT * FROM employees

WHERE job_id=p_job_id;

BEGIN 

FOR v_employees IN c_employees(v_job_id) LOOP

DBMS_OUTPUT.PUT_LINE('Numele angajatului este:'||v_employees.last_name||' '||


v_employees.first_name||', iar salariul sau este '||v_employees.salary);

END LOOP;
SELECT AVG(salary) INTO v_median_wage FROM employees

WHERE job_id=v_job_id;

DBMS_OUTPUT.PUT_LINE('Salariul mediu este:'||v_median_wage);

END;

8.      Modificaţi exemplul anterior prin adăugarea unui nou parametru. Cel de-al doilea (p_vechime)
se referă la vechimea angajaţului la actualul loc de muncă. Astfel, va trebui să afişaţi angajaţii
ce ocupă o anumită funcţie şi au vechime de cel mult valoarea lui p_vechime (ex. 7 ani)

DECLARE

     CURSOR rep_vanzari(id_job angajati.JOB_ID%TYPE, p_vechime NUMBER) IS

       SELECT first_name, last_name, salary

       FROM angajati

       WHERE job_id = id_job AND ((sysdate-hire_date)/365 <= p_vechime); 

     salariu_mediu NUMBER(8,2); 

     v_first_name angajati.first_name%TYPE;

     v_last_name angajati.last_name%TYPE;

     v_salary angajati.salary%TYPE;

     v_function angajati.JOB_ID%TYPE := 'SA_REP';

BEGIN

     SELECT AVG(SALARY)

     INTO salariu_mediu

     FROM angajati

     WHERE JOB_ID = v_function;

     OPEN rep_vanzari('SA_REP', 10);

     LOOP

       FETCH rep_vanzari INTO v_first_name, v_last_name, v_salary;


       EXIT WHEN rep_vanzari%NOTFOUND;

DBMS_OUTPUT.PUT_LINE('Angajatul ' || v_first_name || ' ' || v_last_name || ' are un salariu de ' ||
v_salary || ', media este de: '  || salariu_mediu || ' si ocupa functia de ' || v_function );

     END LOOP;

     CLOSE rep_vanzari;

9.      Cu ajutorul unui cursor multiplu se va parcurge tabela pentru fiecare funcţie, iar în cadrul
acesteia angajaţii vor fi afişaţi alfabetic după nume, apoi prenume. Începutul unei noi funcţii va fi
marcat vizual corespunzător, la finalul fiecăreia apărând informaţii statistice precum salariul
mediu lunar şi fondul de salarii lunar al fiecărei funcţii. Funcţiile vor fi trecute în ordine alfabetică

DECLARE 
  CURSOR fct_cursor IS select distinct job_id from angajati order by 1;
  CURSOR ang_cursor (p_functie VARCHAR2) IS select * from angajati order by last_name,
first_name;
  v_sal NUMBER(9,2);
  v_nr INT;
BEGIN
  FOR v_fct IN fct_cursor
  LOOP
    DBMS_OUTPUT.PUT_LINE('---'||v_fct.job_id);
      v_nr:=0;
      v_sal:=0;
    FOR v_ang in ang_cursor(v_fct.job_id)
       LOOP
      v_nr:=v_nr+1;
      v_sal:=v_sal+v_ang.salary;
      DBMS_OUTPUT.PUT_LINE(v_nr||'. '||v_ang.last_name || ' '|| v_ang.first_name||': '||
v_ang.salary);
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Salariu mediu: '||ROUND(v_sal/v_nr,2));
  END LOOP;
END;

10.   Realizaţi un cursor care să permită scădere cu 5% a salariului vânzătorilor, inclusiv a şefului
lor. Rezolvarea trebuie să ţină cont că e posibil să interacţioneze operaţiunile mai multor
utilizatori asupra aceluiaşi set de date. În caz de concurenţă se va aştepta 5 secunde.

SELECT first_name, last_name, salary FROM angajati

      WHERE job_id LIKE 'SA_%';

DECLARE

 v_salary angajati.salary%TYPE;

  CURSOR sal_cursor IS
    SELECT salary FROM angajati

      WHERE job_id LIKE 'SA_%' FOR UPDATE OF salary WAIT 5;

BEGIN

   OPEN sal_cursor;

   LOOP

       FETCH sal_cursor INTO v_salary;

            EXIT WHEN sal_cursor%NOTFOUND;

         UPDATE angajati SET salary = v_salary*.95

         WHERE CURRENT OF sal_cursor;

     END LOOP;

     CLOSE sal_cursor;

 END;

SAU MAI FRUMOS

DECLARE

  CURSOR vanzatori_cursor IS

    SELECT first_name, last_name, salary FROM angajati

      WHERE job_id LIKE 'SA_%' FOR UPDATE OF salary WAIT 5;

      rec_vanzatori vanzatori_cursor%ROWTYPE;

BEGIN

   OPEN vanzatori_cursor;

   LOOP

       FETCH vanzatori_cursor INTO rec_vanzatori;

            EXIT WHEN vanzatori_cursor%NOTFOUND;

         UPDATE angajati SET salary = rec_vanzatori.salary*.95

         WHERE CURRENT OF vanzatori_cursor;


       DBMS_OUTPUT.PUT_LINE(vanzatori_cursor%ROWCOUNT ||'. Angajatul '||
rec_vanzatori.first_name ||' ' || rec_vanzatori.last_name ||' cu salariul de '||rec_vanzatori.salary||'
are acum '||rec_vanzatori.salary*.95);

     END LOOP;

     CLOSE vanzatori_cursor;

 END;

S-ar putea să vă placă și