Download as pdf or txt
Download as pdf or txt
You are on page 1of 58

Sa se creeze un package care sa contina constructii publice si private, care va cuprinde 2 proceduri:

- o procedura care va fi apelata din a doua procedura, care modifica salariile angaja?ilor, prin adunarea cu 10 la salariul
existent
- o procedura care preia angajatii dintr-un departament dat ca parametru si care va ntoarce numarul de angajati din
acel departament.
Calculul pentru modificarea salariilor se vor face n bucla, cu cursor;
Package-ul va fi verificat ntr-un bloc anonim PL/SQL, n care se va cere de la tastatura numarul departamentului si
tipul operatiei
(0 afisare salarii, 1 modificare salarii) si care va afisa numarul de angajati din departament (ntors de procedura din
package) si
salariile angaja?ilor din acel departament, modificate sau nu, functie de tipul operatiei.
Barem:
(1p) din oficiu
(1p) specificatia package-ului (n care se va scrie ntr-un comentariu argumentat care sunt constructiile publice si
private)
(5p) corpul package-ului (2p procedura de modificare a salariilor si 3p procedura care apeleaza procedura de
modificare a salariilor si ntoarce numarul de angajati)
(3p) blocul anonim PL/SQL*/
create or replace package emp_pack
is
procedure tk_empno(
v_deptno in emp.deptno%type,
nr_salariati out number);
end;
/
create or replace package body emp_pack
is
procedure modifica_salariu(
v_empno emp.empno%type)
is
begin
update emp
set sal=sal+10
where empno=v_empno;
end modifica_salariu;
procedure tk_empno(
v_deptno in emp.deptno%type,
nr_salariati out number)
is
cursor c1 is
select empno
from emp
where deptno=v_deptno;
begin
for c1_record in c1 loop
modifica_salariu(c1_record.empno);
nr_salariati:=c1%rowcount;
end loop;

end tk_empno;
end;
/
accept p_deptno prompt 'Dati nr dep: '
accept p_operatie prompt 'Dati tipul operatiei: '
declare
v_nr number(3);
v_deptno emp.deptno%type:=&p_deptno;
v_operatie number:=&p_operatie;
cursor c1 is
select ename,sal
from emp
where deptno=v_deptno;
begin
if v_operatie=1 then
emp_pack.tk_empno(v_deptno,v_nr);
dbms_output.put_line('Au fost modificati '||v_nr || ' angajati in dept. ' || v_deptno);
end if;
for c1_record in c1 loop
dbms_output.put_line(' ');
dbms_output.put_line(c1_record.ename||' '||c1_record.sal);
end loop;
rollback;
end;

--1.Afisati numele angajatilor care au 2 de 'L' in numele lor si sunt din departamentul 30 sau au manager cu marca
7782.
select ename
from emp
where ename like '%l%l%' and deptno=30 or mgr=7782
--2.Afisati numele si salariul tuturor angajatilor a caror salarii nu intra in intervalul 1500$ si 2850$.
select ename,lpad(sal,7)salary
from emp
where sal not between 1500 and 2850
order by salary
--3.Listati alfabetic numele si salariul celor care castiga mai mult de 1500$ si sunt in departamentele 10 sau 30.
Redenumiti
--coloanele Angajat si Salar Lunar
select ename Angajat,lpad(sal,7)Salar_Lunar
from emp
where sal > 1500 and deptno in(10,30)
order by Salar_Lunar
--4.Afisati codul, numele, salariul si salariul marit cu 15%. Denumiti ultima coloana Salar Nou. Adaugati o coloana in
care veti face
--diferenta dintre salariul nou si cel vechi. Denumiti noua coloana Crestere.
select empno,ename,lpad(sal,7)salary,lpad((sal+sal*0.15),7)Salar_Nou,lpad(sal+sal*0.15-sal,7)Crestere
from emp
order by sal
-select empno,ename,lpad(sal,7)salary,lpad((sal*1.15),7)Salar_Nou,lpad(sal*1.15-sal,7)Crestere
from emp
order by sal
--5.Pentru fiecare angajat afisati numele si calculati numarul de luni intre data de astazi si data angajarii, iar coloana sa
se
--denumeasca luni_de_activitate. Ordonati rezultatul dupa numarul de luni de lucru. Rotunjiti numarul de luni.
select ename,trunc(months_between(sysdate,hiredate)) luni_de_activitate
from emp
order by luni_de_activitate
--6.Scrieti o interogare care afiseaza numele, meseria, numarul departamentului si numele departamentului pentru
toti angajatii
--care lucreaza in Dallas.
select ename,job,lpad(e.deptno,7)department_id,dname
from emp e inner join dept d on e.deptno=d.deptno
and loc='Dallas'
order by dname
--7.Afisati numele angajatului si numarul lui impreuna cu numele managerului si numarul acestuia. Etichetati coloanele
--Employee, Emp#, Manager, Mgr#.
select e.ename Employee,e.empno Emp#,m.ename Manager,e.mgr Mgr#
from emp e inner join emp m on e.mgr=m.empno

order by e.mgr
--8.Creati o interogare care va afisa numele, meseria, numele departamentului, salariul si gradul pentru toti angajatii.
select distinct ename,job,dname,lpad(sal,7)salary,lpad(grade,7)grade_level
from emp e left outer join dept d
on e.deptno=d.deptno inner join salgrade s on e.sal between s.losal and s.hisal
order by salary
--9.Scrieti o interogare pentru afisarea numarului de angajati cu aceeasi meserie.
select job,count(empno)No_of_Employees
from emp
group by job
order by No_of_Employees
--10.Scrieti o interogare care sa afiseze diferenta dintre salariile cele mai mari si cele mai mici. Etichetati coloana
'Diferenta'.
select max(sal)-min(sal) Diferenta
from emp
--11.Afisati numarul managerului si salariul celui mai prost platit angajat pentru acel manager. Excludeti pe cei ce nu au
manager.
--Excludeti grupurile care au salariul mai mic decat 1000$. Sortati rezultatele in ordine descrescatoare dupa salar.
select e.mgr,m.ename,min(e.sal)Minimum_Salary
from emp e inner join emp m on e.mgr=m.empno
having min(e.sal)>1000
group by e.mgr,m.ename
minus
select e.mgr,m.ename,min(e.sal)
from emp e inner join emp m on e.mgr=m.empno
where e.mgr is null
group by e.mgr,m.ename
order by Minimum_Salary desc
--sau
select e.mgr,m.ename,min(e.sal)Minimum_Salary
from emp m inner join emp e on e.mgr=m.empno
having min(e.sal)>1000 and e.mgr is not null
group by e.mgr,m.ename
order by Minimum_Salary
--12.Sa se creeze o cerere pentru a afisa numarul angajatului si numele sau pentru toti angajatii care castiga mai mult
decat salariul
--mediu. Sa se sorteze rezultatele in ordinea descrescatoare a salariului.
select empno,ename,lpad(sal,7)salary
from emp
where sal>
(select avg(sal)
from emp)
order by salary
--13.Afisati numele si salariul tuturor angajatilor subordonati lui King

select ename,lpad(sal,7)salary
from emp
where mgr =
(select empno
from emp
where ename='King')
order by salary
--14.Scrieti o interogare care sa afiseze numele, numarul departamentului si salariul oricarui angajat al carui numar
--de departament si salariu sa se potriveasca cu numarul departamentului si salariul oricarui angajat care percepe un
comision.
select ename,d.deptno,lpad(sal,7)salary
from emp e inner join dept d on e.deptno=d.deptno
where (e.deptno,sal) in
(select e.deptno,sal
from emp
where comm is not null)
order by salary
--15.Scrieti o interogare care sa afiseze angajatii care castiga un salariu mai mare ca al oricarui angajat
functionar(clerks).
--Afisati salariile de la cel mai mare la cel mai mic.
select ename,job,lpad(sal,7)salary
from emp
where sal>all
(select sal
from emp
where job='Clerk')
order by salary desc
--16.Scrieti un script file pentru a afisa numele, functia si data angajarii pentru toti salariatii care au inceput sa lucreze
--intr-o anumita perioada. Se concateneaza numele si functia impreuna, separate de un spatiu si virgula si etichetati
coloana
--'Employees'. Datele calendaristice care delimiteaza perioada se vor introduce de la tastatura. Se utilizeaza formatul
MM//DD/YY.
accept dip date format 'MM/DD/YYYY' prompt 'Introduceti inceputul perioadei : '
accept dsp date format 'MM/DD/YYYY' prompt 'Introduceti sfarsitul perioadei : '
select ename ||', '|| job Employees, hiredate
from emp
where hiredate between to_date('&dip','MM/DD/YYYY') and to_date('&dsp','MM/DD/YYYY')
order by hiredate
--17.Creati un tabel numit employee cu structura de mai jos:
--drop table employee
create table employee(
id number(7)
constraint pk_employee primary key
constraint nn_employee not null,
last_name varchar2(25),
constraint nn_last_name not null,

first_name varchar2(25)
constraint nn_first_name not null,
userid varchar2(8)
constraint nn_userid not null
constraint un_userid unique,
salary number(10)
constraint ck_salary check(salary > 500 and salary < 20000),
department_id number(7)
constraint fk_department_id1 references departments(department_id));
--adaugarea de comentarii la nivelul tabelei si afisarea din dictionarul de date
comment on table employee is 'Employee Information: ';
column table_name format a15
column table_type format a10
column comments format a16
-select * from user_tab_comments
where table_name='employee';
--crearea secventei pentru introducerea automata a valorilor pentru campul ID
--drop sequence seq_id
CREATE SEQUENCE seq_id
MINVALUE 100
START WITH 100
INCREMENT BY 5
--introducere date in tabela employee, iar valorile coloanei id sunt introduse in mod automat pe baza secventei
construita anterior
insert into employee values(seq_id.nextval,'Ionescu','Ion',11,4000,10);
insert into employee values(seq_id.nextval,'Popescu','Ion',21,4000,10);
insert into employee values(seq_id.nextval,'Marinescu','Doru',31,5000,20);
insert into employee values(seq_id.nextval,'Vasilescu','Dumitru',41,500,10);
--mariti salariul angajatilor din departamentul 10 cu 5%
update employee
set salary = replace(salary,salary,salary*1.05)
where department_id=10
--verificare ca salariul a fost marit
select last_name,lpad(salary,7)old_salary,lpad(round(replace(salary,salary,salary*1.05)),7)new_salary
from employee
where department_id=10
--stergeti angajatii cu salariul mai mic de 800
delete from employee
where salary<800
--creati o vizualizare care sa afiseze urmatoarele informatii: nume si prenume (intr-o coloana), salariul lunar,
--salariul anual, numele departamentului si apoi interogati vizualizarea
create or replace view employees_view as
select first_name ||' '||last_name name, lpad(salary,7)salary, 12*salary as annual_salary,

