Sunteți pe pagina 1din 23

ACADEMIA DE STUDII ECONOMICE BUCUREŞTI

FACULTATEA DE CIBERNETICĂ, STATISTICĂ ŞI INFORMATICĂ ECONOMICĂ

RECAPITULARE
LIMBAJELE SQL,
PL/SQL

BUCUREŞTI
2019-2020
SINTAXA COMENZII SELECT

SELECT [DISTINCT] (*/coloana1 [alias], expresii [alias])


FROM tabela1, tabela2, ...
WHERE (conditii, precizarea legaturilor dintre tabele)
GROUP BY nume_tabela.nume_coloana
HAVING (conditii impuse valorilor de grup)
ORDER BY nume_tabela.nume_coloana ASC/DESC;
LIMBAJUL SQL-ORACLE
JONCŢIUNI

Oracle Standard SQL

Joncţiune de egalitate

SELECT t1.a, t2.c SELECT t1.a, t2.c


FROM tabela1 t1, tabela2 t2 FROM tabela1 t1 JOIN tabela2 t2
WHERE t1.b=t2.b; ON t1.b=t2.b;

SELECT t1.a, t2.c


FROM tabela1 t1 NATURAL JOIN tabela2 t2

SELECT t1.a, t2.c


FROM tabela1 t1 JOIN tabela2 t2
USING (b);

3
LIMBAJUL SQL-ORACLE
JONCŢIUNI

Oracle Standard SQL


Joncţiune externă stânga

SELECT t1.a, t2.c SELECT t1.a, t2.c


FROM tabela1 t1, tabela2 t2 FROM tabela1 t1 LEFT JOIN tabela2 t2
WHERE t1.b=t2.b (+); ON t1.b=t2.b;

Joncţiune externă dreapta

SELECT t1.a, t2.c SELECT t1.a, t2.c


FROM tabela1 t1, tabela2 t2 FROM tabela1 t1 RIGHT JOIN tabela2 t2
WHERE t1.b (+)=t2.b; ON t1.b=t2.b;

4
LIMBAJUL SQL-ORACLE
JONCŢIUNI
Oracle Standard SQL
Joncţiune externă completă
SELECT t1.a, t2.c SELECT t1.a, t2.c
FROM tabela1 t1, tabela2 t2 FROM tabela1 t1 FULL JOIN tabela2 t2
WHERE t1.b=t2.b (+) ON t1.b=t2.b;
UNION
SELECT t1.a, t2.c
FROM tabela1 t1, tabela2 t2
WHERE t1.b (+)=t2.b;
Joncţiunea tabelei cu ea însăşi
SELECT t1.a, t2.b SELECT t1.a, t2.b
FROM tabela1 t1, tabela1 t2 FROM tabela1 t1 JOIN tabela1 t2
WHERE t1.a=t2.b; ON t1.a=t2.b;

5
EXERCITII

Afisati pentru fiecare produs comandat denumirea, data comenzii si


valoarea comenzilor pe fiecare zi.
select denumire_produs, data, sum(pret*cantitate)
from produse p, rand_comenzi r, comenzi c
where p.ID_PRODUS=r.ID_PRODUS and
r.NR_COMANDA=c.NR_COMANDA
group by denumire_produs, data;
EXERCITII

select a.nume, a.salariul, d.DENUMIRE_DEPARTAMENT,


case when a.salariul<2000 then 0.1
when a.salariul between 2000 and 5000 then 0.2
else 0.05
end * salariul+salariul majorare
from angajati a, departamente d
where a.ID_DEPARTAMENT=d.ID_DEPARTAMENT;
PL/SQL – PROCEDURAL
LANGUAGE EXTENSION TO SQL
DECLARE (Opţional)
• variabile, cursori, excepţii
BEGIN (Obligatoriu)
• comenzi SQL (asigură accesul la baza de date)
• structuri de programare procedurală PL/SQL
EXCEPTION (Opţional)
• acţiuni ce se execută când apare o eroare
END; (Obligatoriu)
• Tipuri de blocuri PL/SQL:
– Blocuri anonime;
– Funcţii stocate şi funcţii de aplicaţii;
– Proceduri stocate şi proceduri de aplicaţii;
– Pachete;
– Declanşatoare (triggeri) pe baza de date / de aplicaţii.
VARIABILE
• nume_variabila [CONSTANT] TIP_DATA [NOT NULL]
[:= | DEFAULT expresie]
• Atributul %TYPE
variabila tabelă.nume_coloană%TYPE;
sau
variabila1 tip_dată;

--afiseaza numele si prenumele angajatului cu codul 100.


