0% found this document useful (0 votes)
60 views22 pages

GSBD Oracle SQL

The document provides examples of using the "group by" clause in SQL to analyze employee data from a company database. It includes queries to: 1) Find the minimum and maximum salaries and range for each department and job; 2) Count the number of managers; 3) Identify departments with less than 5 employees; 4) Determine the department with the highest average salary. Additional queries calculate location-based salaries, rankings, and averages for managers' teams.

Uploaded by

Andreea Asanache
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views22 pages

GSBD Oracle SQL

The document provides examples of using the "group by" clause in SQL to analyze employee data from a company database. It includes queries to: 1) Find the minimum and maximum salaries and range for each department and job; 2) Count the number of managers; 3) Identify departments with less than 5 employees; 4) Determine the department with the highest average salary. Additional queries calculate location-based salaries, rankings, and averages for managers' teams.

Uploaded by

Andreea Asanache
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 22

Exemple "group by"

--1. diferenta intre salariukl minim si max pe fiecare departament in parte


--2. diferenta intre salariukl minim si max pe fiecare job in parte
--2B. diferenta intre salariukl minim si max pe fiecare job in parte + pe fiecare
departament in parte
--3. citi manageri avem
--4. departamentele cu mai putin de 5 angajati
--5. departamentul cu cel mai mare salariu mediu
--6. salariul mediu pe fiecare locatie in parte
--7. locatiile care au salariul minim >= 3500
--8. sal.mediu pt departamentle ecu cel putin 5 angajati
--9. sal.mediu pt angajatii fiecarui manager - de afisat nume manager, nr angajati
sal.mediu

--1
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta,
e.department_id, d.department_name
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
order by 3 desc
;

--2
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta, j.job_id,
j.job_title
from employees e inner join jobs j on e.job_id = j.job_id
group by j.job_id, j.job_title
order by 3 desc
;

--2B
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta, j.job_title,
d.department_name
from employees e inner join jobs j on e.job_id = j.job_id
inner join departments d on e.department_id = d.department_id
group by j.job_title, d.department_name
order by 3 desc
;

--3.
SELECT
COUNT(e.employee_id)
FROM
employees e
INNER JOIN jobs j ON e.job_id = j.job_id
WHERE
j.job_title LIKE '%Manager%';

--4.
select d.department_name, count(e.employee_id)
from employees e inner join departments d on e.department_id = d.department_id
group by d.department_name
having count(e.employee_id) <= 5
order by 2 desc;

--5.
select d.department_name, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
order by 2 desc;

select * from (
select d.department_name, round(avg(salary),2), rank() over(order by avg(salary)
desc) AS PozitieClasament
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
)
where PozitieClasament <= 3;

--6
select l.city, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
inner join locations l on d.location_id = l.location_id
group by l.city;

--7
select l.city, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
inner join locations l on d.location_id = l.location_id
group by l.city
having avg(salary)>=3500
order by 2 desc;

--8
select d.department_name, round(avg(salary),2), count(employee_id)
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
having count(employee_id) >= 5
order by 2 desc;

--9
select sef.employee_id, sef.first_name || ' ' || sef.last_name,
count(ang.employee_id) nrAngajati, round(avg(ang.salary),2) salMediu
from employees ang inner join employees sef on ang.manager_id = sef.employee_id
group by sef.employee_id,sef.first_name || ' ' || sef.last_name
order by salMediu desc
;
--verificare
select avg(salary) from employees where manager_id=100;
Group by - 2 + diverse ranking
--persoanele care au fost angajate inaintea sefului lor
select ang.last_name, ang.hire_date, sef.last_name, sef.hire_date
from employees ang inner join employees sef
on ang.manager_id = sef.employee_id
where ang.hire_date < sef.hire_date;

--departamentele care nu au angajati folosind union/intersect/minus


select * from (
select department_id from departments --toate
minus
select distinct department_id from employees where department_id is not null
--cele care au angajati
) dfa inner join departments d on dfa.department_id = d.department_id;

--daca exista job_id comun in departamentele 80,90,100 = intersectie


select job_id from employees where department_id = 80
intersect
select job_id from employees where department_id = 30
intersect
select job_id from employees where department_id = 100;