department_name, d.department_id
from employees e inner join departments d on e.department_id=d.department_id
--interogarea vizualizarii
select * from employees_view
where salary between 3000 and 10000
order by department_id
--creati o vizualizare care sa afiseze suma salariilor, media salariilor, minimul si maximul salariilor pe departamente
create or replace view detalii_view as
select lpad(sum(salary),7)suma_salarii,lpad(round(avg(salary)),7)medie_salarii,
lpad(min(salary),7)salariul_minim,lpad(max(salary),7)salariu_maxim,department_id
from employees
where department_id is not null
group by department_id
order by department_id
--interogarea vizualizarii
select * from detalii_view
--creati sinonimul emp1 pentru employee si inserati inregistrari in noile obiecte
create or replace synonym emp1 for employee
-desc emp1
-insert into employee values(seq_id.nextval,'Dumitrescu','Marius',51,700,10);
insert into employee values(seq_id.nextval,'Vasile','Ionut',61,760,20);
insert into employee values(seq_id.nextval,'Murgoci','Ion',71,780,20);
--creati o tabela newemp cu structura si datele tabelei employee
create table newemp
as (select * from employee)
--afisati existenta tabelei in dictionarul de date
select table_name
from user_tables
--stergeti tabela si confirmati stergerea verificand in dictionarul de date
drop table newemp
--in tabela employee adaugati campul manager de tip numeric, latime 7, constrangere cheie externa de tip 'self
join'(coloana ID)
alter table employee
add manager number(7)
constraint fk_manager references employee(id)
--verificati existenta constrangerii in dictionarul de date
select * from user_constraints
--sa se creeze un index neunic pentru campul de tip foreign key din tabela employee
create index idxemployee_department_id on employee(department_id)
--verificati existenta indexului in dictionarul de date
select * from user_indexes

--1.Creati un bloc anonim si afisati urmatoarea fraza pe ecran: "My PL/SQL Block Works"
--set serveroutput on
declare
v_message varchar2(30);
begin
v_message:='My PL/SQL Block Works';
dbms_output.put_line(v_message);
end;
--2.Creati un bloc si declarati 2 variabile. Asignati valorile acestor variabile PL/SQL unor variabile de legatura si afisati-le
pe
--ecran.
declare
v_char varchar2(50);
v_num number(11,2);
begin
v_char:='9.57 a fost media mea la Baze de Date din anul III';
v_num:=to_number(substr(v_char,1,5));
dbms_output.put_line(v_char);
dbms_output.put_line(v_num);
end;
--3.Analizati blocul de mai jos si determinati urmatoarele valori:
--a.valoarea v_weight in sub-bloc
--b.valoarea v_new_locn in sub-bloc
--c.valoarea v_weight in blocul principal
--d.valoarea v_message in blocul principal
--e.valoarea v_new_locn in blocul principal
declare
v_weight number(3):=600;
v_message varchar2(255):='Product 11002';
begin
declare
v_weight number(3):=1;
v_message varchar2(255):='Product 11001';
v_new_locn varchar2(50):=' Europe';
begin
v_weight:=v_weight+1;
v_new_locn:='Western'||v_new_locn;
dbms_output.put_line(v_weight);
dbms_output.put_line(v_new_locn);
end;
v_weight:=v_weight+1;
v_message:=v_message || ' is in stock';
dbms_output.put_line(v_weight);
dbms_output.put_line(v_message);
end;
--4.Fie structura de mai jos, in care variabilele v_customer si v_credit_rating sunt declarate in blocul principal, iar

--v_name si v_customer in sub-bloc. Determinati:


--a.valoarea v_customer in sub-bloc
--b.valoarea v_name in sub-bloc
--c.valoarea v_credit_rating in sub-bloc
--d.valoarea v_customer in blocul principal
--e.valoarea v_name in blocul principal
--f.valoarea v_credit_rating in blocul principal
declare
v_customer varchar2(50):='Womansport';
v_credit_rating varchar2(50):='Excellent';
begin
declare
v_customer number(7):=201;
v_name varchar2(25):='Unisports';
begin
dbms_output.put_line(v_customer);
dbms_output.put_line(v_name);
dbms_output.put_line(v_credit_rating);
end;
dbms_output.put_line(v_customer);
dbms_output.put_line(v_credit_rating);
end;
--5.Creati si executati un bloc PL/SQL care accepta doua numere prin intermediul a doua variabile de substitutie.
--Primul numar trebuie impartit la al doilea, iar rezultatul adunat la cel de-al doilea numar.
accept p_num1 prompt 'Enter the first number: '
accept p_num2 prompt 'Enter the second number: '
declare
v_num1 number(9,2):=&p_num1;
v_num2 number(9,2):=&p_num2;
begin
dbms_output.put_line(round(to_char(v_num1/v_num2+v_num2)));
end;
--6.Construiti un bloc PL/SQL care calculeaza compensatia totala pentru un an. Salariul anual si bonusul anual sunt
trimise blocului
--PL/SQL prin doua variabile de substitutie, bonusul trebuind sa fie convertit dintr-un numar intreg in zecimal (de
exemplu 15 in .15).
--Daca salariul este nul, dati-i valoarea zero inainte de a calcula valoarea compensatiei. Folositi functia NVL pentru
valorile nule.
accept p_salary prompt 'Introduceti salariul: ';
accept p_commission prompt 'Introduceti comisionul: ';
declare
v_salary number:=&p_salary;
v_commission number:=&p_commission;
begin
v_salary:=nvl(v_salary,0);
v_commission:=nvl(v_commission,0);
dbms_output.put_line(v_salary*12+((v_salary*v_commission)/100)*12);
end;

--1.Creati un bloc PL/SQL care sa selecteze numarul maxim al departamentului din tabela dept si sa il stocheze intr-o
variabila.
declare
v_max_deptno number;
begin
select max(deptno)
into v_max_deptno
from dept;
dbms_output.put_line('The maximum id for a department is ' || to_char(v_max_deptno));
end;
--2.Creati un bloc PL/SQL care sa insereze un nou departament in tabela dept.
--a.Folositi numarul departamentului returnat la punctul 1) si adunati 10 la acest numar ca fiind numarul
departamentului pentru
--noul departament.
--b.Folositi un parametru pentru numele departamentului.
--c.Lasati locatia nula deocamdata
--d.Executati blocul PL/SQL.
--e.Afisati noul departament creat.
declare
v_max_deptno dept.deptno%type;
v_dname dept.dname%type:='Finance';
v_result number(2);
begin
select max(deptno)
into v_max_deptno
from dept;
insert into dept(deptno,dname)values(v_max_deptno+10,v_dname);
v_result:=sql%rowcount;
dbms_output.put_line(v_max_deptno+10 ||' '||v_dname);
dbms_output.put_line(v_result || ' row(s) inserted');
end;
--3.Creati un bloc PL/SQL care sa actualizeze locatia pentru un departament existent.
--a.Folositi un parametru pentru nr departamentului.
--b.Folositi un parametru pentru locatia departamentului.
--c.Testati blocul PL/SQL.
--d.Afisati nr dept, numele dept si locatia pentru departamentul updatat.
--e.Afisati departamentul actualizat.
declare
v_deptno dept.deptno%type:=50;
v_dname dept.dname%type:='Finance';
v_loc dept.loc%type:='San Francisco';
v_result number(2);
begin
update dept
set loc = v_loc
where deptno=v_deptno;
v_result:=sql%rowcount;
dbms_output.put_line(v_deptno||' '||v_dname||' '||v_loc);

dbms_output.put_line(v_result || ' row(s) updated.');


commit;
end;
--alta varianta
accept p_deptno prompt 'Dati nr dep: '
accept p_loc prompt 'Dati orasul dep: '
begin
update dept
set loc = '&p_loc'
where deptno = &p_deptno;
commit;
end;
--verificare
select * from dept
where deptno=&p_deptno
--4.Creati un bloc PL/SQL care sa stearga departamentul creat la exercitiul 2.
--a.folositi un parametru pentru numarul departamentului.
--b.afisati pe ecran nr liniilor afectate.
--c.testati blocul PL/SQL.
--d.Ce se intampla daca introduceti un nr de departament care nu exista?
--e.Verificati daca departamentul a fost scos
declare
v_deptno dept.deptno%type;
v_dname dept.dname%type:='Finance';
v_result number(2);
begin
delete
from dept
where dname=v_dname;
v_result:=sql%rowcount;
dbms_output.put_line(v_result||' row(s) deleted.');
end;
--sau
accept p_deptno prompt 'Dati nr departamentului: '
declare
v_result number(2);
begin
delete
from dept
where deptno=&p_deptno;
v_result:=sql%rowcount;
dbms_output.put_line(to_char(v_result)|| ' row(s) deleted.');
commit;
end;
--Exemple din cartea de laborator
--1.Sa se selecteze numarul si locatia departamentului pentru departamentul de vanzari
--se specifica acelasi numar de variabile de iesire in clauza into ca cel de coloane de date din clauza select
declare

