Sunteți pe pagina 1din 25

LABORATOR 1 SQL - REZUMAT

CERERI MONOTABEL 1. Analizai sintaxa simplificat a comenzii SELECT. Care dintre clauze sunt obligatorii? SELECT { [ {DISTINCT | UNIQUE} | ALL] lista_campuri | *} FROM [nume_schem.]nume_obiect ] [, [nume_schem.]nume_obiect ] [WHERE condiie_clauza_where] [[START WITH condiie_clauza_start_with] CONNECT BY condiie_clauza_connect_by] [GROUP BY expresie [, expresie ] [HAVING condiie_clauza_having] ] [ORDER BY {expresie | poziie} [, {expresie | poziie} ] ] [FOR UPDATE [OF [ [nume_schem.]nume_obiect.]nume_coloan [, [ [nume_schem.]nume_obiect.]nume_coloan] ] [NOWAIT | WAIT numr_ntreg] ]; 2. S se iniieze o sesiune SQL*Plus folosind user ID-ul i parola indicate. 3. a) Consultai diagrama exemplu HR (Human Resources) pentru lucrul n cadrul laboratoarelor SQL. b) Identificai cheile primare i cele externe ale tabelelor existente n schem, precum i tipul relaiilor dintre aceste tabele. 4. S se listeze structura tabelului employees, observnd tipurile de date ale coloanelor. Obs: Se va utiliza comanda SQL*Plus DESCRIBE nume_tabel 5. S se listeze coninutul tabelului departments, afind valorile tuturor cmpurilor. Obs: Se va utiliza comanda SQL SELECT * FROM nume_tabel; 6. S se afieze codul i numele angajatului, adugnd coloanelor cte un alias. 7. S se listeze fr duplicate codurile job-urilor din tabelul employees. SELECT DISTINCT col FROM nume_tabel; 8. S se listeze numele i salariul angajailor care ctig mai mult de 10000 $. 9. S se modifice cererea anterioar astfel nct s afieze numele i salariul pentru toi angajaii al cror salariu este cuprins ntre 5000$ i10000$. Obs: Pentru testarea apartenenei la un domeniu de valori se poate utiliza operatorul [NOT] BETWEEN valoare1 AND valoare2 10. S se afieze numele i salariul pentru toi angajaii din departamentele 10 sau 30, n ordine alfabetic a numelor. Obs: Apartenena la o mulime finit de valori se poate testa prin intermediul operatorului IN, urmat de lista valorilor ntre paranteze i separate prin virgule: expresie IN (valoare_1, valoare_2, , valoare_n) SELECT last_name, salary FROM employees WHERE department_id IN (10, 30) ORDER BY last_name; 1

11. Care este data curent? Obs: Pseudocoloana care returneaz data curent este SYSDATE. Pentru completarea sintaxei obligatorii a comenzii SELECT, se utilizeaz tabelul DUAL: SELECT FROM SYSDATE dual;

Datele calendaristice pot fi formatate cu ajutorul funciei TO_CHAR(data,format), unde formatul poate fi alctuit dintr-o combinaie a urmtoarelor elemente: Element D DD DDD MM MON MONTH YYYY HH12, HH24 AM sau PM MI SS Semnificaie Numrul zilei din sptmn (duminic=1; luni=2; smbt=6). Numrul zilei din lun. Numrul zilei din an. Numrul lunii din an. Numele lunii din an, printr-o abreviere de 3 litere (JAN, FEB etc.). Numele complet al lunii din an. Anul n format numeric (4 cifre). Orele din zi, ntre 0-12, respectiv 0-24. Indicator meridian: AM sau PM Minutele din or. Secundele din minut.

12. S se afieze numele i data angajrii pentru fiecare salariat care a fost angajat n 1987. SELECT first_name, last_name, hire_date FROM employees WHERE TO_CHAR(hire_date, YYYY)=1987; 13. S se afieze numele i job-ul pentru toi angajaii care nu au manager. SELECT last_name, job_id FROM employees WHERE manager_id IS NULL; 14. S se listeze numele tuturor angajailor care au a treia litera din nume 'a'. Obs: Pentru a forma mtile de caractere utilizate mpreun cu operatorul LIKE cu scopul de a compara irurile de caractere, se utilizeaz: % - reprezentnd orice ir de caractere, inclusiv irul vid; _ (underscore) reprezentnd un singur caracter. SELECT DISTINCT last_name FROM employees WHERE last_name LIKE '__a%';

LABORATOR 2 - SQL - REZUMAT


FUNCII SQL (single-row) 1. Analizai urmtoarele operaii pe expresii de tip dat calendaristic: Operaie date -/+ number date1 - date2 date +/number/24 Tipul de date al rezultatului Date Number Date Descriere Scade/Adaug un numr de zile dintr-o / la o dat. Returneaz numrul de zile dintre dou date calendaristice. Scade/Adaug un numr de ore la o / dintr-o dat calendaristic.