--departamentele in care exista sefi care au mai mult de 5 angajati

select distinct department_id --, manager_id, count(*) nrAng1, count(employee_id)


nrang2, count(department_id) nrang3 --atentie la numarat valori null-e pentru
"nrang3"
from employees
group by department_id, manager_id
having count(*)>5
order by 1;

--lunile si anii in care s-au angajat mai mult de 5 persoane in organizatia mea
select to_char(hire_date, 'MON-YYYY') LunaSiAn, count(*) NrAngInLunaAn
from employees
group by to_char(hire_date, 'MON-YYYY')
having count(*) > 5;

--care sint departamentle care au cel putin 5 angcare au comision din vinzari
select department_id, count(*) nr_ang, count(commission_pct) nr_ang_cu_comision
from employees
group by department_id
having count(commission_pct)>=5;

--afisam cel mai mare al doilea salariu din organizatie


select distinct salary from (
select employee_id, salary
, rank() over(order by salary desc) rnk_sal
, dense_rank() over(order by salary desc) den_rnk_sal
from employees
) where den_rnk_sal =2;

----select salary, count(salary) from employees group by salary order by salary desc
-- avem nevoie de sub-interogare corelata cu parintele

--

Functii pentru Ranking si Windowing


1. Ranking functions calculate ranks, percentiles, and n-tiles (for example, tertiles,
quartiles).
2. Inverse percentile functions calculate the value that corresponds to a percentile.
3. Window functions calculate cumulative and moving aggregates.
4. Reporting functions calculate things like market shares.
5. Lag and lead functions get a value in a row where that row is a certain number of rows
away from the current row.
6. First and last functions get the first and last values in an ordered group.
7. Linear regression functions fit an ordinary-least-squares regression line to a set of number
pairs.
8. Hypothetical rank and distribution functions calculate the rank and percentile that a new
row would have if you inserted it into a table.

Detalii

 http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.1+Analytic+SQL+Overview/
 http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.2+Ranking+Functions/
 http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.3+Windowing+Functions/
 http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.4+Reporting+Functions/
 https://blogs.oracle.com/oraclemagazine/a-window-into-the-world-of-analytic-functions

 http://www.java2s.com/Tutorial/Oracle/0320__Analytical-
Functions/Catalog0320__Analytical-Functions.htm
 http://www.vertabelo.com/blog/technical-articles/oracle-sql-analytical-functions-for-
beginners-a-gentle-introduction-to-common-sql-window-functions
 https://www.blendo.co/blog/sql-window-functions/

Exemple ranking si windowing – 1


--select cimp1, cimp2, ....
-- Rank() over(order by ....)
-- dense_rank() over(order by ....)
-- row_number() over( order by....)
--from t.....
--where...
--group by,....

select last_name, salary,department_id,


Rank() over(order by salary) rnk,
dense_rank() over(order by salary) d_rnk,
row_number() over( order by salary) rn,

Rank() over(partition by department_id order by salary) p_did_rnk,


dense_rank() over(partition by department_id order by salary) p_did_d_rnk,
row_number() over(partition by department_id order by salary) p_did_rn
,Rank() over(partition by department_id order by salary) p_did_rnk_avg

,sum(salary) over (partition by department_id order by salary) sum_sal_p_did


,round(avg(salary) over (partition by department_id order by salary))
sum_sal_p_did
from employees
order by department_id
;

--1. angajatii cu cel mai mic salariu din fiecare departament


select * from (
select last_name, salary, department_id,
Rank() over(partition by department_id order by salary desc) p_did_rnk
from employees
order by department_id
)
where p_did_rnk <= 3;

-- angajatii care cistiga cell mai mare salariu pentru fiecare tip de functie

select * from (
select last_name, salary, job_id,department_id,
rank() over(partition by job_id order by salary desc) j_rnk
from employees
order by job_id
)
where j_rnk = 1;

--Gasiti angajatii care cistiga salariul minim pentru functia lor