v_deptno number(2);
v_loc varchar2(15);
begin
select deptno,loc
into v_deptno,v_loc
from dept
where dname='Sales';
dbms_output.put_line('Numarul departamentului de vanzari este '||v_deptno||', iar acesta se afla in '||v_loc||'.');
end;
--2.Sa se returneze data comenzii si data de onorare pentru ordinea specificata
declare
v_orderdate ord.orderdate%type;
v_shipdate ord.shipdate%type;
begin
select orderdate,shipdate
into v_orderdate,v_shipdate
from ord
where ordid=617;
dbms_output.put_line('Data comenzii pentru produsul cu id-ul 157 este '||v_orderdate||', iar data onorarii este
'||v_shipdate);
end;
--3.Sa se returneze suma salariilor pentru toti angajatii dintr-un departament specificat
declare
v_sum_sal emp.sal%type;
v_deptno number not null:=10;
begin
select sum(sal)
into v_sum_sal
from emp
where deptno=v_deptno;
dbms_output.put_line('Suma salariilor angajatilor din departamentul '||v_deptno||' este '||v_sum_sal||' dollars per
month.');
end;
--4.Sa se adauge noi angajati in tabela emp
--mai intai se realizeaza o secventa
--increment by - specifica pasul de incrementare, implicit este 1
--start with - specifica prima valoare a secventei, implicit este 1
--maxvalue - valoarea maxima pe care secventa o poate genera
--cycle - secventa continua sa genereze valori dupa ce s-a atins valoarea maxima sau minima
--nocycle - nu genereaza valori aditionale, complementara lui cycle
--cache - specifica numarul de valori pe care serverul Oracle le va prealoca si le pastreaza in memorie, implicit sunt 20
de valori
create sequence empno_sequence
increment by 1
start with 8000
maxvalue 8100
nocache

nocycle
-declare
v_empno emp.empno%type;
v_result number(2);
begin
select empno_sequence.nextval
into v_empno
from dual;
insert into emp(empno,ename,job,deptno) values (v_empno,'Harding','Clerk',10);
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) inserted.');
end;
--verificare
select * from emp;
rollback;
select * from emp;
--5.Sa se mareasca salariul tuturor angajatilor din tabela emp care sunt analisti
declare
v_job emp.job%type:='Analyst';
v_sal_increase emp.sal%type:=2000;
v_result number(2);
begin
update emp
set sal=sal+v_sal_increase
where job=v_job;
v_result:=sql%rowcount;
dbms_output.put_line(v_result|| ' row(s) updated.');
end;
-select empno,ename,sal
from emp
where job='Analyst';
rollback;
select empno,ename,sal
from emp
where job='Analyst';
--6.Sa se stearga liniile care apartin departamentului 10 din tabela emp
declare
v_deptno emp.deptno%type:=10;
v_result number(2);
begin
delete from emp
where deptno=v_deptno;
v_result:=sql%rowcount;
dbms_output.put_line(v_result|| ' row(s) deleted.');
end;
--

select *
from emp
where deptno=10;
rollback;
select *
from emp
where deptno=10;
--7.Sa se stearga itemul a carui order este 605
declare
v_ordid ord.ordid%type:=605;
v_result number(2);
begin
delete from ord
where ordid=v_ordid;
v_result:=sql%rowcount;
dbms_output.put_line(v_result|| ' row(s) deleted.');
end;
-select *
from ord
where ordid=605;
rollback;
select *
from ord
where ordid=605;
--8.Sa se returneze data comenzii si data de onorare a comenzii din tabela ord unde data de onorare este azi.
declare
v_orderdate ord.orderdate%type:='01-08-1986';
v_shipdate ord.shipdate%type:='01-08-1987';
begin
select orderdate,shipdate
into v_orderdate,v_shipdate
from ord
where shipdate=v_shipdate;
dbms_output.put_line('Data comenzii este '||v_orderdate||', iar data onorarii este'||v_shipdate);
end;
--9.Sa se stearga liniile care au nr de ordine specificat in tabela item
declare
v_ordid number:=620;
v_result number(2);
begin
delete from item
where ordid=v_ordid;
v_result:=sql%rowcount;
dbms_output.put_line(v_result ||' row(s) deleted.');
end;
--

select *
from item
where ordid=620;
rollback;
select *
from item
where ordid=620;
--alta varianta
variable v_result number
declare
v_ordid number:=614;
begin
delete from item2
where ordid=v_ordid;
:v_result:=sql%rowcount;
end;
print v_result

--1.Creati tabela messages (text varchar2(50)). Scrieti un bloc PL/SQL pentru a insera numere in tabela messages.
--a.Inserati numerele de la 1 la 10 excluzand 6 si 8.
--b.Realizati commit inainte de finalul blocului
--c.Faceti un select pe tabela messages pentru a verifica daca blocul a functionat bine
drop table messages
-create table messages(
text varchar2(50))
-declare
v_result number(2);
begin
for i in 1..10 loop
if i=6 or i=8 then
null;
else
insert into messages values(i);
end if;
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) inserted.');
commit;
end loop;
end;
-select * from messages
--2.Creati tabela emp2 care are aceeasi structura ca si emp. Creati un bloc PL/SQL care calculeaza valoarea
comisionului
--pentru un angajat dat folosind salariul acestuia.
--a.Inserati un nou angajat in tabela emp2. Angajatul va avea salariul null.
--b.Acceptati nr angajatului ca intrare cu o variabila de substitutie.
--c.Daca salariul angajatului este mai mic ca 1000$ fixati comisionul angajatului la 10% din salar.
--d.Daca salariul angajatului este intre 1000$ si 1500$ fixati comsionul la 15% din salar.
--e.Daca salariul angajatului este mai mare ca 1500$ fixati comsionul la 20% din salar.
--f.Daca salariul angajatului este null fixati comisionul angajatului la 0
--g.commit
--h.Testati blocul PL/SQL pentru fiecare caz folosind urmatoarele cazuri de test:
--nr.angajatului este (7369, 7934, 7499, 8000)
--salariul este (800, 1300, 1600, null)
--comisionul este (80, 195, 320, null)
drop table emp2
-create table emp2 as select * from emp
insert into emp2(empno) values(8000);
-accept p_empno prompt 'Introduceti marca angajatului: '
declare
v_empno emp2.empno%type:=&p_empno;
v_sal emp2.sal%type;

v_comm emp2.comm%type;
v_result number(2);
begin
select sal
into v_sal
from emp2
where empno=v_empno;
if v_sal < 1000 then
v_comm:=.10;
elsif v_sal between 1000 and 1500 then
v_comm:=.15;
elsif v_sal > 1500 then
v_comm:=.20;
else
v_comm:=0;
end if;
update emp2
set comm = sal * v_comm
where empno=v_empno and sal=v_sal;
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) updated.');
commit;
end;
--verificare
select empno,ename,lpad(sal,7)salary,lpad(comm,7)comm
from emp2
where empno in(7369,7934,7499,8000)
order by comm
--3.Modificati exercitiul 1 pentru a insera textul "Numarul este par" sau "Numarul este impar", in functie de paritatea
sau imparitatea
--numarului, in tabela messages. Interogati tabela pentru a vedea daca blocul construit a functionat corect.
declare
v_char varchar2(20);
v_number number(10,2);
v_result number(2);
begin
delete
from messages;
v_char:='101 is the number';
v_number:=to_number(substr(v_char,1,4));
if mod(v_number,2)= 0 then
insert into messages values(v_number,'Numar par');
else
insert into messages values(v_number,'Numar impar');
end if;
v_result:=sql%rowcount;
dbms_output.put_line(v_char);
dbms_output.put_line(v_number);
dbms_output.put_line(v_result ||' row(s) inserted.');

end;
--sau
--drop table messages
create table messages
(result number(6),
text varchar2(25));
-declare
v_result number(2);
begin
for i in 1..10 loop
if mod(i,2)=0 then
insert into messages values (i,'par');
else
insert into messages values (i,'impar');
end if;
end loop;
commit;
end;
-select * from messages
--4.Adaugati o coloana noua numita stars la tabela emp2 pentru a stoca (*)
alter table emp2 add stars varchar2(100);
--5.Creati un bloc PL/SQL care recompenseaza un angajat concatenand un asterisc in coloana stars pentru fiecare 100$
din salariul angajatului.
--Rotunjiti salariul angajatului la cel mai apropiat nr intreg.
--a.Acceptati id-ul angajatului ca intrare intr-o variabila de substitutie.
--b.Initializati o variabila pentru a contine un sir de asteriscuri.
--c.Concatenati un asterisc la sir pentru fiecare 100$ din salar. De exemplu daca un angajat are un salar de 800$, sirul
de
--asteriscuri va contine 8 asteriscuri.
--d.Revizuiti coloana stars pentru angajat dupa metoda de la punctul anterior.
--e.realizati commit
--f.testati blocul pentru un angajat care are salariu.
accept p_empno prompt 'Dati marca angajatului: '
declare
v_empno emp2.empno%type:=&p_empno;
v_stars emp2.stars%type;
v_sal emp2.sal%type;
v_ename emp2.ename%type;
v_result number(2);
begin
select ename,nvl(sal/100,0)
into v_ename,v_sal
from emp2
where empno=v_empno;
for i in 1..v_sal loop

v_stars:=v_stars||'*';
end loop;
update emp2
set stars=v_stars
where empno=v_empno;
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) updated.');
commit;
end;
--verificare
select empno,lpad(sal,7)salary,stars
from emp2
where empno = 7839
order by stars
--Exemple din cartea de laborator
--1.Schimbati denumirea meseriei cu Salesman, numarul departamentului cu 35 si comisionul cu 20% a salariului
curent
--daca numele angajatului este Miller.
declare
v_ename emp2.ename%type;
v_job emp2.job%type;
v_deptno emp2.deptno%type;
v_sal emp2.sal%type;
v_comm emp2.comm%type;
v_result number;
begin
select ename,job,deptno,sal,comm
into v_ename,v_job,v_deptno,v_sal,v_comm
from emp2
where ename='Miller';
if v_ename='Miller' then
v_job:='Salesman';
v_deptno:=35;
v_comm:=v_sal*0.20;
end if;
update emp2
set job=v_job,deptno=v_deptno,sal=v_sal,comm=v_comm
where ename=v_ename;
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) updated.');
end;
--verificare
select ename,deptno,job,sal,comm
FROM emp2
where ename='Miller'
--2.Setati un flag pentru comenzi cand sunt mai putin de 5 zile intre data comenzii si data expedierii
desc ord
alter table ord add (ship_flag varchar2(25))

select * from ord


-declare
v_orderdate ord.orderdate%type:='07-02-1987';
v_shipdate ord.shipdate%type:='08-02-1987';
v_ship_flag ord.ship_flag%type;
begin
select orderdate,shipdate,ship_flag
into v_orderdate,v_shipdate,v_ship_flag
from ord
where orderdate=v_orderdate and shipdate=v_shipdate;
if v_shipdate-v_orderdate<5 then
v_ship_flag:='Acceptat';
else
v_ship_flag:='Neacceptat';
end if;
update ord
set ship_flag=v_ship_flag
where orderdate=v_orderdate and shipdate=v_shipdate;
dbms_output.put_line(v_orderdate || ' ' || v_shipdate || ' ' || v_ship_flag);
end;
--3.Inlocuiti ocupatia cu Manager daca numele angajatului este King. Daca numele angajatului este altul decat King,
atunci
--ocupatia sa fie Clerk.
declare
v_ename emp2.ename%type:='Ward';
v_job emp2.job%type:='Salesman';
v_result number(2);
begin
select ename,job
into v_ename,v_job
from emp2
where ename=v_ename;
if v_ename='King' then
v_job:='Manager';
else
v_job:='Clerk';
end if;
update emp2
set job=v_job
where ename=v_ename;
v_result:=sql%rowcount;
dbms_output.put_line(v_ename || ' ' || v_job);
dbms_output.put_line(to_char(v_result)||' row(s) updated');
end;
--4.Introduceti nr departamentului al noilor angajati pentru a determina bonusul lor
declare
v_deptno emp2.deptno%type:=30;

v_comm emp2.comm%type;
v_result number(2);
begin
select comm
into v_comm
from emp2
where deptno=v_deptno;
if v_deptno=10 then
v_comm:=5000;
elsif v_deptno=20 then
v_comm:=7500;
else
v_comm:=2000;
end if;
update emp2
set comm=v_comm
where deptno=v_deptno;
v_result:=sql%rowcount;
dbms_output.put_line(to_char(v_result)||' row(s) updated');
end;
--5.Pentru o anumita valoare data calculati o alta valoare
accept p_start prompt 'Dati o valoare numerica: '
declare
v_start number(12,2):=&p_start;
begin
if v_start > 100 then
v_start:=2*v_start;
elsif v_start>=50 then
v_start:=0.5*v_start;
else
v_start:=0.1*v_start;
end if;
dbms_output.put_line(v_start);
end;

--1.Creati o tabela noua pentru stocarea angajatilor si salariile lor.