2. S se afieze data (luna, ziua, ora, minutul si secunda) de peste 10 zile. SYSDATE+10 3. a. S se afieze data de peste 12 ore. SYSDATE+12/24 b. S se afieze data de peste 5 minute. SYSDATE+1/288 4. Analizai urmtoarele funcii pentru prelucrarea datelor calendaristice: Funcie SYSDATE Semnificaie Exemplu ntoarce data i timpul curent Returneaz numrul de luni dintre data date1 i data date2. Rezultatul poate fi pozitiv sau negativ dup cum ROUND(MONTHS_BETWEEN date1 este mai recent sau nu fa de (SYSDATE + 31, SYSDATE)) = 1 date2. Zecimalele reprezint pari dintr-o luna! Adaug n luni la o data specificat. Valoarea n trebuie s fie ntreag (pozitiv sau negativ). MONTHS_BETWEEN (ADD_MONTHS(SYSDATE, 3), SYSDATE) = 3

MONTHS_BETWEEN (date1, date2)

ADD_MONTHS (date, n)

5. Pentru fiecare angajat s se afieze numele i numrul de luni de la data angajrii. Etichetai coloana Luni lucrate. S se ordoneze rezultatul dup numrul de luni lucrate. Se va rotunji numrul de luni la cel mai apropiat numr ntreg. SELECT last_name, ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) Luni lucrate FROM employees ORDER BY MONTHS_BETWEEN(SYSDATE, hire_date); SELECT last_name, ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) Luni lucrate FROM employees ORDER BY Luni lucrate; 3

SELECT last_name, ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) Luni lucrate FROM employees ORDER BY 2; 6. Analizai urmtoarea funcie SQL: Funcie Semnificaie Returneaz expr1 dac aceasta nu este NULL, expr2 n caz contrar. Cele 2 expresii trebuie s aib acelai tip sau expr2 s permit conversia implicit la tipul expresiei expr1. Exemplu NVL(NULL, 1) = 1 NVL(2, 1) = 2 NVL('c', 1) = 'c' -- face conversie NVL(1, 'c') -- eroare --nu face conversie

NVL (expr1, expr2)

7. S se afieze numele angajailor i comisionul. Dac un angajat nu ctig comision, s se scrie Fara comision. Etichetai coloana Comision. SELECT last_name, NVL(TO_CHAR(commission_pct),Fara comision) comision FROM employees; 8. S se listeze numele, salariul i comisionul tuturor angajailor al cror venit lunar depete 10000$. SELECT last_name, salary, commission_pct, salary + salary * NVL(commission_pct, 0) venit_lunar FROM employees WHERE salary + salary * NVL(commission_pct, 0) > 10000 ORDER BY venit_lunar; 9. Analizai expresia CASE i funcia DECODE: Funcie/Expresie CASE expr WHEN expr_bool1 THEN return_expr1 [WHEN expr_bool2 THEN return_expr2 ... WHEN expr_booln THEN return_exprn ] [ELSE return_expr] END DECODE (expr, expr_cautare1, expr_rezultat1, [expr_cautare2, expr_rezultat2, .. expr_cautaren, expr_rezultatn, ] [rezultat_implicit]) Semnificaie n funcie de valoarea unei expresii returneaz valoarea primei perechi WHEN .. THEN care se potrivete sau dac nu se potrivete nici una expresia din ELSE. Nu se poate specifica NULL pentru toate expresiile de returnat. (return_expri). Toate expresiile trebuie sa aib acelai tip de date Decodific valoarea expresiei. Dac valoarea expresiei este expr_cautarei atunci e returnat expr_rezultati. Dac nu se potrivete nici o expresie de cutare atunci e returnat rezultat_implicit. Exemplu

DECODE (1, 1, 2, 3) = 2 DECODE (2, 1, 2, 3) = 3 DECODE (3, 1, 2, 3) = 3

10. S se afieze numele, codul funciei, salariul i o coloana care s arate salariul dup mrire. Se tie c pentru IT_PROG are loc o mrire de 10%, pentru ST_CLERK 15%, iar pentru SA_REP o mrire de 20%. Pentru ceilali angajai nu se acord mrire. S se denumeasc coloana "Salariu revizuit".

SELECT last_name, job_id, salary, DECODE(job_id, IT_PROG, salary*1.1, ST_CLERK, salary*1.15, SA_REP, salary*1.2, salary ) salariu revizuit FROM employees; SELECT last_name, job_id, salary, CASE job_id WHEN IT_PROG THEN salary* 1.1 WHEN ST_CLERK THEN salary*1.15 WHEN SA_REP THEN salary*1.2 ELSE salary END salariu revizuit FROM employees;

LABORATOR 3 - SQL -REZUMAT