select * from (
select last_name, salary, job_id,department_id,
rank() over(partition by job_id order by salary) j_rnk
from employees
order by job_id
)
where j_rnk = 1;
--Gasiti cei mai recenti angajati din fiecare departament
select * from (
select last_name, hire_date, department_id,
rank() over(partition by department_id order by hire_date desc) j_rnk
from employees
--order by job_id
)
where j_rnk = 1
order by hire_date desc;

--angajat care cistiga un salariu mai mare ca media pentru departamentul lor
select * from (
select last_name, salary, department_id
, round(avg(salary) over (partition by department_id)) medie_sal_dep
, round(median(salary) over (partition by department_id)) mediana_sal_dep
from employees
) where salary > medie_sal_dep;

---departamentul cu cel mai mare total al salariilor


select * from (
select department_id, tot_sal,
rank() over(order by tot_sal desc) rnk
,row_number() over(order by tot_sal desc) nrCrt
from
(
select department_id, last_name,
sum(salary) over(partition by department_id) tot_sal
from employees
) x
order by tot_sal desc
)
where nrCrt = 1;

---In ce an s-au angajat cei mai multi in companie

select * from (
select AnAngajare
, max(NrCrtPersAngPeAn) maxim
, row_number() over(order by max(NrCrtPersAngPeAn) desc) nrCrt
from (
select last_name, hire_date, to_char(hire_date, 'yyyy') AnAngajare
,row_number() over(partition by to_char(hire_date, 'yyyy') order by
to_char(hire_date, 'yyyy')) NrCrtPersAngPeAn
from employees
)
group by AnAngajare
order by 2
) where nrcrt=1;

select * from (
select AnAngajare,NrCrtPersAngPeAn,
row_number() over(order by NrCrtPersAngPeAn desc) nrcrt
from (
select distinct to_char(hire_date, 'yyyy') AnAngajare
,count(*) over(partition by to_char(hire_date, 'yyyy') order by
to_char(hire_date, 'yyyy')) NrCrtPersAngPeAn
from employees
)
) where nrcrt=1;

Exercitii cu ranking si windowing – 2


----nrcrt in dreptul fiecarui departament
select department_id, department_name,
row_number() over(order by Department_Name) NrCrt
from departments;

--update departments set manager_id=108 where department_id=120;

--exista mai multe departamente cu acelasi sef? / o persoana conduce mai multe
departament?
select * from departments where manager_id in (
select manager_id from (
select department_id, department_name, manager_id, ---am nevoie doar de
manager_id + NrCrt_managerid
row_number() over(partition by manager_id order by manager_id)
NrCrt_managerid
from departments
order by manager_id
) where nrcrt_managerid >= 2 and manager_id is not null ---o persoana
conduce mai multe departament?
)
;

--orasele cu cele mai multe departamente


---Common Table Expression CTE
with x as (
select department_id, department_name, location_id
, count(location_id) over(partition by location_id) nr1
from departments
)
select department_id, department_name, location_id
from x
where nr1 = (select max(nr1) from x);

--In ce an s-au angajat cei mai multi in companie


with x as (
select employee_id, hire_date, to_char(hire_date, 'yyyy') AnAng
, count(*) over (partition by to_char(hire_date, 'yyyy')) NrAngInAnul
from employees
)
select distinct AnAng, NrAngInAnul
from x
where NrAngInAnul = (select max(NrAngInAnul) from x);
--tarile cu cele mai putine departamente
with x as (
select department_id, department_name, d.location_id, c.country_name
, count(l.country_id) over(partition by c.country_name) nr2
from departments d inner join locations l on d.location_id = l.location_id
inner join countries c on l.country_id = c.country_id
)
select * from x
where nr2 = (select min(nr2) from x);

--angajatii cre cistiga cel mai putin


select * from (
select employee_id, salary,
rank() over(order by salary) nr
from employees
) where nr=1;

--media sal. pe fiecare locatie in parte


select l.city, round(avg(salary)) mediaSal from employees e inner join departments d
on e.department_id = d.department_id inner join locations l on d.location_id =
l.location_id group by l.city;

--media sal. pe fiecare locatie in parte cu ranking/windowing


select * from (
select l.city
,round(avg(salary) over(partition by l.city) ) RunnAvg
,row_number() over(partition by l.city order by l.city) NrCrtOras
from employees e inner join departments d on e.department_id = d.department_id inner
join locations l on d.location_id = l.location_id
) where NrCrtOras = 1