drop table top_dogs
-create table top_dogs(
name varchar2(25),
salary number(11,2));
--2.Se citeste de la tastatura marca unui salariat. Scrieti un bloc PL/SQL pentru a stoca numele si salariul
--angajatului respectiv din tabela emp in tabela top_dogs.
--a.declarati doua tabele PL/SQL, ename_table si sal_table, pentru stocarea temporara a numelor si salariilor
--b.transferati numele si salariile din tabelele PL/SQL in tabela top_dogs
--c.afisati continutul tabelei.
accept p_empno prompt 'Va rugam introduceti marca angajatului: '
declare
--doua tabele de tip PL/SQL cu numele ename_table si sal_table
type ename_table_type is table of varchar2(10) index by binary_integer;
type sal_table_type is table of number(7,2) index by binary_integer;
ename_table ename_table_type;
sal_table sal_table_type;
v_empno emp.empno%type:=&p_empno;
v_ename emp.ename%type;
v_sal emp.sal%type;
v_result number(2);
i binary_integer:=0;
begin
delete
from top_dogs;
select ename,sal
into v_ename,v_sal
from emp
where empno=v_empno;
ename_table(i):=v_ename;
sal_table(i):=v_sal;
insert into top_dogs(name,salary)values(ename_table(i),sal_table(i));
v_result:=sql%rowcount;
dbms_output.put_line(v_result || ' row(s) inserted.');
commit;
end;
--verificare
select * from top_dogs
--3. Sa se creeze o tabela de inregistrari PL/SQL plecind de la tabela EMP.
--a.sa se preia, in aceasta tabela, informatiile aferente angajatilor BLAKE, SCOTT, KING si FORD
--b.sa se modifice in tabela emp2 data de angajare astfel:
-- daca este angajat pe data 1 a lunii ramine neschimbat
-- altfel data se modifica astfel incit ziua de angajare sa fie 1 a lunii respective !
--c.sa se afiseze o lista care sa contina: numele, data modificata (acolo unde e cazul) si data originala de angajare din
tabela emp2
--si un atribut 'MODIFICAT/NEMODIFICAT' in functie de comparatia dintre cele 2 date !
declare

type emp2_table_type is table of emp2%ROWTYPE index by binary_integer;


emp2_table emp2_table_type;
v_hiredate emp2.hiredate%type;
i
number:=1;
begin
select ename,hiredate,sal
into emp2_table(i).ename,emp2_table(i).hiredate,emp2_table(i).sal
from emp2
where ename='Blake';
i:=i+1;
select ename,hiredate,sal
into emp2_table(i).ename,emp2_table(i).hiredate,emp2_table(i).sal
from emp2
where ename='Scott';
i:=i+1;
select ename,hiredate,sal
into emp2_table(i).ename,emp2_table(i).hiredate,emp2_table(i).sal
from emp2
where ename='King';
i:=i+1;
select ename,hiredate,sal
into emp2_table(i).ename,emp2_table(i).hiredate,emp2_table(i).sal
from emp2
where ename='Ford';
i:=1;
loop
if to_char(emp2_table(i).hiredate,'day')<>'1' then
emp2_table(i).hiredate:=trunc(emp2_table(i).hiredate,'MONTH');
end if;
select hiredate
into v_hiredate
from emp2
where ename=emp2_table(i).ename;
if emp2_table(i).hiredate <> v_hiredate then
dbms_output.put_line(emp2_table(i).ename || '
' ||emp2_table(i).hiredate || ' ' ||
' Modificata !');
else
dbms_output.put_line(emp2_table(i).ename || '
' ||emp2_table(i).hiredate || ' ' ||
' Nemodificata !');
end if;
i:= i+1;
if emp2_table.exists(i) then
null;
else
exit;
end if;
end loop;
end;

v_hiredate ||

v_hiredate ||

--Exemplu din cartea de laborator


--1.Sa se creeze o tabela PL/SQL
--pentru stocarea numelui angajatilor si a datei lor de angajare
create table ename_hiredate(
nume varchar2(25),
data_ang date);
--se creeaza tipul ename_table_type pentru stocarea numelui angajatilor
--se creeaza tipul hiredate_table_type pentru stocarea datei de angajare
--apoi se creeaza tabelele ename_table si hiredate_table care sunt de tipul ename_table_type si respectiv
hiredate_table_type
--table.exists(i) intoarce true daca cel putin o linie cu indexul i este returnata (se foloseste pentru evitarea unei erori
determinata
--de apelul unui element inexistent al tabelei)
accept p_ename prompt 'Dati numele angajatului: '
accept p_hiredate prompt 'Dati data de angajare: '
declare
type emp_table_type is table of emp%rowtype index by binary_integer;
emp_table emp_table_type;
v_ename emp.ename%type:='&p_ename';
v_hiredate emp.hiredate%type:='&p_hiredate';
i binary_integer:=0;
begin
delete from ename_hiredate;
select ename,hiredate
into emp_table(i).ename,emp_table(i).hiredate
from emp
where ename=v_ename and hiredate=v_hiredate;
if emp_table.exists(i) then
insert into ename_hiredate(nume,data_ang)values(emp_table(i).ename,emp_table(i).hiredate);
commit;
end if;
end;
--verificare
select * from ename_hiredate

--1.Creati un bloc PL/SQL care sa determine primii angajati in ordinea salariilor.


--a.Cititi de la tastatura nr de angajati ce trebuie afisati
--b.Puneti numele si salariile in tabela top_dogs
--c.Presupuneti ca nu exista doi angajati cu acelasi salar
--d.Testati o varietate de cazuri, precum n = 0, cand n este mai mare decat nr de angajati din tabela emp.
--Goliti tabela top_dogs dupa fiecare test.
accept p_number prompt 'Va rugam introduceti numarul de angajati din topul celor mai bine platiti angajati: '
declare
v_number number(3):=&p_number;
v_ename emp.ename%type;
v_sal emp.sal%type;
cursor top_salarii_cursor is
select ename,lpad(sal,7)salary
from emp
where sal is not null
order by sal desc;
begin
delete
from top_dogs;
open top_salarii_cursor;
fetch top_salarii_cursor into v_ename,v_sal;
while top_salarii_cursor%rowcount <= v_number and top_salarii_cursor%found loop
insert into top_dogs(name,salary)values(v_ename,v_sal);
fetch top_salarii_cursor into v_ename,v_sal;
end loop;
close top_salarii_cursor;
commit;
end;
--verificare
select * from top_dogs
--2.Considerati cazul in care cativa angajati au acelasi salariu. Daca o persoana este afisata, atunci toate persoanele cu
acelasi
--salariu trebuie de asemenea afisate.
accept p_number prompt 'Va rugam introduceti numarul de angajati din topul celor mai bine platiti angajati: '
declare
v_number number(3):=&p_number;
v_ename emp.ename%type;
v_current_sal emp.sal%type;
v_last_sal emp.sal%type;
cursor top_salarii_cursor is
select ename,sal
from emp
where sal is not null
order by sal desc;
begin
delete
from top_dogs;
open top_salarii_cursor;
fetch top_salarii_cursor into v_ename,v_current_sal;

while(top_salarii_cursor%rowcount <= v_number or v_current_sal = v_last_sal)and top_salarii_cursor%found loop


insert into top_dogs(name,salary)values(v_ename,v_current_sal);
v_last_sal:=v_current_sal;
fetch top_salarii_cursor into v_ename,v_current_sal;
end loop;
close top_salarii_cursor;
commit;
end;
--verificare
select * from top_dogs
--3.Scrieti o interogare pentru a extrage departamentele si angajatii din fiecare departament. Introduceti rezultatele in
tabela
--messages. Folositi un cursor pentru a extrage numarul departamentului si pasati numarul departamentului unui
cursor pentru
--a extrage angajatii din acel departament.
declare
v_current_deptno dept.deptno%type;
v_ename varchar2(50);
cursor dept_cursor is
select deptno
from dept
order by deptno;
cursor emp_cursor(v_deptno number) is
select ename || ' - department '||to_char(deptno)
from emp
where deptno = v_deptno;
begin
delete
from messages;
open dept_cursor;
loop
fetch dept_cursor into v_current_deptno;
exit when dept_cursor%notfound;
if emp_cursor%isopen then
close emp_cursor;
end if;
open emp_cursor (v_current_deptno);
loop
fetch emp_cursor into v_ename;
exit when emp_cursor%notfound;
insert into messages(results) values (v_ename);
end loop;
close emp_cursor;
end loop;
close dept_cursor;
commit;
end;
--verificare
select * from messages

--Exemple din cartea de laborator


--1.Incarca primii zece angajati unul cate unul, in ordinea marcii acestora
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
i number:=1;
cursor c1 is
select empno,ename
from emp
order by empno;
begin
open c1;
for i in 1..10 loop
fetch c1 into v_empno,v_ename;
dbms_output.put_line(v_empno ||' - '|| v_ename);
end loop;
close c1;
end;
--sau
declare
v_empno emp.empno%type;
v_ename emp.ename%type;
i number:=1;
cursor c1 is
select empno,ename
from emp
order by empno;
begin
open c1;
loop
fetch c1 into v_empno,v_ename;
exit when c1%rowcount>10 or c1%notfound;
dbms_output.put_line(v_empno ||' - '|| v_ename);
end loop;
close c1;
end;
--2.Aduce angajatii unul cate unul pana nu a mai ramas nici un angajat.
declare
cursor c1 is
select empno,ename
from emp;
emp_record c1%rowtype;
begin
for emp_record in c1 loop
if emp_record.empno=7839 then
dbms_output.put_line(emp_record.empno||' - '|| emp_record.ename);
end if;
end loop;

end;
--alta varianta in care nu este nevoie sa se declare cursorul
begin
for emp_record in (select empno,ename from emp) loop
if emp_record.empno=7839 then
dbms_output.put_line(emp_record.empno||' - '|| emp_record.ename);
end if;
end loop;
end;
--3.Sa se preia angajatii pe baza numarului departamentului si a numelui meseriei
declare
cursor c_deptno_job
(v_deptno number,v_job varchar2)is
select empno,ename
from emp
where deptno=v_deptno and job=v_job;
emp_record c_deptno_job%rowtype;
begin
open c_deptno_job(30,'Salesman');
loop
fetch c_deptno_job into emp_record;
exit when c_deptno_job%notfound;
dbms_output.put_line(emp_record.empno||' - '||emp_record.ename);
end loop;
close c_deptno_job;
end;
--4.Sa se determine marca si numele angajatilor in functie de nr departamentului
declare
cursor c_empno_ename
(v_deptno number)is
select empno,ename
from emp
where deptno=v_deptno;
begin
for emp_record in c_empno_ename(30)
loop
dbms_output.put_line(emp_record.empno|| ' - ' ||emp_record.ename);
end loop;
end;
--varianta clasica, fara for
declare
cursor c_empno_ename
(v_deptno number)is
select empno,ename
from emp
where deptno=v_deptno;
emp_record c_empno_ename%rowtype;
begin