DECLARE
v_nume angajati.nume%TYPE;
v_prenume angajati.prenume%TYPE;
BEGIN
SELECT nume, prenume
INTO v_nume, v_prenume
FROM angajati
WHERE id_angajat = 100;
DBMS_OUTPUT.PUT_LINE('NUMELE ANGAJATULUI ESTE:' || v_nume||'
'||v_prenume);
END;
/
TIPUL RECORD
TYPE nume_record IS RECORD (nume_câmp TIP_DATA [,nume_câmp
TIP_DATA:=|DEFAULT valoare]...);
Variabilă NUME_RECORD;

nume_record.nume_câmp.

NUME_RECORD tabela%ROWTYPE;
CURSORUL ÎN PL/SQL
• Atunci când se execută o comandă SQL, Oracle Server
deschide o zonă de memorie (context area) în care
comanda este executată. Cursorul este un pointer către
această zonă.
• În PL/SQL se utilizează două tipuri de cursoare:
• implicit: declarat pentru toate instrucţiunile PL/SQL de
tip LMD
• explicit: declarat şi gestionat de programator.
CURSORUL EXPLICIT
• se foloseşte pentru a procesa individual fiecare linie (înregistrare)
returnată de o instrucţiune SELECT ce returnează mai multe înregistrări.
• mulţimea înregistrărilor returnate de o instructiune SELECT este numită
mulţime rezultat.
• cursorul păstrează un pointer către linia curentă în cadrul unei mulţimi
rezultat.
• Verificarea stării unui cursor explicit se realizează prin intermediul
următoarelor atribute:
– NUME_CURSOR%ISOPEN;
– NUME_CURSOR%NOTFOUND;
– NUME_CURSOR%FOUND;
– NUME_CURSOR%ROWCOUNT.
PARCURGEREA FOLOSIND OPEN-
LOOP-FECTH-CLOSE
• DECLARE nume_cursor IS SELECT........................;
• OPEN nume_cursor;
• FETCH nume_cursor INTO var1, var2,..............;
• CLOSE nume_cursor;
Exemple:
Să se afişeze lista cu numele şi salariul angajaţilor din departamentul 60 folosind un cursor explicit și trei
variabile scalare:
set serveroutput on open ang_cursor;
declare loop
cursor ang_cursor is select id_angajat, nume, salariul fetch ang_cursor into ang_rec;
from angajati where id_departament=60; exit when ang_cursor%notfound;
--tipul record definit cu %ROWTYPE pt incarcarea dbms_output.put_line('Salariatul '||ang_rec.nume||' are
valorilor cursorului salariul: '||ang_rec.salariul);
ang_rec ang_cursor%rowtype; end loop;
begin close ang_cursor;
dbms_output.put_line('Lista cu salariariile angajatilor end;
din departamentul 60');
PARCURGEREA FOLOSIND FOR-
LOOP
FOR nume_record IN nume_cursor LOOP
--------------------------------------------------------
END LOOP;

Exemplu: Se afişează printr-un ciclu FOR numele şi salariile angajaţilor din departamentul 60:
set serveroutput on
declare
cursor ang_cursor is select id_angajat, nume, salariul from angajati where id_departament=60;
begin
dbms_output.put_line('Lista cu salariariile angajatilor din departamentul 60');
for ang_rec in ang_cursor loop
dbms_output.put_line('Salariatul '||ang_rec.nume||' are salariul: '||ang_rec.salariul);
end loop;
end;/
PARCURGEREA FOLOSIND FOR-
LOOP A UNUI CURSOR INLINE
(ANONIM)
FOR NUME_RECORD IN (SELECT......) LOOP
.....................................................................................
END LOOP;
Exemplu: Să se afişeze suma aferentă salariilor din fiecare departament:
set serveroutput on
declare
begin
dbms_output.put_line('Total salarii pe fiecare departament:');
for dep_rec in
(select d. id_departament dep, sum(a.salariul) sal
from angajati a, departamente d
where a.id_departament=d.id_departament
group by d.id_departament)
loop
dbms_output.put_line('Departamentul '||dep_rec.dep||' are de platit salarii in valoare de: '||dep_rec.sal||' RON');
end loop;
end;
UTILIZAREA CURSORULUI CU
PARAMETRU
CURSOR NUME_CURSOR (PARAMETRU1 TIP_DATA,.....)
IS SELECT .................;
PROCEDURI
Sintaxa pentru crearea unei proceduri:
CREATE [OR REPLACE] PROCEDURE NUME_PROC
[(param1 [IN|OUT|IN OUT] TIP1,
Param2[IN|OUT|IN OUT] TIP2, ....) ]
-- tipul variabilelor este precizat fara dimensiune (ex: NUMBER sau VARCHAR2)
IS|AS
-- zona de declarare a variabilelor utilizate in subprogram
-- NU se utilizeaza DECLARE
BEGIN
----
[EXCEPTION]
------
END [NUME_PROC];

Pentru a sterge procedura:


DROP PROCEDURE NUME_PROC;
Apelul unei proceduri se poate realiza in urmatoarele moduri:
• prin nume dintr-un bloc PL/SQL anonim sau un alt subprogram;
• prin apel direct cu EXECUTE nume_proc sau EXEC nume_proc sau CALL
nume_proc;
• din alt mediu Oracle (Oracle Developer Suite)
PROCEDURI
• Exemplu: Procedura modifica_salariul primeşte doi parametrii: p_id_angajat şi
procent şi majorează cu procentul specificat salariul angajatului cu
id_angajat=p_id_angajat:

CREATE OR REPLACE
PROCEDURE modifica_salariul_procent
(p_id_angajat IN angajati.id_angajat%type, procent IN number)
IS
v_salariul angajati.salariul%type;
BEGIN
Select salariul into v_salariul from angajati where id_angajat=p_id_angajat;
dbms_output.put_line('Angajatul are salariul de '||v_salariul);
Update angajati
Set salariul=salariul*(1+procent/100)
Where id_angajat=p_id_angajat;
Select salariul into v_salariul from angajati where id_angajat=p_id_angajat;
Dbms_output.put_line('Angajatul are acum salariul de '||v_salariul);
END;
FUNCTII
Sintaxa pentru crearea unei functii:
CREATE [OR REPLACE] FUNCTION nume_functie
[(param1 [IN] TIP1,
Param2[IN] TIP2, ....) ]
RETURN TIP_DATA
-- tipul variabilelor este precizat fara dimensiune (ex: NUMBER sau VARCHAR2)
IS|AS
-- zona de declarare a variabilelor utilizate in subprogram
-- nu se utilizeaza DECLARE
BEGIN
----
RETURN VALOARE;
[EXCEPTION]
------
END [NUME_FUNCTIE];

Pentru vizualizarea tipului returnat se utilizeaza:


DESCRIBE nume_functie;

Pentru a sterge functia:


DROP FUNCTION nume_functie;
FUNCTII
Exemplu: Returnează true/false daca salariatul are salariul mai mare/mai mic
sau egal cu salariul mediu si null daca salariatul nu exista

CREATE OR REPLACE FUNCTION verifica_salariul


(p_id_angajat IN angajati.id_angajat%type, p_sal_mediu IN number)
RETURN Boolean
IS
v_salariul angajati.salariul%type;
BEGIN
SELECT salariul into v_salariul from angajati where id_angajat=p_id_angajat;
IF v_salariul > p_sal_mediu then
return true;
ELSE
return false;
end if;
EXCEPTION
WHEN no_data_found THEN
return NULL;
end;
TO DO!
• Afisati pentru fiecare angajat numele, salariul,
denumirea departamentului de care apartine,
valoarea marita a salariului si numarul de comenzi
gestionate de acestia.
Salariul va fi marit astfel:
- Salariul <2000, crestere cu 10%
- Salariul between 2000 and 5000, crestere cu 20%
- Altfel crestere cu 5%
• Să se afişeze pentru fiecare comanda plasata online
data acesteia si lista produsele comandate.
TO DO!

• Create a program to add a new job into the JOBS table.


a. Create a stored procedure called NEW_JOB to enter a new
order into the JOBS table. The procedure should accept
three parameters. The first and second parameters supply a
job ID and a job title. The third parameter supplies the
minimum salary. Use the maximum salary for the new job
as twice the minimum salary supplied for the job ID.
b. Invoke the procedure to add a new job with job ID
'SY_ANAL', job title 'System Analyst', and minimum salary
of 6000.
c. Note the new job ID for use in the next exercise. Commit
the changes.
TO DO!
• In this exercise, create a program to add a new row to the JOB_HISTORY table, for an
existing employee.
a. Create a stored procedure called ADD_JOB_HIST to add a new row into the
JOB_HISTORY table for an employee who is changing his job to the new job ID
('SY_ANAL') that you created in the previous exercise.
The procedure should provide two parameters, one for the employee ID who is
changing the job, and the second for the new job ID. Read the employee ID from
the EMPLOYEES table and insert it into the JOB_HISTORY table. Make the hire
date of this employee as start date and today’s date as end date for this row in the
JOB_HISTORY table. Change the hire date of this employee in the EMPLOYEES
table to today’s date. Update the job ID of this employee to the job ID passed as
parameter (use the 'SY_ANAL' job ID) and salary equal to the minimum salary for
that job ID + 500. Note: Include exception handling to handle an attempt to insert a
nonexistent employee.
b. Execute the procedure with employee ID 106 and job ID 'SY_ANAL' as
parameters.
c. Query the JOB_HISTORY and EMPLOYEES tables to view your changes for
employee 106, and then commit the changes