CERERI MULTITABEL, SUBCERERI Tipuri de join: equijoin (se mai numete inner join sau simple join) - compunerea a dou tabele diferite dup o condiie ce conine operatorul de egalitate. SELECT last_name, department_name, location_id, e.department_id FROM employees e, departments d WHERE e.department_id = d.department_id; Obs: Numele sau alias-urile tabelelor sunt obligatorii n dreptul coloanelor care au acelai nume n mai multe tabele. nonequijoin - compunerea a dou relaii tabele dup o condiie oarecare, ce NU conine operatorul de egalitate. SELECT last_name, salary, grade_level FROM employees, job_grades WHERE salary BETWEEN lowest_sal AND highest_sal; outerjoin - compunerea extern a dou tabele diferite completnd una dintre relaii cu valori NULL acolo unde nu exist n aceasta nici un tuplu ce ndeplinete condiia de corelare. Relaia completat cu valori NULL este cea n dreptul creia apare (+). Operatorul (+) poate fi plasat n orice parte a condiiei de join, dar nu n ambele pri. Full outer join = Left outer join UNION Right outer join. SELECT last_name, department_name,location_id FROM employees e, departments d WHERE e.department_id(+) = d.department_id; selfjoin - compunerea extern a unui tabel cu el nsui dup o condiie dat. SELECT sef.last_name, angajat.last_name FROM employees sef, employees angajat WHERE sef.employee_id = angajat.manager_id ORDER BY sef.last_name; 1. S se afieze numele, job-ul i numele departamentului pentru toi angajaii care lucreaz n Seattle. SELECT FROM WHERE AND AND last_name, job_id, department_name employees e, departments d, locations s e.department_id = d.department_id d.location_id = s.location_id city = Seattle;

2. S se afieze numele salariailor i numele departamentelor n care lucreaz. Se vor afia i salariaii care nu lucreaz ntr-un departament. SELECT FROM WHERE last_name, department_name employees e, departments d e.department_id = d.department_id(+);

3. S se afieze numele i data angajrii pentru salariaii care au fost angajai dup Fay. SELECT last_name, hire_date FROM employees 6

WHERE

hire_date > (SELECT hire_date FROM employees WHERE last_name = Fay);

sau SELECT a.last_name, a.hire_date FROM employees a, employees b WHERE UPPER(b.last_name)=FAY AND a.hire_date>b.hire_date; 4. S se afieze numele i job-ul tuturor angajailor din departamentul Sales. SELECT FROM WHERE last_name, job_id employees department_id = (SELECT department_id FROM departments WHERE department_name ='Sales');

5. Rezolvai cererea anterioar utiliznd joinuri.

LABORATOR 4 - SQL- REZUMAT Funcii grup. Gruparea datelor. Funciile multiple-row (grup sau agregat)
1. S se afieze cel mai mare salariu, cel mai mic salariu, suma i media salariilor tuturor angajatilor. Etichetai coloanele Maxim, Minim, Suma, respectiv Media. S se rotunjeasc rezultatele. SELECT MIN(salary) min, MAX(salary) max, SUM(salary) suma, ROUND(AVG(salary)) media FROM employees; 2. Utiliznd funcia grup COUNT s se determine: a. numrul total de angajai; b. numrul de angajai care au manager; c. numrul de manageri. 3. S se afieze suma salariilor angajailor din departamentul 80. 4. S se afieze numrul de angajai pentru fiecare job. SELECT job_id, COUNT(employee_id) nr_angajati FROM employees GROUP BY job_id; 5. S se afieze codul departamentului i media salariilor pentru fiecare job din cadrul acestuia. SELECT department_id, job_id, AVG(salary) FROM employees GROUP BY department_id, job_id; 6. S se afieze codul departamentelor pentru care salariul minim depete 5000$. SELECT department_id, MIN(salary) FROM employees GROUP BY department_id HAVING MIN(salary)>5000; 7. S se obin codul departamentelor i numrul de angajai al acestora pentru departamentele care au cel puin 10 angajai. 8. S se obin numrul departamentelor care au cel puin 10 angajai. SELECT FROM GROUP BY HAVING SELECT FROM GROUP BY HAVING COUNT(COUNT(employee_id)) employees department_id COUNT(*) > =10; job_id employees job_id AVG(salary) = (SELECT MIN(AVG(salary)) FROM employees GROUP BY job_id); 8

9. S se obin job-ul pentru care salariul mediu este minim.

10. S se creeze o cerere prin care s se afieze numrul total de angajai i, din acest total, numrul celor care au fost angajai n 1997, 1998, 1999 i 2000. Datele vor fi afiate n forma urmtoare: Total 1997 1998 1999 2000 -------------------------------------------------------------50 10 5 25 1 SELECT COUNT(*) TOTAL, SUM(DECODE(TO_CHAR(hire_date,'yyyy'),1997,1,0)) SUM(DECODE(TO_CHAR(hire_date,'yyyy'),1998,1,0)) SUM(DECODE(TO_CHAR(hire_date,'yyyy'),1999,1,0)) SUM(DECODE(TO_CHAR(hire_date,'yyyy'),2000,1,0)) FROM employees; "AN "AN "AN "AN 1997", 1998", 1999", 2000"

Operatorii ROLLUP i CUBE