open c_empno_ename(30);
loop
fetch c_empno_ename into emp_record;
exit when c_empno_ename%notfound;
dbms_output.put_line(emp_record.empno||' - ' ||emp_record.ename);
end loop;
close c_empno_ename;
end;
--5.Sa se afle numele angajatilor pe baza marcii si job-ului acestora.
--se folosesc acum doi parametri in definirea cursorului
declare
cursor cursor_emp_details
(v_empno number,v_job char)is
select empno,ename,job
from emp
where empno=v_empno and job=v_job;
begin
for emp_record in cursor_emp_details(7792,'Manager')
loop
dbms_output.put_line(emp_record.empno||' ' ||emp_record.ename||' '||emp_record.job);
end loop;
end;
--varianta clasica, fara for
declare
cursor cursor_emp_details
(v_empno number,v_job char)is
select empno,ename,job
from emp
where empno=v_empno and job=v_job;
emp_record cursor_emp_details%rowtype;
begin
open cursor_emp_details(7792,'Manager');
loop
fetch cursor_emp_details into emp_record;
exit when cursor_emp_details%notfound;
dbms_output.put_line(emp_record.empno||' ' ||emp_record.ename||' '||emp_record.job);
end loop;
end;
--6.Exemplu de utilizare a cursoarelor pentru actualizare
--Se actualizeaza salariile angajatilor care au salariul sub 2000 dolari pe luna
--uneori se doreste blocarea liniilor inainte de o operatiune de stergere sau de actualizare, iar pentru acest lucru
--se foloseste clauza for update in cadrul cursorului, care trebuie asezata ca ultima clauza, chiar si dupa order by, daca
exista
--nowait returneaza o eroare daca liniile sunt blocate de o alta sesiune
--mai intai sunt blocate liniile ce se doresc a fi actualizate pentru clauza for update, iar apoi pentru actualizare este
--utilizata clauza where current of (este actualizata fiecare linie procesata de fetch)
declare
cursor c_update_sal is

select empno,sal
from emp2
where sal<=2000 for update nowait;
emp_record c_update_sal%rowtype;
v_result number(2);
begin
open c_update_sal;
loop
fetch c_update_sal into emp_record;
exit when c_update_sal%notfound;
update c_update_sal
set sal=emp_record.sal*1.1;
where current of c_update_sal;
end loop;
v_result:=sql%rowcount;
dbms_output.put_line(v_result ||' row(s) updated.');
close c_update_sal;
commit;
end;
--varianta cu for
declare
cursor c_update_sal is
select empno,sal
from emp2
where sal < 2000 for update nowait;
emp_record c_update_sal%rowtype;
v_result number(2);
begin
for emp_record in c_update_sal
loop
update emp2
set sal=emp_record.sal*1.1
where current of c_update_sal;
end loop;
v_result:=sql%rowcount;
dbms_output.put_line(v_result ||' row(s) updated.');
commit;
end;
--7.Sa se creeze un raport pe mai multe nivele, in care sa se afiseze angajatii pe departamente
declare
cursor c_dept is
select deptno,dname
from dept
order by dname;
cursor c_emp
(v_deptno number)is
select ename
from emp
where deptno=v_deptno

order by ename;
v_dept c_dept%rowtype;
v_emp c_emp%rowtype;
begin
open c_dept;
loop
fetch c_dept into v_dept;
exit when c_dept%notfound;
dbms_output.put_line(v_dept.dname||'--');
open c_emp (v_dept.deptno);
loop
fetch c_emp into v_emp;
exit when c_emp%notfound;
dbms_output.put_line(v_emp.ename);
end loop;
close c_emp;
end loop;
close c_dept;
end;
--8.Construiti un cursor care sa afiseze marca si salariul angajatilor, dand cate o steluta la fiecare 100 de dolari din
salariu.
accept p_empno prompt 'Dati marca angajatului: '
declare
v_empno emp.empno%type:=&p_empno;
v_stars emp.stars%type:=null;
cursor c1 is
select empno,nvl(round(sal/100),0)sal
from emp
where empno=v_empno
for update nowait;
begin
for emp_record in c1 loop
begin
for i in 1..c1.sal loop
v_stars:=v_stars||'*';
end loop;
update emp
set stars=v_stars
where current of c1;
v_stars:=null;
end;
end loop;
commit;
end;

--1.Scrieti un bloc PL/SQL care sa selecteze numele angajatului cu o valoare data a salariului:
--a.Daca salariul introdus returneaza mai mult de un rand, tratati exceptia cu o exceptie tratata asemanatoare si
introduceti
--in tabelul messages, mesajul "Mai mult de un angajat cu salariul < salariu >".
--b.Daca salariul introdus nu returneaza nici un rand, tratati exceptia cu o exceptie tratata asemanatoare si introduceti
--in tabloul messages, mesajul "Nu este nici un angajat cu salariul < salariu >".
--c.Daca salariul introdus returneaza numai un rand, introduceti in tabloul messages numele angajatului si valoarea
salariului
--d.Tratati orice alta exceptie cu o exceptie tratata asemanatoare si introduceti in tabloul messages, mesajul
--"S-au mai produs alte erori".
--e.Testati blocul pentru mai multe cazuri (situatii).
accept p_sal prompt 'Introduceti valoarea salariului: '
declare
v_ename emp.ename%type;
v_sal emp.sal%type:=&p_sal;
begin
delete from messages;
select ename
into v_ename
from emp
where sal=v_sal;
insert into messages(results)values(v_ename || ' ' || v_sal);
exception
when too_many_rows then
insert into messages(results)values('Mai mult de un angajat cu salariul '||to_char(v_sal));
when no_data_found then
insert into messages(results)values('Nu este nici un angajat cu salariul '||to_char(v_sal));
when others then
insert into messages(results)values('S-au mai produs alte erori.');
end;
--2.Creati un bloc PL/SQL care sa actualizeze locatia pentru un departament existent.
--a.Folositi o variabila citita de la tastatura pentru nr departamentului
--b.Introduceti de la tastatura locatia departamentului
--c.Tratati cazul in care departamentul introdus nu exista in tabela
--d.Testati blocul PL/SQL
--e.Afisati nr departamentului, numele departamentului si locatia pentru departamentul actualizat sau mesajul de
eroare
accept p_deptno prompt 'Introduceti numarul departamentului: '
accept p_loc prompt 'Introduceti locatia departamentului: '
declare
e_invalid_dept exception;
v_deptno dept.deptno%type:=&p_deptno;
v_loc dept.loc%type:='&p_loc';
begin
update dept
set loc=v_loc
where deptno=v_deptno;

if sql%notfound then
raise e_invalid_dept;
else
dbms_output.put_line(v_deptno|| ' ' ||v_loc);
rollback;
end if;
exception
when e_invalid_dept then
dbms_output.put_line('Departamentul '||to_char(v_deptno)||' nu exista !');
end;
--3.Scrieti un bloc PL/SQL care tipareste numele angajatilor care au cu 100$ mai mult sau mai putin la salar fata de
valoarea
--salariului introdus:
--a.Daca nu este nici un angajat al carui salar sa se incadreze in aceasta valoare, tipariti un mesaj utilizatorului
--indicandu-i acest lucru. Folositi o exceptie pentru acest caz.
--b.Daca sunt unul sau mai multi angajati ale caror salarii se incadreaza in aceasta valoare, mesajul va trebui sa indice
--cati angajati au un salar ce se incadreaza in valoarea respectiva.
--c.Tratati orice alta exceptie cu o exceptie asemanatoare, mesajul va trebui sa indice daca au mai aparut si alte erori.
accept p_sal prompt 'Introduceti valoarea salariului: '
declare
v_sal emp.sal%type:=&p_sal;
v_sub_sal emp.sal%type:=v_sal-100;
v_peste_sal emp.sal%type:=v_sal+100;
v_ename emp.ename%type;
v_nr number(1);
v_current_sal emp.sal%type;
v_last_sal emp.sal%type;
e_no_emp exception;
e_more_than_one_emp exception;
e_one_emp exception;
cursor c1 is
select ename,sal
from emp
where sal is not null
order by sal desc;
begin
select count(*)
into v_nr
from emp
where sal between v_sub_sal and v_peste_sal;
if v_nr=0 then
raise e_no_emp;
elsif v_nr=1 then
raise e_one_emp;
elsif v_nr>1 then
raise e_more_than_one_emp;
end if;
exception
when e_no_emp then