Subinterogari
--interogai in alte interogari

--1. gasire sal. minim


select min(salary) from employees;

--2. gasire ang. care cistiga acest sal.minim


select * from employees where salary = (select min(salary) from employees) ;

------------
select * from employees where salary in (select salary from employees where
last_name='Cambrault');

------
select * from employees where (salary, department_id) in (
select min(salary), department_id from employees group by department_id
);
select * from employees where salary = (
select min(salary) from employees group by department_id
);

---
select department_id, avg(salary) from employees
group by department_id
having avg(salary) >= (select avg(salary) from employees where
department_id=30);

select * from employees e1


where salary > (select avg(salary) from employees e2 where e1.department_id =
e2.department_id);

select * from employees e where exists (select 1 from employees ang where
ang.manager_id = e.employee_id);

--departm. care nu au angajati


select * from departments d where not exists (Select 1 from employees e where
e.department_id = d.department_id);

select * from employees where salary in (select salary from employees);

---ang.care cistiga cel mai mare sal pentru fievare tip de functie
select * from employees
where salary in (select max(salary) from employees group by job_id);

---cei mai recet angajati din fiecare departament


select * from employees e
where hire_date in (select max(hire_date) from employees e2 where e.department_id
= e2.department_id group by department_id)
order by employee_id;

--ang care cistiga mai mult decit media dep. din care fac parte
select * from employees e where salary > (select avg(salary) from employees e2 where
e.department_id = e2.department_id group by department_id);

--depart cu cel mai mare sal.total anual

select department_id, sum(salary) from employees group by department_id having


sum(salary) = (
select max(sal_total) from (
select sum(salary) sal_total, department_id from employees group by
department_id order by 1 desc
)
);

select department_id, sum(salary) from employees group by department_id having


sum(salary) = (
select max(sum(salary)) from employees group by department_id
);

--dep.al caror salariu maxim este mai mare de 10000


select * from departments where department_id in
(select department_id from employees group by department_id having
max(salary)>10000);

--pers.care nu au mai fost abgajate anterior in organizatie


select * from employees e where employee_id not in (select employee_id from
job_history);

select * from employees e where not exists (select employee_id from job_history jh
where jh.employee_id = e.employee_id);

--job + salariul mediu pt pers. care au mai fost anterior angajate


select job_id, avg(salary) from employees
where employee_id in (select employee_id from job_history)
group by job_id;

--sa afisam detlii despre job-uri pentru pers. care anteriro au fost angajate pe
poztie de IT_PROG
select * from jobs where job_id in (
select job_id from employees where employee_id in (
select employee_id from job_history where job_id='IT_PROG'
)
);

--toate inf.depsre angajatii care cistiga intre cel mai mic salariu din depart.lor
si 3000
select * from employees e where salary > (
select min(salary) from employees e2 where e.department_id = e2.department_id group
by department_id
) and salary < 3000;

--toti ang.din Toronto


select * from employees where department_id in (
select department_id from departments where location_id in (
select location_id from locations where city='Toronto'
));

--pers.al caror salariu este mai mic decit ale oricaror pers.cu job_id=FI_MGR
select * from employees e
where salary < (select salary from employees where job_id='FI_MGR');

--pt fiecare angajar o comparatie cu sal.mediu din depart lui si sal.mediu din org,
inclusiv diferentele si starea (mai mare/mai mic, egal)
select employee_id, salary, salary-sal_med_org, salary-sal_med_depart, sal_med_org,
sal_med_depart
,case when salary > sal_med_org then '+ med.sal.org' else '- med.sal.org' end as
Stare_med_sal_org
,case when salary > sal_med_depart then '+ med.sal.depart' else '- decit
med.sal.depart' end as Stare_med_sal_depart
from (
select employee_id, salary,
(select round(avg(salary)) from employees) sal_med_org,
(select round(avg(salary)) from employees e2 where e2.department_id =
e.department_id) sal_med_depart
from employees e
);