11. S se afieze codurile departamentelor n care lucreaz cel puin un angajat, iar pentru fiecare dintre acestea i pentru fiecare manager care lucreaz n departamentul respectiv s se afieze numrul de salariai. De asemenea, s se afieze numrul de salariai pentru fiecare departament indiferent de manager i numrul total de angajai din companie. SELECT department_id, manager_id, COUNT(employee_id) FROM employees WHERE manager_id IS NOT NULL AND department_id IS NOT NULL GROUP BY ROLLUP (department_id, manager_id); department_id manager_id COUNT(employee_id) --------------------------------------------------------------------10 7782 1 10 7839 1 10 2 ----------------------------------------------------------------------20 7566 2 20 7788 1 20 7839 1 20 7902 1 20 5 ----------------------------------------------------------------------30 7698 5 30 7839 1 30 6 ----------------------------------------------------------------------13 12. S se afieze codurile departamentelor n care lucreaz cel puin un angajat, iar pentru fiecare dintre acestea i pentru fiecare manager care lucreaz n departamentul respectiv s se afieze numrul de salariai. De asemenea, s se afieze numrul de salariai pentru fiecare departament indiferent de manager, numrul de angajai subordonai unui manager indiferent de departament i numrul total de angajai din companie. 9

SELECT department_id, manager_id, COUNT(employee_id) FROM employees WHERE manager_id IS NOT NULL AND department_id IS NOT NULL GROUP BY CUBE (department_id, manager_id); department_id manager_id COUNT(employee_id) --------------------------------------------------------------------10 7782 1 10 7839 1 10 2 ----------------------------------------------------------------------20 7566 2 20 7788 1 20 7839 1 20 7902 1 20 5 ----------------------------------------------------------------------30 7698 5 30 7839 1 30 6 ----------------------------------------------------------------------7566 2 7698 5 7782 1 7788 1 7839 3 7902 1 ---------------------------------------------------------------------13 13. Clauza GROUPING SETS. Permite obinerea numai a anumitor grupri superagregat. Acestea pot fi precizate prin intermediul clauzei: GROUPING SETS ((expr_11, expr_12, , expr_1n), (expr_21, expr_22, expr_2m), ) 14. S se afieze numele departamentelor, numele job-urilor, codurile managerilor, maximul i suma salariilor pentru: - fiecare departament i, n cadrul su, fiecare job; - fiecare job i, n cadrul su, pentru fiecare manager; - ntreg tabelul. SELECT department_name, job_title, e.manager_id, MAX(salary) Maxim, SUM(salary) Suma FROM employees e, departments d, jobs j WHERE e.department_id = d.department_id AND e.job_id = j.job_id GROUP BY GROUPING SETS ((department_name, job_title), (job_title, e.manager_id), ());

10

LABORATOR 5 - SQL - REZUMAT Subcereri. Operatori. Cereri cu sincronizare (corelate). Subcereri


1. S se obin numele primilor 5 angajai care au salariul cel mai mare. Rezultatul se va ordona descresctor dup salariu. SELECT last_name, job_id, salary FROM employees e WHERE 5>(SELECT COUNT(*) FROM employees WHERE salary > e.salary) ORDER BY salary DESC; sau SELECT * FROM (SELECT last_name, job_id, salary FROM employees ORDER BY salary DESC) WHERE ROWNUM<=5; 2. S se afieze numele, job-ul i salariul celor mai prost pltii angajai din fiecare departament. Fr sincronizare SELECT last_name, salary, job_id, department_id FROM employees WHERE (department_id, salary) IN (SELECT department_id, MIN(salary) FROM employees GROUP BY department_id); Cu sincronizare SELECT last_name, salary, job_id, department_id FROM employees e WHERE salary = (SELECT MIN(salary) FROM employees WHERE department_id=e.department_id); 3. S se obin codurile i numele departamentelor n care nu lucreaz nimeni. Rulai urmtoarea cerere SQL. Ce observai? Modificai cererea astfel nct s fie corect. Observaie: Dac este utilizat operatorul NOT NULL, atunci subcererea nu trebuie s ntoarc valori NULL. SELECT department_name, department_id FROM departments 11

WHERE department_id

NOT IN (SELECT DISTINCT department_id FROM employees);

4. S se afieze numele i salariul angajailor al cror salariu este mai mare dect salariile medii din toate departamentele. SELECT last_name, salary FROM employees WHERE salary > ALL (SELECT AVG(salary) FROM employees GROUP BY department_id);

Operatori pe mulimi
5. S se creeze o cerere prin care s se afieze numrul total de angajai i, din acest total, numrul celor care au fost angajai n 1997. SELECT COUNT(*)|| ' nr_total ' numar FROM employees UNION SELECT COUNT(*)|| ' nr_1980 ' numar_1997 FROM employees WHERE TO_CHAR(hire_date,'YYYY')=1997; 6. S se obin, folosind operatorul INTERSECT, angajaii care au salariul < 3000 i al cror nume conine litera a pe poziia 3. SELECT employee_id, last_name FROM employees WHERE salary<3000 INTERSECT SELECT employee_id, last_name FROM employees WHERE UPPER(last_name) LIKE '__A%'; 7. S se afieze codurile departamentelor care nu au angajai, implementnd operatorul MINUS. SELECT department_id FROM departments MINUS SELECT DISTINCT department_id FROM employees;

Operatorul boolean EXISTS


8. S se obin numele i codul angajailor care au salariul mai mare dect angajatul cu codul 200. SELECT employee_id, last_name FROM employees e WHERE EXISTS (SELECT * FROM employees WHERE employee_id = 200 AND e.salary >salary); 12