dbms_output.put_line('Nu exista nici un angajat cu salariul cuprins intre '||to_char(v_sub_sal) || ' si


'||to_char(v_peste_sal));
when e_one_emp then
dbms_output.put_line('Exista ' ||to_char(v_nr)||' angajat(i) cu salariul cuprins intre '||to_char(v_sub_sal)||' si
'||to_char(v_peste_sal)||' si poarta numele de '||v_ename);
select ename
into v_ename
from emp
where sal between to_char(v_sub_sal) and to_char(v_peste_sal);
dbms_output.put_line(v_ename);
when e_more_than_one_emp then
dbms_output.put_line('Exista '||to_char(v_nr)||' angajat(i) cu salariul cuprins intre '||to_char(v_sub_sal)||' si
'||to_char(v_peste_sal));
open c1;
loop
fetch c1 into v_ename,v_current_sal;
exit when c1%notfound;
if (v_current_sal<v_peste_sal and v_current_sal>v_sub_sal) then
dbms_output.put_line(v_ename || ' ' ||v_current_sal);
end if;
end loop;
close c1;
when others then
dbms_output.put_line('Au aparut alte erori.');
end;
--4.Sa se trateze (eventuala) exceptie generata de stergerea unuia din departamentele existente in baza de date
--marca unui departament se va da de la tastatura din tabela dept si sa se afiseze atat un mesaj de eroare utilizator cat
si mesajul de eroare
--standard.
--pragma trebuie lansat pe tabela parinte
--fara pragma nu se seteaza exceptia
accept p_deptno prompt 'Introduceti nr dep pe care vreti sa il stergeti: '
declare
v_deptno dept.deptno%type:=&p_deptno;
e_exception exception;
error_message varchar2(50);
pragma exception_init(e_exception,-2292);
begin
delete from dept
where deptno = v_deptno;
exception
when e_exception then
error_message:='Departamentul '||v_deptno||' este referit in tabela emp';
dbms_output.put_line(error_message);
dbms_output.put_line(sqlerrm);
end;
--5.Sa se introduca un departament deja existent in tabela dept.
accept p_deptno prompt 'Introduceti nr departamentului: ';

accept p_dname prompt 'Introduceti numele departamentului:';


accept p_loc prompt 'Introduceti locatia departamentului:' ;
declare
v_deptno dept.deptno%type:=&p_deptno;
v_dname dept.dname%type:='&p_dname';
v_loc dept.loc%type:='&p_loc';
error_message
varchar2(50);
e_exist
exception ;
pragma exception_init(e_exist,-0001);
begin
insert into dept values (v_deptno,'v_dname','v_loc');
exception
when e_exist then
error_message:=
'Departamentul '||v_deptno||' exista deja!!';
dbms_output.put_line(error_message);
end;
--alta varianta
accept p_deptno prompt 'Introduceti nr departamentului: ';
accept p_dname prompt 'Introduceti numele departamentului:';
accept p_loc prompt 'Introduceti locatia departamentului:' ;
declare
v_deptno dept.deptno%type:=&p_deptno;
v_dname dept.dname%type:='&p_dname';
v_loc dept.loc%type:='&p_loc';
error_message
varchar2(70);
begin
insert into dept values (v_deptno,'v_dname','v_loc');
exception
when dup_val_on_index then
error_message:=
'Departamentul '||v_deptno||' exista deja si trebuie sa fie unic!!';
dbms_output.put_line(error_message);
end;
--6.Sa se incerce stergerea unui produs care nu exista
--pragma sterge implicit si liniile din tabela copil
declare
v_prodid product.prodid%type:=100860;
e_products_invalid exception;
/*-2292 este cod prevazut in compilator*/
pragma exception_init(e_products_invalid,-2292);
error_message varchar2(100);
begin
delete from product;
raise e_products_invalid;
exception
when e_products_invalid then
error_message:='Produsul cu id-ul '||v_prodid||' nu exista in baza de date !';
dbms_output.put_line(error_message);
end;
----------------------------------------------se poate face stergerea unui produs din tabela copil (item), chiar daca nu folosesc pragma

declare
v_prodid item.prodid%type:=100860;
e_products_invalid exception;
--pragma exception_init(e_products_invalid,-2292);
error_message varchar2(100);
begin
delete from item
where prodid=v_prodid;
raise e_products_invalid;
exception
when e_products_invalid then
error_message:='Produsul cu id-ul '||v_prodid||' nu exista in baza de date !';
dbms_output.put_line(error_message);
end;
select * from product
select * from item
rollback;

--1.Procedura ce mareste salariul angajatilor din tabela emp cu 10%


create or replace procedure raise_salary
(v_empno in emp.empno%type)
is
begin
update emp
set sal=sal*1.10
where empno=v_empno;
end raise_salary;
--executia
begin
raise_salary(7369);
end;
-select ename,sal
from emp
where empno=7369;
rollback;
select ename,sal
from emp
where empno=7369;
--2.Procedura ce returneaza datele despre un angajat din tabela emp
--parametrii de tip OUT returneaza o valoare apelantului
--se creeaza o procedura cu parametri de tip OUT pentru a prelua informatii despre un angajat
--procedura accepta valoarea 7521 pentru marca angajatului (empno) si preia numele, salariul si eventualul comision
al angajatului
--cu id-ul 7521 in trei parametri de tip OUT
--procedura query_emp are patru parametri formali, din care trei sunt de tip OUT care returneaza valori la mediul
apelant
create or replace procedure query_emp
(v_empno in emp.empno%type,
v_ename out emp.ename%type,
v_sal out emp.sal%type,
v_comm out emp.comm%type)
is
begin
select ename,sal,comm
into v_ename,v_sal,v_comm
from emp
where empno=v_empno;
end query_emp;
--executia
--variabilele v_ename, v_sal si v_comm sunt populate cu informatia preluata dintr-o interogare in cei trei parametri
--de tip OUT corespunzatori
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
v_comm emp.comm%type;
begin

query_emp(7654,v_ename,v_sal,v_comm);
dbms_output.put_line('Name: ' || v_ename);
dbms_output.put_line('Salary: ' || v_sal);
dbms_output.put_line('Commission: ' || v_comm);
end;
--sau
declare
v_empno emp.empno%type:=7654;
v_ename emp.ename%type;
v_sal emp.sal%type;
v_comm emp.comm%type;
begin
query_emp(v_empno,v_ename,v_sal,v_comm);
dbms_output.put_line('Marca: ' || v_empno);
dbms_output.put_line('Name: ' || v_ename);
dbms_output.put_line('Salary: ' || v_sal);
dbms_output.put_line('Commission: ' || v_comm);
end;
--3.Procedura care afiseaza formatul unui nr de telefon
create or replace procedure format_phone
(v_phone_no in out varchar2)
is
begin
v_phone_no:='(' || substr(v_phone_no,1,3) || ')' || substr(v_phone_no,4,3) || '-' || substr(v_phone_no,7);
end format_phone;
--executia
declare
a_phone_no varchar2(15):=589858475664334;
begin
dbms_output.put_line('Telefon number: ' || a_phone_no);
end;
--4.Procedura pentru adaugarea unui departament pe baza unei secvente
--se creeaza mai intai secventa
create sequence dept_deptno
increment by 1
start with 41
maxvalue 100
nocache
nocycle
-create or replace procedure add_dept
(v_dname in dept.dname%type default 'unknown',
v_loc in dept.loc%type default 'unknown')
is
begin
insert into dept values(dept_deptno.nextval,v_dname,v_loc);
end add_dept;
--executia

begin
--add_dept;
--add_dept('training','New York');
--add_dept(v_loc=>'Dallas',v_dname=>'Education');
add_dept(v_loc=>'Boston');
end;
--verificare
select *
from dept;
rollback;
select *
from dept;
--5.Invocarea unei proceduri (cresterea salariului pe baza unei proceduri deja existente)
create or replace procedure process_emps
is
cursor emp_cursor is
select empno
from emp;
begin
for emp_record in emp_cursor loop
raise_salary(emp_record.empno);
end loop;
end process_emps;
--executie
begin
raise_salary(7369);
end;
--verificare
select sal
from emp
where empno=7369;
rollback;
select sal
from emp
where empno=7369;
--Exercitii propuse in cartea de laborator
--1.Creati si apelati procedura add_prod astfel:
--a.add_prod va insera un produs nou in tabela product
--b.apelati procedura si apoi interogati tabela pentru a vedea rezultatele
--c.apelati procedura cu prodid avand valoarea 100860
create or replace procedure add_prod
(v_prodid in product.prodid%type,
v_descrip in product.descrip%type)
is
e_exist exception;
pragma exception_init(e_exist,-0001);
begin
insert into product values(v_prodid,v_descrip);

exception
when e_exist then
dbms_output.put_line('Produsul cu codul ' ||v_prodid||' exista in baza de date! ');
dbms_output.put_line(sqlerrm);
end;
/
--begin
--add_prod(100860,'Ace Tennis Racket I');
--end;
/
--sau
begin
add_prod(200011,'Minge fotbal World Cup 2014');
end;
-select * from product
where prodid=200011;
rollback;
select * from product
where prodid=200011;
--varianta cu secventa
create sequence product_prodid
increment by 1
start with 200400
maxvalue 200500
nocache
nocycle
-create or replace procedure add_prod1
(v_descrip in product.descrip%type default 'unknown')
is
begin
insert into product values(product_prodid.nextval,v_descrip);
end add_prod1;
/
begin
add_prodd1;
--add_prodd1('Armani Jeans');
--add_prodd1('Valentino Shoes');
end;
/
select * from product;
rollback;
select * from product;
--2.Creati procedura upd_prod astfel:
--a.upd_prod va actualiza descrierea unui produs dat ca parametru. Includeti cod si pentru tratarea exceptiilor
--b.Apelati procedura cu diversi parametri si apoi interogati tabela pentru a vedea rezultatele. Testati si cazurile
--corespunzatoare pentru tratarea exceptiilor

create or replace procedure upd_prod


(v_prodid in product.prodid%type,
v_descrip in product.descrip%type)
is
e_not_exist exception;
begin
update product
set descrip=v_descrip
where prodid=v_prodid;
if sql%notfound then
raise e_not_exist;
end if;
exception
when e_not_exist then
dbms_output.put_line('Produsul cu id-ul '||v_prodid||' nu se regaseste in baza de date ! ');
dbms_output.put_line(sqlcode||' '||sqlerrm);
end;
/
begin
upd_prod(101863,'Badminton Racket');
end;
/
select * from product
where prodid=101863;
rollback;
select * from product
where prodid=101863;
--3.Creati procedura del_prod astfel:
--a.Procedura del_prod va sterge un produs dat. Includeti partea de tratare a exceptiilor
--b.Testati procedura pentru diferite cazuri.
create or replace procedure del_prod
(v_prodid in item.prodid%type)
is
e_not_exist exception;
begin
delete from item
where prodid=v_prodid;
if sql%notfound then
raise e_not_exist;
end if;
exception
when e_not_exist then
dbms_output.put_line('Produsul cu id-ul '||v_prodid||' nu se regaseste in baza de date !');
dbms_output.put_line(sqlcode||' '||sqlerrm);
end;
--executia
begin
del_prod(100860);
--del_prod(100001);

end;
-select * from item;
rollback;
select * from item;
--4.Creati procedura query_emp astfel:
--a.query_emp va extrage salariul si meseria pentru un angajat dat.
--b.Testati procedura pentru angajatul cu nr 7839
--c.Testati procedura pentru angajatul cu nr 98989
create or replace procedure query_emp
(v_empno in emp.empno%type,
v_sal out emp.sal%type,
v_job out emp.job%type)
is
begin
select sal,job
into v_sal,v_job
from emp
where empno=v_empno;
dbms_output.put_line('Angajatul cu marca '||v_empno||' are salariul '||v_sal||' si este '||v_job);
exception
when no_data_found then
dbms_output.put_line('Angajatul cu marca '||v_empno||' nu exista in baza de date!');
end;
--executia
declare
v_sal emp.sal%type;
v_job emp.job%type;
begin
query_emp(7839,v_sal,v_job);
dbms_output.put_line('Salary: '||v_sal);
dbms_output.put_line('Job: '||v_job);
query_emp(98989,v_sal,v_job);
dbms_output.put_line('Salary: '||v_sal);
dbms_output.put_line('Job: '||v_job);
end;
--Alte exercitii
--1.Scrieti o procedura stocata pentru calculul impozitului pt.salariu atunci cnd acesta este calculat pe baza transelor
de
--impozitare si nu ca procent fix dedus din salariu. Adaugati si salariul net ca diferenta dintre salariul brut si impozit.
CREATE OR REPLACE PROCEDURE calcul_impozit_salariu_net
(v_sal emp.sal%type)
IS
v_impozit number(10):=0;
v_salar_net number(10):=0;
BEGIN
delete from messages;
IF v_sal between 3001 and 9999 THEN

v_impozit := (v_sal * 0.6);


v_salar_net:=v_sal-v_impozit;
ELSIF v_sal between 2001 and 3000 THEN
v_impozit := (v_sal * 0.35);
v_salar_net:=v_sal-v_impozit;
ELSIF v_sal between 1401 and 2000 THEN
v_impozit := (v_sal * 0.2);
v_salar_net:=v_sal-v_impozit;
ELSIF v_sal between 1201 and 1400 THEN
v_impozit := (v_sal * 0.15);
v_salar_net:=v_sal-v_impozit;
ELSIF v_sal between 700 and 1200 THEN
v_impozit := (v_sal * 0.1);
v_salar_net:=v_sal-v_impozit;
END IF;
insert into messages values('Salariu: '||v_sal|| ' - Impozit: '||v_impozit || ' - Salariu net: ' ||v_salar_net);
END calcul_impozit_salariu_net;
--apelul
begin
calcul_impozit_salariu_net(2330);
end;
--2.a)Sa se creeze o procedura care modifica salariile angajatilor dintr-un departament dat ca parametru prin
adaugarea la salariul acestora
--a inca 10% din valoarea departamentului lor.
create or replace procedure modifica_salariu(
v_empno emp.empno%type,
v_deptno emp.sal%type)
is
begin
update emp
set sal=sal+v_deptno/10
where empno=v_empno;
end modifica_salariu;
/
begin
modifica_salariu(7839,10);
end;
/
select ename,empno,sal
from emp
where empno=7839;
/
rollback;
/
select ename,empno,sal
from emp
where empno=7839;
--2.b).Sa se creeze doua proceduri astfel:

--o prima procedura care preia angajatii dintr-un departament dat ca parametru de intrare si de asemenea sa se mai
determine si nr
--de angajati care isi modifica salariul
--a doua procedura (cea de la punctul 2.a) care este apelata din prima si modifica salariile angajatilor din
departamentul dat ca parametru in
--prima procedura prin adunarea la salariul existent al angajatilor a inca 10% din valoarea departamentului acestora.
create or replace procedure preluare_angajati(
v_deptno in emp.deptno%type,
v_nr out number)
is
cursor c1 is
select empno
from emp
where deptno=v_deptno;
begin
for emp_record in c1 loop
modifica_salariu(emp_record.empno,v_deptno);
v_nr:=c1%rowcount;
end loop;
end preluare_angajati;
/
create or replace procedure modifica_salariu(
v_empno emp.empno%type,
v_deptno emp.sal%type)
is
begin
update emp
set sal=sal+v_deptno/10
where empno=v_empno;
end modifica_salariu;
--apelul
/
declare
v_nr number(3);
v_deptno emp.deptno%type:=10;
begin
preluare_angajati(v_deptno,v_nr);
dbms_output.put_line('Au fost modificati '||v_nr|| ' angajati in departamentul '||v_deptno);
end;
/
select ename,sal
from emp
where deptno=10;
/
rollback;
/
select ename,sal
from emp
where deptno=10;

--3.a)Sa se realizeze o procedura care calculeaza suma platilor pe fiecare client (se va folosi campul total din tabela
ord).
create or replace procedure suma_plati_per_client
(v_custid in customer.custid%type,
v_sum out ord.total%type)
is
cursor c1 is
select total
from ord
where custid=v_custid;
begin
v_sum:=0;
for c1_record in c1 loop
v_sum :=v_sum+c1_record.total;
end loop;
end;
/
declare
v_sum ord.total%type;
begin
suma_plati_per_client(100,v_sum);
dbms_output.put_line('Suma platilor pentru clientul cu marca 100 este: ' || v_sum);
end;
--3.b)Pentru un agent de vanzari dat sa se afiseze clientul care are cea mai mare suma a platilor facute catre clientii
acelui agent.
--Se cere: o procedura care primeste marca agentului de vanzari, trimitand clientii catre procedura de la
--punctul 3.a)(se folosesc campurile custid si repid - ce corespunde marcii agentului de vanzari, empno, din customer)
--care calculeaza suma platilor pe fiecare client si apoi foloseste aceasta suma
--pentru a vedea care este maximul si la ce client. In final procedura intoarce marca clientului si suma aferenta in apel.
--In apel vor fi afisate numele clientului si suma platilor aferente.
--Calculele pentru sumele platilor, respectiv maximul se vor face in bucla, cu cursori
create or replace procedure suma_plati_per_client
(v_custid customer.custid%type,
v_sum out ord.total%type)
is
cursor c1 is
select total
from ord
where custid=v_custid;
begin
v_sum:=0;
for ord_record in c1 loop
v_sum :=v_sum+ord_record.total;
end loop;
end;
/
create or replace procedure maxim_client
(v_repid customer.repid%type,
v_custid
out customer.custid%type,

v_sum out ord.total%type)