with x as (
select employee_id, salary,
(select round(avg(salary)) from employees) sal_med_org,
(select round(avg(salary)) from employees e2 where e2.department_id =
e.department_id) sal_med_depart
from employees e
)
select employee_id, salary, salary-sal_med_org, salary-sal_med_depart, sal_med_org,
sal_med_depart
,case when salary > sal_med_org then '+ med.sal.org' else '- med.sal.org' end as
Stare_med_sal_org
,case when salary > sal_med_depart then '+ med.sal.depart' else '- decit
med.sal.depart' end as Stare_med_sal_depart
from x;

--pers.care cistiga la fel cu angajatii din departmanetul de MK=arketing


select * from employees where salary in (
select salary from employees where department_id in (select department_id from
departments where department_name='Marketing')
);

Subinterogari – exercitii
--care sint angajatii cu job-ul "Stock Manager"
Select * from employees where job_id=(SELECT job_id from jobs where job_title='Stock
Manager');

--care sint angajatii cu job-urile "Stock Manager" si "Stock Clerk"


select * from employees where
job_id in (select job_id from jobs where job_title='Stock Manager' or
job_title='Stock Clerk');

--pers. care au fost angajate pe alte pozitii in trecut


select * from employees where employee_id in (select employee_id from job_history);

--angajatii din Roma si Singapore


SELECT * from employees where department_id IN
(SELECT department_id from locations where location_id
IN (select location_id from locations where city='Roma' OR city='Singapore')
);

--departamentele care nu au angajati - cu "exists"


select * from departments d where not exists
(select 1 from employees e where e.department_id = d.department_id);

--numele si data angajarii pentru pers. care au fost angajate dupa persoana cu id-ul
101
select first_name, last_name, hire_date from employees
where hire_date > (select hire_date from employees where employee_id = 101)
order by hire_date;

--depart. pentru care costul total mediu al salariului este mai mare decit costul
mediu pe organizatie
select AVG(salary) as salariu_total_mediu, department_id
from employees
group by department_id
having avg(salary) > ( select AVG(salary) from employees );

--1. afisati job_id, min_salary, and max_salary din tabela jobs


--2. adaugati 2 coloane la 1) care sa contina sal.mediu minim si sal.mediu maxim (cu
subinterogare)
select job_id, min_salary, max_salary
, (select round(avg(min_salary)) from jobs) avg_min_sal
, (select round(avg(max_salary)) from jobs) avg_max_sal
from jobs;

--citi angajati exista in fiecare departament si cit reprezinta totalul salariilor


din departamentul respectiv, afisate procentual la total orgaizatie
select nr_pe_depart.department_id, round(nr_pe_depart.nr_ang / nr_total.totalang *
100, 2), round(nr_pe_depart.sum_sal / nr_total.totalsal * 100, 2) from

(select department_id, count(*) nr_ang, sum(salary) sum_sal


from employees
group by department_id) nr_pe_depart
,
(select count(*) totalAng, sum(salary) totalSal from employees) nr_total;

--cu CTE
with
nr_pe_depart as (
select department_id, count(*) nr_ang, sum(salary) sum_sal
from employees
group by department_id
),
nr_total as (
select count(*) totalAng, sum(salary) totalSal from employees
)
select nr_pe_depart.department_id, round(nr_pe_depart.nr_ang / nr_total.totalang *
100, 2), round(nr_pe_depart.sum_sal / nr_total.totalsal * 100, 2)
from nr_pe_depart, nr_total;

--
select nr_pe_depart.department_id, (select department_name from departments where
nr_pe_depart.department_id=department_id) as nume_departament,
round(nr_pe_depart.nr_ang / nr_total.totalang * 100, 2),
round(nr_pe_depart.sum_sal / nr_total.totalsal * 100, 2)
from
(select department_id, count(*) nr_ang, sum(salary) sum_sal from employees group
by department_id) nr_pe_depart
,
(select count(*) totalAng, sum(salary) totalSal from employees) nr_total;

DML – MERGE
 http://psoug.org/reference/merge.html
 https://www.oracletutorial.com/oracle-basics/oracle-merge/
 https://livesql.oracle.com/apex/livesql/file/content_PC76LRDFFAVI6P6LMCWJLBOP2.
html