9.

S se determine codul i numele departamentelor n care nu lucreaz nimeni, folosind operatorul EXISTS. SELECT department_id, department_name FROM departments d WHERE NOT EXISTS (SELECT 'x' FROM employees WHERE department_id =d.department_id);

13

LABORATOR 6 SQL - REZUMAT SQL*PLUS


1. S se afieze numele, job-ul i salariul angajailor care au salariul cuprins ntre 2 numere introduse de utilizator. ACCEPT n PROMPT 'n=' ACCEPT m PROMPT 'm=' SELECT FROM WHERE last_name, job_id, salary employees salary BETWEEN &n AND &m;

2. S se menin ntr-o variabil de legtur numele salariatului avnd codul 100. VARIABLE v_nume VARCHAR2(20) BEGIN SELECT last_name INTO :v_nume FROM employees WHERE employee_id = 100; END; / PRINT v_nume

14

LABORATOR 7 SQL - REZUMAT


Operatorul DIVISION 1. S se afieze codul i numele proiectelor la care au lucrat toi angajaii din departamentul 20. Varianta 1 SELECT FROM WHERE AND p.project_id, project_name projects p, work w p.project_id=w.project_id employee_id IN (SELECT employee_id FROM employees WHERE department_id =20) GROUP BY p.project_id, project_name HAVING COUNT(*)=(SELECT COUNT(*) FROM employees WHERE department_id =20); Varianta 2 SELECT FROM WHERE AND DISTINCT p.project_id, project_name projects p, work w p.project_id=w.project_id NOT EXISTS (SELECT X FROM employees e WHERE department_id=20 AND NOT EXISTS (SELECT X FROM work w1 WHERE e.employee_id=w1.employee_id AND w.project_id=w1.project_id));

Limbajul de prelucrare a datelor (LMD) 1. S se creeze tabele emp_*** i dept_***, avnd aceeai structur i date ca i tabelele employees, respectiv departments. CREATE TABLE emp_*** AS SELECT * FROM employees WHERE 0=1; CREATE TABLE dept_*** AS SELECT * FROM departments WHERE 0=1; 2. Sintaxa simplificat a comenzii INSERT - pentru inserarea unei singure linii: INSERT INTO nume_tabel [(col1,col2,...)] VALUES (expresie1, expresie2, ...); - pentru inserarea liniilor rezultat ale unei comenzi SELECT: 15

INSERT INTO nume_tabel [(col1,col2,...)] comanda_SELECT; 3. Inserai n tabelul emp_*** salariaii (din tabelul employees) al cror comision depete 25% din salariu. Salvai modificrile. 4. Inserai o linie nou n tabelul dept_***, folosind valori introduse de la tastatur. 5. Inserai o linie nou n tabelul dept_***. Salvai ntr-o variabil de legtur codul departamentului nou introdus. Afiai valoarea meninut n variabila respectiv. Anulai tranzacia. VARIABLE v_cod NUMBER INSERT INTO dept_*** (department_id, department_name,location_id) VALUES (200, dept_nou, 2000) RETURNING department_id INTO :v_cod; PRINT v_cod ROLLBACK; 6. Sintaxa simplificat a comenzii DELETE DELETE FROM nume_tabel [WHERE conditie]; 7. tergei toate nregistrrile din tabelele emp_*** i dept_***. Inserai n aceste tabele toate nregistrrile corespunztoare din employees, respectiv departments. Permanentizai tranzacia. DELETE FROM dept_***; DELETE FROM emp_***; INSERT INTO emp_*** SELECT * FROM employees; INSERT INTO dept_*** SELECT * FROM departments; COMMIT; 8. Eliminai departamentele care nu au nici un angajat. Anulai modificrile. 9. tergei un angajat al crui cod este dat de la tastatur. 10. S se tearg angajatul avnd codul 100. S se menin numele acestuia ntr-o variabil de legtur. Afiai valoarea acestei variabile. VARIABLE t VARCHAR2(20) DELETE FROM emp_*** WHERE employee_id = 100 RETURNING first_name INTO :t; PRINT t 16

ROLLBACK; 11. Sintaxa simplificat a comenzii UPDATE: UPDATE nume_tabel [alias] SET col1 = expr1[, col2=expr2] [WHERE conditie]; sau UPDATE nume_tabel [alias] SET (col1,col2,...) = (subcerere) [WHERE conditie]; 12. Mrii cu 5% salariul tuturor angajailor . Anulai modificrile. UPDATE emp_*** SET salary = salary * 1.05; ROLLBACK; 13. Mrii cu 5% salariul tuturor angajailor care lucreaz n departamentul 50. Anulai modificrile. 14. S se modifice jobul i departamentul angajatului avnd codul 114, astfel nct s fie la fel cu cele ale angajatului avnd codul 205. UPDATE emp_*** SET (job_id, department_id) = (SELECT job_id, department_id FROM emp_*** WHERE employee_id = 205) WHERE employee_id = 114; ROLLBACK; 15. S se modifice cererea de la exerciiul anterior astfel nct actualizarea coloanei email s fie realizat doar pentru angajatul avnd codul 200. S se menin numele i emailul acestuia n dou variabile de legtur. S se anuleze tranzacia. VARIABLE v_nume VARCHAR2(20) VARIABLE v_email VARCHAR2(20) UPDATE emp_*** SET email = LOWER(SUBSTR(first_name,1,1)) || _ ||LOWER(last_name) WHERE employee_id = 200 RETURNING last_name, email INTO :v_nume, :v_email; PRINT v_nume PRINT v_email ROLLBACK; 16. Mrii cu 1000 salariul unui angajat al crui cod este introdus de la tastatur.