is
c_sum ord.total%type;
sum_max
number:=0;
cursor c1 is
select custid
from customer
where repid=v_repid;
begin
for c1_record in c1 loop
suma_plati_per_client(c1_record.custid,c_sum);
if c_sum>=sum_max then
sum_max:=c_sum;
v_custid:=c1_record.custid;
end if;
end loop;
v_sum:=sum_max;
end;
/
accept p_repid prompt 'Dati marca agentului de vanzari: '
declare
v_repid customer.repid%type:=&p_repid;
v_custid
customer.custid%type;
v_sum ord.total%type;
begin
maxim_client(v_repid,v_custid,v_sum);
dbms_output.put_line('Agentul '||v_repid|| ' a vandut clientului '||v_custid || ' produse in valoare de '||v_sum);
end;
/
--alta varianta
create or replace procedure max_client(
v_repid in customer.repid%type,
v_custid out customer.custid%type,
v_sum out ord.total%type)
is
cursor c1 is
select c.custid,sum(total)
from customer c inner join ord o on o.custid=c.custid
where c.repid=v_repid
group by c.custid
order by sum(total)desc;
begin
open c1;
fetch c1 into v_custid,v_sum;
close c1;
end;
/
declare
v_custid customer.custid%type;
v_sum ord.total%type;

begin
max_client(7844,v_custid,v_sum);
dbms_output.put_line('Agentul cu marca 7844 a vandut clientului cu marca '||v_custid||' produse in valoare de
'||v_sum);
end;
--4.a)Realizati o procedura care primeste codul ordinului de plata si intoarce suma de pe ordin (campul total din ord)
create or replace procedure get_total
(v_ordid
ord.ordid%type,
v_custid
out ord.custid%type,
v_total out ord.total%type)
is
begin
select total,custid
into v_total,v_custid
from ord
where ordid=v_ordid;
end;
/
declare
v_custid ord.custid%type;
v_total
ord.total%type;
begin
get_total(610,v_custid,v_total);
dbms_output.put_line('Ordinul de plata cu nr 610 apartine clientului '|| v_custid || ' si are valoarea de ' || v_total);
end;
--4.b)Pentru un produs dat sa se afle ordinul de plata cel mai mic din punct de vedere valoric care il contine, valoarea
acestuia si clientul
--aferent. Se cere o procedura care primeste codul produsului (campul prodid din item) si trimite codul ordinelor de
plata (campul ordid din item)
--care il contin spre procedura de la punctul 4.a) care intoarce totalul de pe respectivul ordin (total din ord).
--Pe baza acestei valori se determina ordinul de plata cu valoarea minima si clientul aferent (campul custid din ord)
--In apel veti afisa codul ordinului de plata (ordid din ord) cu valoarea cea mai mica, valoarea in sine si clientul care a
platit
--cu respectivul ordin de plata.
create or replace procedure get_total
(v_ordid
ord.ordid%type,
v_custid
out ord.custid%type,
v_total out ord.total%type)
is
begin
select total,custid
into v_total,v_custid
from ord
where ordid=v_ordid;
end;
/
create or replace procedure min_order
(v_prodid
item.prodid%type,

v_total out ord.total%type,


v_ordid out ord.ordid%type,
v_cust_min out ord.custid%type
)
is
cursor c1 is
select ordid
from item
where prodid=v_prodid;
v_min ord.total%type :=999999;
v_custid
ord.custid%type;
begin
for c1_record in c1 loop
get_total(c1_record.ordid,v_custid,v_total);
if v_min>=v_total then
v_min:=v_total;
v_cust_min:=v_custid;
v_ordid:=c1_record.ordid;
end if;
end loop;
v_total:=v_min;
end;
/
declare
v_total
ord.total%type;
v_ordid
ord.ordid%type;
v_custid
ord.custid%type;
begin
min_order(100860,v_total,v_ordid,v_custid);
dbms_output.put_line('Produsul cu codul 100860 are valoarea minima de '||v_total||
' pe ordinul '||v_ordid||' de la clientul '||v_custid);
end;
/
--5.a)Sa se realizeze o procedura care calculeaza suma platilor pentru fiecare client (campul total din ord)
create or replace procedure suma_plati_per_client
(v_custid ord.custid%type,
v_total out ord.total%type)
is
cursor c1 is
select total
from ord
where custid=v_custid;
begin
v_total:=0;
for ord_record in c1 loop
v_total:=v_total+ord_record.total;
end loop;
end;
/

declare
v_total
ord.total%type;
begin
suma_plati_per_client(100,v_total);
dbms_output.put_line('Clientul cu nr 100 are plati in valoare de '||v_total);
end;
--5.b)Sa se afiseze numele agentilor de vanzari, comisionul vechi si comisionul nou calculat ca fiind 5% din totalul
vanzarilor fiecaruia.
--Se cere o procedura care calculeaza suma platilor clientilor fiecarui agent de vanzari, pe care-i trimite (campul custid
din customer) spre
--procedura de la punctul 5.a)care calculeaza suma pe fiecare client. Apoi calculeaza suma pe toti clientii agentului pe
care o trimite
--in final spre apel unde se calculeaza noul comision.
create or replace procedure suma_plati_per_client
(v_custid ord.custid%type,
v_total out ord.total%type)
is
cursor c1 is
select total
from ord
where custid=v_custid;
begin
v_total:=0;
for c1_record in c1 loop
v_total:=v_total+c1_record.total;
end loop;
end;
/
create or replace procedure total_plati_clienti_per_agent
(v_repid
customer.repid%type,
v_total out ord.total%type)
is
cursor c1 is
select custid
from customer
where repid=v_repid;
v_plati ord.total%type;
begin
v_total:=0;
for c1_record in c1 loop
suma_plati_per_client(c1_record.custid,v_plati);
v_total:=v_total+v_plati;
end loop;
end;
/
declare
cursor c1 is
select empno,ename,comm
from emp

where job ='Salesman';


v_plati ord.total%type;
v_comm emp.comm%type;
begin
for c1_record in c1 loop
total_plati_clienti_per_agent(c1_record.empno,v_plati);
v_comm:=v_plati*5/100;
dbms_output.put_line('Agentul '||c1_record.ename || ' are comisionul vechi '|| c1_record.comm || ' si noul
comision ' || v_comm);
end loop;
end;
--6.a)Sa se realizeze o procedura care, pe baza unui departament dat, calculeaza media salariilor angajatilor si de
asemenea
--determina si nr angajati.
--pentru a determina media salariilor angajatilor trebuie mai intai sa determinam salariul acestora, facem acest lucru
printr-un cursor
create or replace procedure avg_dept
(v_dname
dept.dname%type,
v_nr_angajati out number,
v_medie_salariala
out number)
is
cursor c1 is
select sal
from emp e inner join dept d
on e.deptno=d.deptno
and dname=v_dname;
v_sum emp.sal%type:=0;
begin
for c1_record in c1 loop
v_sum:=v_sum+c1_record.sal;
v_nr_angajati:=c1%rowcount;
end loop;
v_medie_salariala:= v_sum/v_nr_angajati;
end;
/
declare
v_dname dept.dname%type:='Sales';
v_medie_salariala
number(8,2);
v_nr_angajati number(3);
begin
avg_dept(v_dname,v_nr_angajati,v_medie_salariala);
dbms_output.put_line('Departamentul ' || v_dname ||' are in total '||v_nr_angajati ||' angajati, iar media salariala a
acestora este '||
v_medie_salariala);
end;
--6.b)Pentru un departament dat prin nume se cere:
--a.daca departamentul este de vanzari sa se calculeze media salariilor angajatilor si sa se afiseze media si nr de
angajati