PLSQL 1 - parcurgere angati 1-->300 + exception + if + update


set SERVEROUTPUT On;

declare
v_empid emp2.employee_id%type := 1;
v_sal number(10,2);
v_nume varchar(100);
v_jobid emp2.job_id%type;
begin

loop

begin
select first_name || ' ' || last_name, salary, job_id into v_nume, v_sal,
v_jobid from employees where employee_id = v_empid;

dbms_output.put_line(v_nume || ' salariu=' || v_sal);

if lower(v_jobid) like '%clerk%' then


dbms_output.put_line('update sal. pt=' || v_empid );
update emp2 set salary = v_sal * 1.15 where employee_id = v_empid;
end if;

exception
when others then
dbms_output.put_line('nu exista date pt id=' || v_empid || ' ...
cod=' ||sqlcode);
end;

v_empid := v_empid+1;

exit when v_empid > 300;


end loop;

commit;

end;
PLSQL - de mutat toti angajatii de pe postul SH_CLERK --->
ST_CLERK in tabela Angajat, cu pastrare istoric, inclusiv salariu in
Ang_job_hist. La "end_date" se completeaza data curenta
declare
    v_empid angajat.employee_id%type;   
    v_start_date angajat.hire_date%type;
    v_end_date ang_job_hist.end_date%type;
    v_job_id angajat.job_id%type;
    v_department_id angajat.department_id%type;
    v_salariu angajat.salary%type;
    v_salariu_nou ang_job_hist.salariu%type;
    v_empid_max angajat.employee_id%type;
begin

    dbms_output.put_line('inceput prelucrare...');


    
    select max(employee_id), min(employee_id) into v_empid_max, v_empid from angajat;
    loop    
        begin
            dbms_output.put_line('prelucrare id=' || v_empid);
        
            select employee_id, hire_date, job_id, department_id, salary
                    into v_empid, v_start_date, v_job_id, v_department_id, v_salariu 
from angajat
                where employee_id = v_empid;
            
            if upper(v_job_id) = 'SH_CLERK' then
            
                if v_empid mod 2 = 0 then
                    v_salariu_nou := v_salariu * 1.1;
                else 
                    v_salariu_nou := v_salariu * 1.07;
                end if;
            
            select sysdate into v_end_date from dual;
            
            insert into ang_job_hist (employee_id, start_date, end_date, job_id,
department_id, salariu) 
                values (v_empid, v_start_date, v_end_date, v_job_id, v_department_id,
v_salariu);
            
            update angajat set salary = v_salariu_nou, job_id = 'ST_CLERK' where
employee_id = v_empid;
            
            end if;
        
        exception
            when others then
            dbms_output.put_line('eroare angajat v_empid' || sqlcode);
        
        end;
        
        v_empid := v_empid + 1;
        
        exit when v_empid > v_empid_max;
        
        dbms_output.put_line('final prelucrare fara erori'); 
        
    end loop;
             
exception
    when others then
        dbms_output.put_line('eroare' || sqlcode);
end;

Cursoare – 1
declare

v_end_date date;
v_salariu_nou ang_job_hist.salariu%type;

cursor c1 is
select * from angajat where upper(job_id) = 'ST_CLERK';

vrc c1%rowtype;
begin

dbms_output.put_line('inceput prelucrare...');

if c1%isopen = false THEN


open c1; --deschide cursor daca nu este deschis
end if;

loop --LOOP pentru parcurgere inregistrari din cursor!!!

fetch c1 into vrc; --obine datele pentru o / 1 /una inregistrare si le


pune in variabila "vrc", de acelasi tip ca un RIND din cursor!

begin
dbms_output.put_line('prelucrare id=' || vrc.employee_id);

if upper(vrc.job_id) = 'ST_CLERK' then

if vrc.employee_id mod 2 = 0 then


v_salariu_nou := vrc.salary * 1.1;
else
v_salariu_nou := vrc.salary * 1.07;
end if;

--obine data curenta si o pune intr-o variabila


select sysdate into v_end_date from dual;

insert into ang_job_hist (employee_id, start_date, end_date, job_id,


department_id, salariu)
values (vrc.employee_id, vrc.hire_date, v_end_date, vrc.job_id,
vrc.department_id, vrc.salary);

update angajat set salary = v_salariu_nou, job_id = 'SH_CLERK' where


employee_id = vrc.employee_id;

end if;

exception
when others then
dbms_output.put_line('eroare angajat v_empid' || sqlcode);

end;

exit when c1%notfound; ---iesire din cursor cind nu mai exita date de
prelucrat

dbms_output.put_line('final prelucrare fara erori');

end loop;

close c1;

exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;

Cursor 2 - cu parametri
declare

v_end_date date;
v_salariu_nou ang_job_hist.salariu%type;
v_job_destinatie angajat.job_id%type;

cursor c1 (param_job_id angajat.job_id%type, param2 date) is


select * from angajat where upper(job_id) = param_job_id and hire_date <
param2;

vrc c1%rowtype;
begin

dbms_output.put_line('inceput prelucrare...');

v_job_destinatie := 'ST_CLERK';
if c1%isopen = false THEN
open c1 ('SH_CLERK', '18-11-2020') ; --deschide cursor daca nu este
deschis
end if;

loop --LOOP pentru parcurgere inregistrari din cursor!!!

fetch c1 into vrc; --obine datele pentru o / 1 /una inregistrare si le


pune in variabila "vrc", de acelasi tip ca un RIND din cursor!

begin
dbms_output.put_line('prelucrare id=' || vrc.employee_id);

if vrc.employee_id mod 2 = 0 then


v_salariu_nou := vrc.salary * 1.1;
else
v_salariu_nou := vrc.salary * 1.07;
end if;

--obine data curenta si o pune intr-o variabila


select sysdate into v_end_date from dual;

insert into ang_job_hist (employee_id, start_date, end_date, job_id,


department_id, salariu)
values (vrc.employee_id, vrc.hire_date, v_end_date, vrc.job_id,
vrc.department_id, vrc.salary);

update angajat set salary = v_salariu_nou, job_id = v_job_destinatie


where employee_id = vrc.employee_id;

exception
when others then
dbms_output.put_line('eroare angajat v_empid ' || vrc.employee_id || '
cod=' || sqlcode);

end;

exit when c1%notfound; ---iesire din cursor cind nu mai exita date de
prelucrat

dbms_output.put_line('final prelucrare fara erori');

end loop;

close c1;

exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;

Cursoare 3 - crestere salariu in limita unui buget de 30000


set SERVEROUTPUT On;
declare 
 v_crestere angajat.salary%type;
 v_salariu_nou angajat.salary%type;
 v_buget angajat.salary%type:=0;
 --in buget voi aduna
   
    cursor c1 is 
        select * from angajat ;
        
    vrc c1%rowtype;
     
        begin
        dbms_output.put_line('inceput prelucrare...');
    
         if c1%isopen = false THEN
            open c1;        --deschide cursor daca nu este deschis
        end if;
    
        loop                --LOOP pentru parcurgere inregistrari din cursor!!!
    
        fetch c1 into vrc;   
        
         begin
            dbms_output.put_line('prelucrare id=' || vrc.employee_id);
        
            
                v_crestere:= vrc.salary * 0.1;
                v_buget:=v_buget+v_crestere;
                v_salariu_nou := vrc.salary * 1.1;
                
                 update angajat set salary = v_salariu_nou where
employee_id=vrc.employee_id;
    
    
          exception
                when others then
                dbms_output.put_line('eroare angajat v_empid ' || vrc.employee_id ||
' cod=' || sqlcode);
            end;
        
        
        exit when c1%notfound OR  v_buget>=30000;  ---iesire din cursor cind nu mai
exita date de prelucrat
        
        dbms_output.put_line('final prelucrare fara erori'); 
        dbms_output.put_line('Buget folosit ='||v_buget); 
    end loop;
    
    close c1;
             
exception
    when others then
        dbms_output.put_line('eroare' || sqlcode);
end;

Cursoare 4 – FOR
set SERVEROUTPUT On;
declare
v_crestere angajat.salary%type;
v_salariu_nou angajat.salary%type;
v_buget angajat.salary%type:=0;
--in buget voi aduna

cursor c1 (param_job_id angajat.job_id%type) is


select * from angajat where upper(job_id) = param_job_id ;

begin
dbms_output.put_line('inceput prelucrare...');

for vrc in c1('ST_CLERK') ---in care "vrc" este de tip


"c1%rowtype" si este declarat automat!
loop
begin
dbms_output.put_line('prelucrare id=' || vrc.employee_id);

v_crestere:= vrc.salary * 0.1;


v_buget:=v_buget+v_crestere;
v_salariu_nou := vrc.salary * 1.1;

update angajat set salary = v_salariu_nou where


employee_id=vrc.employee_id;

--iesire fortata din ciclu daca se indeplineste conditia !!!!


exit when v_buget > 1000;

exception
when others then
dbms_output.put_line('eroare angajat v_empid ' || vrc.employee_id || '
cod=' || sqlcode);
end;

dbms_output.put_line('final prelucrare fara erori');


dbms_output.put_line('Buget folosit ='||v_buget);
end loop;

exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;

Cursor in cursor, cu FOR


set SERVEROUTPUT ON size unlimited;

declare

cursor cAngajati (param_departament_id employees.department_id%type) is


select employees.first_name, employees.last_name, employee_id from employees
where department_id = param_departament_id;

vrc cAngajati%rowtype;

cursor cDepartamente is
select * from departments;

vrd cDepartamente%rowtype;

begin

dbms_output.put_line('inceput prelucrare...');

for vrd in cDepartamente


loop

begin
dbms_output.put_line('prelucrare department_id=' || vrd.department_id);

for vrc in cAngajati(vrd.department_id)


loop

begin
dbms_output.put_line(vrc.employee_id);

exception
when NO_DATA_FOUND then
dbms_output.put_line('employee_id=' || vrc.employee_id || '
nu are un departament alocat');
end;

end loop;

end;
end loop;

end;

UDF - 1 functie care returneaza date intr-un tip complex definit de


utilizator
create or replace function udf_listaAngajati(p_nrDepart in number)
return tbl_tip_ang
is
v_rez tbl_tip_ang;
begin

select tip_ang(last_name || ' ' || first_name, department_name, salary, job_id)


---initializare+conversie rezultate la tipul "tip_ang" pt ca tabela rez este de acest
tip
bulk collect into v_rez
from employees e inner join departments d on e.department_id =
d.department_id
where e.department_id = p_nrDepart;

return v_rez;
end;

UDF – 2 functie care returneaza date intr-un tip complex definit de


utilizator. Prelucrare aditionala de date intr-un cursor - se returneaza
doar inregistrarile care indeplinesc conditii (complexe)
create or replace function udf_listaAngajati_2(p_nrDepart in number)
return tbl_tip_ang
is
v_rez tbl_tip_ang := tbl_tip_ang();

idx number;
numarInregistrare number:=0;

cursor c is select last_name || ' ' || first_name as NUME, department_name,


salary, job_id ---initializare+conversie rezultate la tipul "tip_ang" pt
ca tabela rez este de acest tip
from employees e inner join departments d on e.department_id =
d.department_id
where e.department_id = p_nrDepart;

begin

idx:= 1;

for rec in c loop


numarInregistrare := numarInregistrare + 1;

if (numarInregistrare mod 2 = 0) then -------conditie complexa

v_rez.extend;
idx := v_rez.last; --ultima inregistrare

v_rez(idx) := tip_ang(null, null, null, null); ---instantiere


rind curent din tabela v_rez in care fiecare element este de tipul "TIP_ANG" si il
facem egal cu TIP_ANG initializat peste tot cu NULL

v_rez(idx).numeAng := rec.NUME;
v_rez(idx).numeDepart := rec.department_name;
v_rez(idx).salariu := rec.salary;
v_rez(idx).numefunctie := rec.job_id;

end if;

end loop;

return v_rez;
end;

UDF - apel la functii


--apel la functia 1
select ang.*, j.job_title from table(udf_listaAngajati(20)) ang inner join jobs j on
ang.numefunctie = j.job_id;

--apel simplu la functia 2


select ang.* from table(udf_listaAngajati_2(50)) ang;

You might also like