17

LABORATOR 8 SQL - REZUMAT


Limbajul de definire a datelor (CREATE, ALTER, DROP) Crearea tabelelor CREATE TABLE [schema.]nume_tabel ( nume_coloana tip_de_date [DEFAULT expr], ...); CREATE TABLE nume_tabel [(col1, col2...)] AS subcerere; 1. Creai tabelul salariat_*** avnd urmtoarea structur: Nume cod_ang nume prenume functia sef data_angajarii varsta email salariu Caracteristici NOT NULL Tip NUMBER(4) VARCHAR2(25) VARCHAR2(25) VARCHAR2(20) NUMBER(4) DATE NUMBER(2) CHAR(20) NUMBER(9,2)

Valoare implicit data curent Valoare implicit 0

CREATE TABLE salariat_*** ( cod_ang NUMBER(4) NOT NULL, nume VARCHAR2(25), prenume VARCHAR2(25), functia VARCHAR2(20), sef NUMBER(4), data_angajarii DATE DEFAULT SYSDATE, varsta NUMBER(2), email CHAR(20), salariu NUMBER(9,2) DEFAULT 0); 2. Se dau urmtoarele valori:
COD _ANG NUME 1 ..... 2 ..... PRENUME ..... ..... FUNCTIA SEF director null functionar 1 DATA_ANG VARSTA ........ 30 ......... 25 EMAIL ..... ..... SALARIU 5500 0

3. Inserai n tabelul salariat_*** prima nregistrare din tabelul de mai sus fr s precizai lista de coloane n comanda INSERT. 4. Inserai a doua nregistrare folosind o list de coloane din care excludei data_angajarii i salariul care au valori implicite. Observai apoi rezultatul. Modificarea tabelelor 5. Adugai o nou coloan tabelului salariat_*** care s conin data naterii.

18

ALTER TABLE salariat_*** ADD (datan DATE); 6. Eliminai coloana varsta din tabelul salariat_***. ALTER TABLE salariat_*** DROP COLUMN varsta; Constrngeri Tipuri de constrngeri: NOT NULL - coloane ce nu pot conine valoarea Null; (NOT NULL) UNIQUE - coloane sau combinaii de coloane care trebuie s aib valori unice n cadrul tabelului; ( UNIQUE (col1, col2, ) ) PRIMARY KEY - identific n mod unic orice nregistrare din tabel. Echivalent cu NOT NULL + UNIQUE; (PRIMARY KEY (col1, col2, )) FOREIGN KEY - stabilete o relaie de cheie extern - cheie primar ntre o coloan a tabelului i o alt coloana dintr-un tabel specificat. [FOREIGN KEY nume_col] REFERENCES nume_tabel(nume_coloana) [ ON DELETE {CASCADE| SET NULL}] - FOREIGN KEY este utilizat ntr-o constrngere la nivel de tabel pentru a defini coloana din tabelul copil; - REFERENCES identific tabelul printe i coloana corespunztoare din acest tabel; - ON DELETE CASCADE determin ca, odat cu tergerea unei linii din tabelul printe, s fie terse i liniile dependente din tabelul copil; - ON DELETE SET NULL determin modificarea automat a valorilor cheii externe la valoarea null, atunci cnd se terge valoarea printe. CHECK - o condiie care s fie adevrat la nivel de coloan sau linie (CHECK (conditie)). Constrngerile pot fi create cu tabelul sau adugate ulterior cu o comand ALTER TABLE. Adugarea constrngerilor la crearea tabelului (CREATE TABLE) CREATE TABLE [schema.]nume_tabel ( nume_coloana tip_de_date [DEFAULT expr] [constrangere_de_coloana], ... [constrangere la nivel de tabel]) 7. tergei i apoi creai din nou tabelul salariat_*** cu urmtoarea structur.
NUME cod_ang nume prenume data_nasterii functia sef data_angajarii TIP NUMBER(4) VARCHAR2(25) VARCHAR2(25) DATE VARCHAR2(9) NUMBER(4) DATE CONSTRNGERE Cheie primar NOT NULL data_nasterii<data_angajarii NOT NULL Refer coloana cod_ang din acelai tabel

19

email salariu cod_dept

VARCHAR2(20) NUMBER(12,3) NUMBER(4)

unic >0 Combinaia NUME i PRENUME s fie unic