--b.pentru restul departamentelor se vor afisa numele angajatilor si salariile modificate prin adaugarea ultimelor 2
cifre ale marcii
--dar nu mai putin de 20
--Se cer urmatoarele doua proceduri:
--a.o procedura care primeste numele departamentului, determina angajatii, calculeaza media salariala, pe care o
intoarce in apel unde va fi
--afisat un mesaj semnificativ
--b.o procedura care primeste numele departamentului, marca salariatilor si intoarce spre apel valoarea cu care se
modifica salariul. In apel
--se vor afisa numele, marca angajatilor, salariul vechi si noul salariu.
--calculele pentru media salariilor se vor face in bucla, folosind un cursor
create or replace procedure avg_dept
(v_dname
dept.dname%type,
v_nr_angajati out number,
v_medie_salariala
out number)
is
cursor c1 is
select sal
from emp e inner join dept d
on e.deptno=d.deptno
and dname=v_dname;
v_sum emp.sal%type:=0;
begin
for c1_record in c1 loop
v_sum:=v_sum+c1_record.sal;
v_nr_angajati:=c1%rowcount;
end loop;
v_medie_salariala:= v_sum/v_nr_angajati;
end;
/
create or replace procedure modifica_salariu
(v_empno
emp.empno%type,
v_salariu_modificat out number)
is
begin
v_salariu_modificat:= mod(v_empno,100);
if v_salariu_modificat <20 then
v_salariu_modificat:=20;
end if;
end;
/
accept p_dname prompt 'Dati numele departamentului: '
declare
v_dname dept.dname%type:='&p_dname';
v_medie_salariala
number(8,2);
v_nr_angajati number(3);
v_mod number(3);
new_sal
emp.sal%type;
cursor c1 is
select empno,ename,sal

from emp e inner join dept d on e.deptno=d.deptno


where dname=v_dname;
begin
if v_dname ='Sales' then
avg_dept('v_dname',v_medie_salariala,v_nr_angajati);
dbms_output.put_line('Departamentul '|| v_dname ||' are ' ||v_nr_angajati || ' angajati si media
'||v_medie_salariala);
else
for c1_record in c1 loop
modifica_salariu(c1_record.empno,v_mod);
new_sal:=c1_record.sal+v_mod;
dbms_output.put_line(c1_record.ename || ' are marca '||c1_record.empno || ' salariul vechi '|| c1_record.sal || '
si noul salariu '||new_sal) ;
end loop;
end if;
end;
/

--1.Creati si apelati functia q_prod pentru a returna o descriere a produsului


--a.Creati o functie numita q_prod pentru a returna o descriere a produsului intr-o variabila
--b.Compilati codul, apelati functia si apoi interogati variabila pentru a vedea rezultatul
create or replace function q_prod
(v_prodid in product.prodid%type)
return varchar2
is
v_descrip product.descrip%type;
begin
select descrip
into v_descrip
from product
where prodid=v_prodid;
return v_descrip;
end q_prod;
--executia
accept p_prodid prompt "Dati codul produsului: "
begin
dbms_output.put_line('Produsul cu codul '||&p_prodid ||' este: '||q_prod(&p_prodid));
exception
when no_data_found then
dbms_output.put_line('Nu exista produsul cu marca '||&p_prodid);
end;
--2.Creati o functie annual_comp pentru a returna salariul anual unde treceti salariul lunar al unui angajat si
comisionul.

--Asigurati-va ca functia poate gestiona valori de null.


--a.Creati si apelati functia annual_comp, treceti valorile pentru salariul lunar si comision. Functia ar trebui sa
returneze
--salariul anual, definit prin (sal*12)+comm
--b.Folositi functia intr-o instructiune select referitoare la tabelul emp
create or replace function annual_comp
(v_empno in emp.empno%type)
return number
is
v_annual_sal number;
begin
select (sal*12)+nvl(comm,0)
into v_annual_sal
from emp
where empno=v_empno;
return v_annual_sal;
end annual_comp;
--executia
accept p_empno prompt 'Dati marca angajatului: '
declare
v_empno emp.empno%type:=&p_empno;
v_ename emp.ename%type;
v_sal emp.sal%type;
v_comm emp.comm%type;
v_annual_sal number;
begin
select ename,sal,nvl(comm,0),annual_comp(v_empno)
into v_ename,v_sal,v_comm,v_annual_sal
from emp
where empno=v_empno;
dbms_output.put_line('Angajatul '||v_ename||' are salariul lunar '||v_sal||', comisionul '||v_comm ||' si salariul
anual '||v_annual_sal);
exception
when no_data_found then
dbms_output.put_line('Nu exista angajatul cu marca '||v_empno);
end;
--3.Creati o procedura, new_emp, pentru a insera un nou angajat in tabelul emp. Procedura va trebui sa contina un
apel al functiei
--valid_deptno pentru a valida daca nr de departament specificat pentru noul angajat exista in tabelul dept.
--a.Creati o functie valid_deptno pentru a valida un nr de departament specificat. Functia trebuie sa returneze o
valoare de tip boolean.
--b.Apoi creati procedura new_emp pentru a adauga un angajat la tabelul emp. Un nou articol va trebui sa fie adaugat
la emp daca
--functia returneaza true. Daca functia returneaza false, procedura va trebui sa avertizeze utilizatorul cu un mesaj
apropriat.
--Definiti valori default pentru toate argumentele. Comisionul implicit este 0, salariul implicit este 1000, nr de dep
implicit este 30,
--job-ul implicit este salesman si managerul implicit este 7839. Pentru id-ul angajatului folositi secventa seq_empno.

--c.Testati procedura new_emp prin adaugarea unui nou angajat numit Harris in departamentul 99. Lasati toti ceilalti
parametri impliciti.
--Care este rezultatul?
--d.Testati procedura new_emp prin adaugarea unui nou angajat numit Harris in departamentul 30. Lasati toti ceilalti
parametri impliciti.
--Care este rezultatul?
create or replace function valid_deptno
(v_deptno in dept.deptno%type)
return boolean
is
e_dept boolean;
v_number number;
begin
select count(*)
into v_number
from dept
where deptno=v_deptno;
if v_number=0 then
dbms_output.put_line('Departamentul cu marca '||v_deptno||' nu exista !');
e_dept:=false;
else
e_dept:=true;
end if;
return e_dept;
end valid_deptno;
--alta varianta a functiei
/*create or replace function valid_deptno
(v_deptno in dept.deptno%type)
return boolean
is
v_number number;
e_dept boolean;
begin
select count(*)
into v_number
from dept
where deptno=v_deptno;
if v_number=0 then
dbms_output.put_line('Departamentul cu marca '||v_deptno||' nu exista !');
return false;
else
return true;
end if;
return e_dept;
end valid_deptno; */
-create sequence seq_empno
minvalue 8000
start with 8000
increment by 1

-create or replace procedure new_emp


(v_deptno emp.deptno%type:=30,
v_mgr emp.mgr%type:=7839,
v_sal emp.sal%type:=1000,
v_job emp.job%type:='SALESMAN',
v_comm
emp.comm%type:=0,
v_hiredate emp.hiredate%type:=sysdate)
is
begin
if valid_deptno(v_deptno) then
insert into emp(empno,ename,deptno,mgr,hiredate,sal,job,comm)
values(seq_empno.nextval,'Harris',v_deptno,v_mgr,v_hiredate,v_sal,v_job,v_comm);
else
dbms_output.put_line('Nu se poate insera');
end if;
end new_emp;
--apelul proecedurii
begin
--new_emp(99);
new_emp(30);
end;
/
select * from emp
where ename='Harris'
/
delete from emp
where ename='Harris'
/
create or replace procedure new_emp
(v_deptno emp.deptno%type:=30,
v_mgr emp.mgr%type:=7839,
v_sal emp.sal%type:=1000,
v_job emp.job%type:='SALESMAN',
v_comm
emp.comm%type:=0,
v_hiredate emp.hiredate%type:=sysdate,
v_ename emp.ename%type:='Harris')
is
begin
if valid_deptno(v_deptno) then
insert into emp(empno,ename,deptno,mgr,hiredate,sal,job,comm)
values(seq_empno.nextval,v_ename,v_deptno,v_mgr,v_hiredate,v_sal,v_job,v_comm);
else
dbms_output.put_line('Nu se poate insera');
end if;
end new_emp;
--apelul functiei
begin
new_emp(99);
--new_emp();

end;
/
select * from emp
where ename='Harris'
/
delete from emp
where ename='Harris'
/
--Alte exercitii
--4.Returnati salariul unui angajat pe baza id-ului sau
create or replace function get_sal
(v_empno in emp.empno%type)
return number
is
v_sal emp.sal%type:=0;
begin
select sal
into v_sal
from emp
where empno=v_empno;
return v_sal;
exception
when no_data_found then
return null;
end get_sal;
--invocarea functiei
declare
v_sal emp.sal%type;
begin
v_sal := get_sal(7839);
dbms_output.put_line('Angajatul cu marca 7839 are salariul '|| get_sal(7839));
end;
--alta varianta de apel
accept p_empno prompt "Dati marca angajatului: "
begin
dbms_output.put_line('Angajatul cu marca '||&p_empno ||' are salariul: '||get_sal(&p_empno));
end;
--5.Calculul impozitului, cu ajutorul unei functii, pt.salariu atunci cnd acesta este
--calculat pe baza transelor de impozitare si nu ca procent fix
--dedus din salariu.
CREATE OR REPLACE FUNCTION calculeaza_impozit
(v_sal emp.sal%type)
RETURN NUMBER IS
impozit NUMBER := 0;
BEGIN
IF v_sal between 3001 and 9999 THEN
impozit := (v_sal * 0.6);
ELSIF v_sal between 2001 and 3000 THEN

impozit := (v_sal * 0.35);


ELSIF v_sal between 1401 and 2000 THEN
impozit := (v_sal * 0.2);
ELSIF v_sal between 1201 and 1400 THEN
impozit := (v_sal * 0.15);
ELSIF v_sal between 700 and 1200 THEN
impozit := (v_sal * 0.1);
END IF;
RETURN impozit;
END calculeaza_impozit;
/
--apel functie
DECLARE
impozit emp.sal%type;
v_sal emp.sal%type;
salariu_net emp.sal%type;
BEGIN
impozit := calculeaza_impozit(1500);
v_sal :=1500;
salariu_net := v_sal-impozit;
dbms_output.put_line('Impozitul pentru un salariu de 1500 de dolari este ' || impozit);
dbms_output.put_line('Salariul net ' || salariu_net);
END;
--apelul functiei calculeaza_impozit din interiorul unei interogari
select empno,ename,lpad(sal,7)sal,lpad(round(calculeaza_impozit(sal)),7)impozitul
from emp
order by sal
--6.Modificati salariile din tabela emp adaugind, cu ajutorul unei functii, la salariul existent ultima
--cifra a anului de angajare.
create or replace function sal_datang
(v_empno
in emp.empno%type)
return number
is
v_sal_nou
number;
begin
select substr(to_char(hiredate,'YYYY'),4,1)
into v_sal_nou
from emp
where empno=v_empno;
return v_sal_nou;
end sal_datang;
/
declare
v_sal_nou number;
cursor c1 is
select empno
from emp;
begin
for c1_record in c1 loop

v_sal_nou:=sal_datang(c1_record.empno);
update emp
set sal=sal+v_sal_nou
where empno=c1_record.empno;
end loop;
end;
/
select ename,hiredate,sal
from emp
/
rollback
/
select ename,hiredate,sal
from emp
/

You might also like