Observaie: Constrngerile de tip CHECK se pot implementa la nivel de coloan doar dac nu refer o alt coloan a tabelului. DROP TABLE salariat_***; CREATE TABLE salariat_*** ( cod_ang NUMBER(4) PRIMARY KEY, nume VARCHAR2(25) NOT NULL, prenume VARCHAR2(25), data_nasterii DATE, functia VARCHAR2(9) NOT NULL, sef NUMBER(4) REFERENCES salariat_*** (cod_ang), data_angajarii DATE DEFAULT SYSDATE, email VARCHAR2(20)UNIQUE, salariu NUMBER(9,2) CONSTRAINT c_*** CHECK (salariu > 0), cod_dep NUMBER(4), CONSTRAINT const_c_*** CHECK (data_angajarii > data_nasterii), CONSTRAINT const_u_*** UNIQUE (nume,prenume,data_nasterii)); 8. tergei tabelul salariat_***, iar apoi recreai-l implementnd toate constrngerile la nivel de tabel. Observaie: Constrngerea de tip NOT NULL se poate declara doar la nivel de coloan. DROP TABLE salariat_***; CREATE TABLE salariat_*** ( cod_ang NUMBER(4), nume VARCHAR2(25) NOT NULL, prenume VARCHAR2(25), data_nasterii DATE, functia VARCHAR2(9) NOT NULL, sef NUMBER(4), data_angajarii DATE DEFAULT SYSDATE, email VARCHAR2(20), salariu NUMBER(9,2), cod_dep NUMBER(4), CONSTRAINT ccp_*** PRIMARY KEY (cod_ang), CONSTRAINT cce_*** FOREIGN KEY (sef) REFERENCES salariat_***(cod_ang), CONSTRAINT cu1_*** UNIQUE (email), CONSTRAINT cc1_*** CHECK (data_angajarii > data_nasterii), CONSTRAINT cc2_*** CHECK (salariu > 0), CONSTRAINT cu2_*** UNIQUE (nume,prenume,data_nasterii)); 10. Creai tabelul departament_*** care s aib urmtoarea structur. NUME TIP COD_DEP NUMBER(4) NUME VARCHAR2(20) ORAS VARCHAR2(25) CONSTRNGERI Cheie primar Not null 20

b. Ulterior crerii tabelului, adugai constrngerea NOT NULL pe coloana nume. ALTER TABLE departament_*** MODIFY nume NOT NULL; c. Eliminai constrngerea NOT NULL definit pe coloana oras. Adugarea constrngerilor ulterior crerii tabelului, eliminarea, activarea sau dezactivarea constrngerilor (ALTER TABLE nu se aplic pentru NOT NULL) - adaug constrngeri ALTER TABLE nume_tabel ADD [CONSTRAINT nume_constr] tip_constr (coloana); - elimin constrngeri ALTER TABLE nume_tabel DROP [CONSTRAINT nume_constr] tip_constr (coloana); - activare/dezactivare constrngere ALTER TABLE nume_tabel MODIFY CONSTRAINT nume_constr ENABLE|DISABLE; sau ALTER TABLE nume_tabel ENABLE| DISABLE nume_constr; 11. Inserai o nou nregistrare n salariat_*** de forma:
cod nume prenume data_n functia sef data_ang email salariu cod_dep

N2

P2

11-JUN-1960 economist 1

Sysdate

E2

2000

10

Ce observai? Introducei nregistrarea dar specificnd valoarea NULL pentru coloana sef. 12. ncercai s adugai o constrngere de cheie extern pe cod_dep din salariat_***. Ce observai? ALTER TABLE salariat_*** ADD CONSTRAINT cce2_*** FOREIGN KEY (cod_dep) REFERENCES departament_*** (cod_dep); 13. Inserai o nou nregistrare n departament_***. Apoi adugai constrngerea de cheie extern definit anterior. cod_dep nume loc 10 Economic Bucuresti 14. Inserai noi nregistrri n salariat_***, respectiv n departament_***. Care trebuie s fie ordinea de inserare?
cod nume prenume data_n functia sef data_ang email salariu cod_dep

N3

P3

11-JUN1967 loc Constanta

jurist

Sysdate

E3

2500

20

cod_dep nume 20 Juritic

15. tergei departamentul 20 din tabelul departament_***. Ce observai? 21

LABORATOR 9 SQL- REZUMAT


Vizualizri Definirea vizualizrilor 1. S se creeze vizualizarea v_emp_*** care s conin codul i numele salariailor din tabelul emp_***. S se afieze coninutul acesteia. S se insereze o nou nregistrare n aceast vizualizare. Ce observai? S se tearg vizualizarea v_emp_***. CREATE VIEW v_emp_*** (cod, nume) AS SELECT employee_id, last_name FROM emp_***; INSERT INTO v_emp_*** VALUES (400,N1); DROP VIEW v_emp_***; 2. S se creeze vizualizarea v_emp_*** care s conin codul, numele, emailul, data angajrii, salariul i codul jobului salariailor din tabelul emp_***. S se analizeze structura i coninutul vizualizrii. S se insereze o nou nregistrare n aceast vizualizare. S se verifice c noua nregistrare a fost inserat i n tabelul de baz. Observaie: Trebuie introduse neaprat n vizualizare coloanele care au constrngerea NOT NULL n tabelul de baz (altfel, chiar dac tipul vizualizrii permite operaii LMD, acestea nu vor fi posib ile din cauza nerespectrii constrngerilor NOT NULL). CREATE VIEW v_emp_*** AS SELECT employee_id, last_name, email, hire_date, salary,job_id FROM emp_***; DESC v_emp_*** SELECT * FROM v_emp_***; INSERT INTO v_emp_*** VALUES (400,N1,E1,SYSDATE,5000,SA_REP); SELECT employee_id, last_name, email, hire_date, salary, job_id FROM emp_***; 3. S se tearg angajatul avnd codul 400 din vizualizarea creat anterior. Ce efect va avea aceast aciune asupra tabelului de baz? DELETE FROM v_emp_*** WHERE employee_id = 400; SELECT employee_id, last_name, salary FROM emp_*** WHERE employee_id = 400; 22

5. a) S se creeze vizualizarea v_emp_dept_*** care s conin employee_id, last_name, hire_date, job_id, department_id din tabelul emp_*** i coloana department_name din tabelul dept_***. CREATE VIEW v_emp_dept_*** AS SELECT employee_id, last_name, email, hire_date, job_id, e.department_id, department_name FROM emp_*** e, dept_*** d WHERE e.department_id =d.department_id; b) S ncerce inserarea nregistrrii (500, 'N2', 'E2',SYSDATE,SA_REP,30, 'Administrativ') n vizualizarea creat anterior. INSERT INTO v_emp_dept_*** VALUES (500, 'N2', 'E2',SYSDATE,SA_REP,30, 'Administrativ'); c) Care dintre coloanele vizualizrii v_emp_dept_*** sunt actualizabile? SELECT FROM WHERE * user_updatable_columns UPPER(table_name) = UPPER('v_emp_dept_***');

d) Adugai tabelului emp_*** constrngerea de cheie extern care refer tabelul dept_***, apoi verificai ce coloane din vizualizarea v_emp_dept_*** sunt actualizabile. ALTER TABLE emp_*** ADD CONSTRAINT cp_emp_*** PRIMARY KEY (employee_id); ALTER TABLE dept_*** ADD CONSTRAINT cp_dept1_*** PRIMARY KEY (department_id); ALTER TABLE emp_*** ADD CONSTRAINT ce_emp1_*** FOREIGN KEY (department_id) REFERENCES dept_***(department_id); SELECT FROM WHERE * user_updatable_columns UPPER(table_name) = UPPER('v_emp_dept_***');

d) Recreai vizualizarea v_emp_dept_***, apoi verificai ce coloane sunt actualizabile. DROP VIEW v_emp_dept_***; CREATE VIEW v_emp_dept_*** AS SELECT employee_id, last_name, email, hire_date, job_id, e.department_id, department_name FROM emp_*** e, dept_*** d WHERE e.department_id =d.department_id; SELECT column_name, updatable FROM user_updatable_columns WHERE UPPER(table_name) = UPPER('v_emp_dept_***'); 23

f) Inserai o linie prin intermediul acestei vizualizri. Obs. Tabelul ale crui coloane sunt actualizabile este protejat prin cheie. INSERT INTO v_emp_dept_*** (employee_id, last_name,email,hire_date, job_id, department_id) VALUES (500, 'N2', 'E2',SYSDATE,SA_REP,30); g) Ce efect are o operaie de tergere prin intermediul vizualizrii v_emp_dept_***? Comentai. DELETE FROM v_emp_dept_*** WHERE employee_id = 500; SELECT employee_id, last_name, hire_date, job_id, department_id FROM emp_*** WHERE employee_id = 500; SELECT department_id, department_name FROM dept_*** WHERE department_id = 30; 4. a) S se creeze vizualizarea v_emp30_*** care s conin numele, emailul, data angajrii, salariul, codul jobului i codul departamentului celor care lucreaz n departamentul 30. n aceast vizualizare nu se va permite modificarea sau inserarea liniilor ce nu sunt accesibile ei. Dai un nume constrngerii. CREATE VIEW v_emp30_*** AS SELECT employee_id, last_name, email, hire_date, salary, job_id, department_id FROM emp_*** WHERE department_id=30 WITH CHECK OPTION CONSTRAINT ck_option1_***; b) S se listeze structura i coninutul vizualizrii v_emp30_***. DESCRIBE v_emp30_*** SELECT * FROM v_emp30_***; c) S se ncerce prin intermediul vizualizrii inserarea unui angajat n departamentul 10 i a unui angajat n departamentul 30. INSERT INTO v_emp30_*** VALUES (111, 'N1', 'E1',SYSDATE,1000,SA_REP,10); INSERT INTO v_emp30_*** VALUES (11, 'N11', 'E11',SYSDATE,1000,SA_REP,30); d) S se ncerce prin intermediul vizualizrii modificarea departamentului unui angajat.

24

UPDATE v_emp30_*** SET department_id =20 WHERE employee_id = 11; 5. S se creeze vizualizarea v_dept_*** asupra tabelului dept_*** s nu permit efectuarea nici unei operaii LMD. Testai operaiile de inserare, modificare i tergere asupra acestei vizualizri. CREATE VIEW v_dept_*** AS SELECT * FROM dept_*** WITH READ ONLY;

25

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