Sunteți pe pagina 1din 128

NOȚIUNI DE BAZE DE DATE

Arhitectura internă a unui sistem de baze de date propusă prin standardul


ANSI/X3/SPARC (1975) conține trei niveluri functionale:
- nivelul extern,
- nivelul conceptual și
- nivelul intern (fig. 1.2).
Nivelul extern este o colectie de scheme externe, care sunt vederi ale diferitelor
grupuri de utilizatori, existând câte o vedere individuală a datelor pentru fiecare grup;
Nivelul conceptual conține schema conceptuală (logică) a bazei de date,
Nivelul intern conține schema internă (fizică) a bazei de date.

O schema externă (vedere utilizator) (external schema, user’s view) conține o


subschemă conceptuală a bazei de date, mai precis descrierea datelor care sunt
folosite de acel grup de utilizatori.
Schema conceptuală a bazei de date (conceptual schema) corespunde unei
reprezentări unice (pentru toti utilizatorii) și abstracte a datelor, descriind ce date sunt
stocate în baza de date și care sunt asocierile dintre acestea.
Schema internă (fizică) a bazei de date (internal schema) specifică modul de
reprezentare a datelor pe suportul fizic.

Un sistem de baze de date suportă o schemă internă, o schemă conceptuală și


mai multe scheme externe; toate aceste scheme sunt descrieri diferite ale aceleeași colecții
de date, care există doar în nivelul intern.

Avantajele oferite de sistemele de baze de date

• Compactitate ridicată: volumul ocupat de sistemele de baze de date este mult mai redus

1
decât volumul ocupat de documente scrise sau de fișiere necorelate.

• Viteza mare de regăsire și actualizare a informațiilor.

• Redundanța scăzută a datelor memorate, care se obține prin partajarea datelor între
mai mulți utilizatori și aplicații.

• Posibilitatea de introducere a standardelor privind modul de stocare a datelor, ceea ce


permite interschimbul informațiilor între diferite organizații.

• Menținerea integrității datelor prin politica de securitate (drepturi de acces diferențiate


în funcție de rolul utilizatorilor), prin gestionarea tranzacțiilor si prin refacerea datelor în caz
de funcționare defectuoasă a diferitelor componente hardware sau software.

• Independența datelor față de suportul hardware utilizat. Sistemele de gestiune a


bazelor de date oferă o vedere (view) externă a datelor, care nu se modifică atunci când se
schimbă suportul de memorare fizic, ceea ce asigură imunitatea structurii bazei de date și a
aplicațiilor la modificări ale sistemului hardware utilizat.

1.8 Clasificarea sistemelor de baze de date

Există diferite criterii de clasificare ale sistemelor de baze de date.


Clasificare dupa modelul de date.
- ierarhic
- rețea
- relațional
- obiect
- obiect-relațional

Clasi ficare dupa numarul de utilizatori.


- multiutilizator, permit accesul concurent (în același timp) al mai multor
utilizatori la aceeași bază de date.
- monoutilizator, suportă accesul doar al unui singur utilizator la un moment
dat.
Clasificare după numărul de stații pe care este stocată baza de date.
- sistem de baze de date centralizat (Centralized Database System ) este un
sistem de baze de date în care datele și sistemul de gestiune sunt stocate pe o singură stație.
- sistem de baze de date distribuit (Distributed Database System) poate avea
atât datele, cât și sistemul de gestiune, distribuite în mai multe stații interconectate
printr-o rețea de calculatoare.

Modelarea datelor

Un model este o abstractizare a unui sistem, care captează cele mai


importante trăsături caracteristice ale sistemului (concepte), relevante din punct de vedere
al scopului pentru care se definește modelul respectiv. Tehnica de identificare a trăsăturilor
caracteristice esențiale ale unui sistem se numeste abstractizare.
Un model de date stabilește regulile de organizare și interpretare a unei colecții de

2
date. În proiectarea bazelor de date se folosesc, de regulă, mai multe modele de date, care se
pot clasifica în două categorii:
- modele conceptuale de nivel înalt și
- modele specializate.

Un model conceptual de nivel înalt al datelor conține o descriere concisă a colecțiilor


de date care modelează activitatea dorită (numită schema conceptuală de nivel înalt ), fără să
detalieze modul de reprezentare sau de prelucrare a datelor.
Modelele specializate de date (modelul ierarhic, modelul rețea, modelul relațional,
etc.) impun anumite structuri speciale de reprezentare a mulțimilor de entități și a asocierilor
dintre acestea, structuri pe baza cărora sunt dezvoltate sistemele de gestiune a bazelor de
date. Într-un astfel de model de date, o baza de date este reprezentata printr-o schema
conceptuala (logica) specifica. Trecerea de la modelul conceptual de nivel înalt la un model
de date specific reprezintă etapa de proiectare logică a bazei de date care asigură
corespondența dintre schema conceptuală de nivel înalt a bazei de date și schema
conceptuală specifică modelului de date respectiv.

Modelul Entitate-Asociere

Modelul Entitate-Asociere (Entity-Relationship Model), introdus în 1976 de P.S.


Chen, este un model conceptual de nivel înalt al unei baze de date, care definește mulțimile
de entități și asocierile dintre ele, dar nu impune niciun mod specific de structurare și
prelucrare (gestiune) a datelor.
Elementele esențiale ale modelului Entitate-Asociere folosit în proiectarea
bazelor de date sunt entitățile (entities) și asocierile dintre acestea (relationships).
O entitate (entity) este „orice poate fi identificat în mod distinctiv"; o entitate se
referă la un aspect al realității obiective care poate fi deosebit de restul universului și poate
reprezenta un obiect fizic, o activitate, un concept, etc. Orice entitate este descrisă prin
atributele sale.
Un atribut (attribute) este o proprietate care descrie un anumit aspect al unei
entități.
Atributele prin care este descrisă o entitate se aleg pe baza criteriului relevanței
relativ la domeniul de interes pentru care se definește modelul respectiv, astfel încât să
asigure diferențierea acelei entități față de restul universului.
Toate entitățile similare, care pot fi descrise prin aceleași atribute, aparțin unui
aceluiași tip de entitate (entity type), iar colecția tuturor entităților de același tip dintr-o
bază de date constituie o mulțime de entități (entities set). În general, în modelul E-A se
folosește aceeași denumire atât pentru un tip de entitate cât și pentru mulțimea entităților de
acel tip.
De exemplu, tip ul de entitate „angajat” (al unei instituții) reprezintă orice persoană
angajată a instituției, care are o anumită funcție și primește un anumit salariu. Acest tip de
entitate poate fi descris prin mai multe atribute, dintre care o parte sunt atribute de
identificare a persoanei (Nume, Prenume, DataNasterii, Adresa), iar altele sunt atribute
legate de activitatea acesteia în instituția respectivă (Funcție, Salariu).
Prin analogie cu modelul obiect, se poate spune că un tip de entitate corespunde unei
clase, o entitate este o instanță a unui tip de entitate și corespunde unui obiect, iar mulțimea
entităților de un tip dat corespunde mulțimii obiectelor (instanțelor) unei clase.
O asociere (relationship) este o corespondență între entități din două sau mai
multe mulțimi de entități.
Gradul unei asocieri este dat de numărul de mulțimi de entități asociate.

3
Asocierile pot fi
- binare (de gradul 2, între 2 mulțimi de entități) sau
- multiple (între k mulțimi de entități, k > 2).
Asocierile binare sunt, la rândul lor, de trei categorii, după numărul elementelor din
fiecare dintre cele două mulțimi puse în corespondență de asocierea respectivă. Fiind date
două mulțimi de entități, E1 ș i E2 , se definesc următoarele categorii de asocieri binare:
• Asocierea “unul-la-unul” (one-to-one) este asocierea prin care unui element
(entitate) din mulțimea E1 îi corespunde un singur element din mulțimea E2 , si reciproc; se
notează cu 1:1.
• Asocierea „unul-la-multe” (one-to-many) este asocierea prin care unui element din
mulțimea E1 îi corespund unul sau mai multe elemente din mulțimea E2 , dar unui element
din E2 îi corespunde un singur element în mulțimea E1 ; se notează cu 1:N.
• Asocierea „multe-la-multe” (many-to-many) este asocierea prin care unui element
din mulțimea E1 îi corespund unul sau mai multe elemente din mulțimea E2 si reciproc; se
notează cu M: N.

Cardinalitatea (multiplicitatea) unei asocieri față de o mulțime de entități


(cardinality, multiplicity) este numărul maxim de elemente din acea mulțime care pot fi
asociate cu un element din altă mulțime a asocierii.

Realizarea bazelor de date relaționale constă în luarea unor decizii cu privire la modelarea
unor sisteme din lumea reală într-o bază de date.
Există trei etape în procesul de realizare a unei baze de date:
- proiectarea conceptuală,
- proiectarea logică și
- proiectarea fizică.

Proiectarea conceptuală a bazei de date constă în construirea reprezentării conceptuale a


bazei de date, care include identificarea tipurilor importante de entități, relații, atribute și
prezintă următorii pași: identificarea tipurilor de entități (E), identificarea tipurilor de
relații (R), identificarea și asocierea atributelor (A) cu tipurile de E sau R, determinarea

4
domeniilor atributelor, determinarea atributelor chei candidat și chei primare,
specializarea și generalizarea tipurilor de entități.

Proiectarea logică a bazei de date constă în transpunerea reprezentării conceptuale în


structura logică a bazei de date, care include proiectarea relațiilor; avem parte de
următoarele etape: transpunerea modelului conceptual local în modelul de date logic
local (eliminarea relațiilor M:N prin înlocuirea cu relații de tip 1:M sau alte metode,
eliminarea relațiilor complexe prin înlocuirea cu relații de tip 1:M, eliminarea relațiilor
recursive prin înlocuirea cu relații dependente, eliminarea atributelor multiple prin
înlocuirea cu relații dependente, reexaminarea relațiilor 1:1, eliminarea relațiilor
redundante), extragerea relațiilor din modelul de date logic local pentru a reprezenta
entitățile și relațiile, normalizarea relațiilor, validarea modelului conform tranzacțiilor
utilizatorului pentru a garanta că acesta acceptă și rezolvă operațiile cerute de către
model, definirea constrângerilor de integritate.

Notații:

5
Diagrama Entitate-Asociere (Entitate-Relație)

Eliminarea relațiilor de tip N:M:

MODELUL RELATIONAL
Terminologie

Structura relațională a datelor

Relație: o relație este un tabel cu coloane și linii (rânduri). – tip de entitate, mulțime de entități
Atribut: Un atribut este o coloană a unei relații, cu o anumită denumire.
Domeniu: Un domeniu este mulțimea de valori permise pentru unul sau mai multe
atribute. Pentru fiecare atribut se definește în mod central denumirea domeniului, sensul
acestuia și domeniul de definiție. Ca urmare, sistemul va evita operațiile incorecte semantic.

6
Exemplu:

Atribut Denumirea Sensul Domeniul de definitie


(cap de coloana) domeniului
Localitatea Localitatea Multimea tuturor denumirilor Caracter: dimensiune 20
de localitati din România
Nr tel Numere telefon Multimea tuturor numerelor Caracter: dimensiune 14
de telefon din România

Tuplu: Un tuplu este un rând dintr-o relație. Corespunde unei entități, instanțe a unui tip de
entitate.
Intensitatea unei relații: structura tabelului, specificarea domeniilor și a altor restricții
referitoare la valorile posibile. Intensitatea este de regulă fixa/fixată.
Extensia (starea) unei relații: tuplurile, care se modifică în timp.
Grad: Gradul unei relații reprezintă numărul de atribute pe care îl conține. O relație cu două
atribute, de exemplu, se numește binară.
Cardinalitate : cardinalitatea unei relații este numărul de tupluri conținute de aceasta.

Chei relaționale

Trebuie să existe posibilitatea de identificare unică a unui tuplu dintr-o relație,


prin valorile atributelor sale.

Supercheia : Este un atribut sau un set de atribute care identifică în mod unic un tuplu din
interiorul unei relații.
O supercheie poate conține și atribute care nu sunt necesare identificării unice a tuplului.

Cheia candidat: este o supercheie minimă, pentru care nicio submulțime nu este supercheie
în cadrul relației respective.
O cheie poate include mai multe atribute, caz în care se numeste cheie combinată.
O cheie candidat este unică (în fiecare tuplu al relației R, valorile cheii identifică
acel tuplu în mod unic) și ireductibilă (nicio submulțime a cheii candidat nu este unică).

Cheia primară: este cheia candidat care este selectată ( din toate cheile candidat
identificate) pentru a identifica în mod unic tuplurile din cadrul unei relații.
Cheile candidat neselectate se numesc chei alternative.

Cheie straină : Un atribut sau o mulțime de atribute din cadrul unei relatii, care se potrivesc
cu o cheie candidat din altă relație.
De exemplu, o cheie straina dintr-o relatie poate coincide cu cheia primara din alta
relație.
Atributele comune joaca un rol important în manipularea datelor.
Prin intermediul cheilor străine se realizează legăturile dintre relații (tabele).

7
1) Relaţia dintre tabela DateDeContact şi tabela Abonaţi este o relaţie de tipul 1-1.

8
2). Relaţia dintre tabela Abonamente şi tabela Tarife - relaţie de tipul 1-1.

9
2. CREAREA UNEI BAZE DE DATE PRIN COMENZI SQL

2.1. TIPURI DE UTILIZATORI AI BAZELOR DE DATE ORACLE

În funcţie de volumul activităţilor implicate de administrarea unei baze de date


Oracle, sarcinile de administrare pot fi repartizate pe mai multe categorii de
utilizatori ai bazei de date.

Administratorul bazei de date (DBA) este, în funcţie de complexitatea şi mărimea


unei baze de date, o persoană sau mai multe persoane, care să execute următoarele
sarcini administrative:
• Instalarea şi dezvoltarea sever-ului Oracle;
• Alocarea memoriei sistemului şi planificarea cerinţelor viitoare de memorie
ale acestuia;
• Crearea bazei de date şi a obiectelor acesteia (tabele, vederi, indecşi);
• Modificarea structurii bazei de date în funcţie de cerinţele
dezvoltatorilor de aplicaţii;
• Definirea utilizatorilor bazei de date şi întreţinerea sistemului de securitate;
• Controlul şi monitorizarea accesului utilizatorilor la baza de date;
• Monitorizarea şi optimizarea performanţelor bazei de date;
• Definirea şi asigurarea politicii de salvarea sau copiere (backup) şi refacere
(recovery) a bazei de date;
• Arhivarea datelor;
• Asigurarea legăturii cu firma Oracle pentru suportul tehnic şi licenţa de
utilizare a produselor Oracle.

Dezvoltatorii de aplicaţii proiectează şi implementează aplicaţii cu baze de date


Oracle, executând următoarele sarcini:
• Proiectarea şi dezvoltarea unei aplicaţii, precum şi a structurilor de date ale
acesteia;
• Estimarea cerinţelor de memorie pentru aplicaţie;
• Definirea modificărilor structurilor de date ale unei aplicaţii;
• Transmiterea tuturor informaţiilor despre activităţile de mai sus către
administratorul bazei de date;
• Stabilirea măsurilor de securitate pentru aplicaţie.
Administratorul de aplicaţii se ocupă cu administrarea unei aplicaţii;

Utilizatorii finali ai bazei de date au acces la baza de date prin intermediul unei
aplicaţii sau a instrumentelor Oracle, executând în special următoarele activităţi:
• Adăugarea, modificarea şi ştergerea datelor din baza de date în
concordanţă cu drepturile de acces pe care le are;
• Generarea unor rapoarte cu datele din baza de date.

1
Pentru a putea executa sarcinile de administrare a unei baze de date o persoană
trebuie să aibă privilegii (drepturi) atât la nivelul bazei de date Oracle, cât şi la
nivelul sistemului de operare al serverului pe care se află baza de date.
Prin urmare, un administrator trebuie să aibă:
• Cont de administrator pentru sistemul de operare, care să-i permită
să execute comenzile sistemului de operare;
• Cont de administrator Oracle definit de două conturi de utilizator (SYS şi
SYSTEM cu parolele CHANGE_OF_INSTALL şi respectiv MANAGER);
• Rol de DBA, care este creat automat la momentul creării unei baze de date
Oracle. Acest rol conţine toate privilegiile bazei de date Oracle.

Datorită faptului că un administrator execută activităţi pe care un utilizator obişnuit nu


le poate executa, este necesar ca acesta să poată fi autentificat înainte de a executa
activităţile de administrare.

Pentru autentificarea administratorului există două metode:


• autentificarea folosind sistemul de operare şi
• autentificarea folosind fişierul de parole.

Autentificarea folosind sistemul de operare se face utilizând două conturi de


administrator:
• OSOPER (sub care poate executa STARTUP, SHUTDOWN, ALTER
DATABASE OPEN/MOUNT, ALTER DATABASE
BACKUP, ARCHIVELOG şi RECOVER) şi
• OSDBA (care conţine toate privilegiile de sistem cu opţiunea ADMIN
OPTION, precum şi rolul OSOPER). Sub contul OSDBA se poate
executa comanda CREATE DATABASE.

Autentificarea folosind fişierul de parole permite definirea parolelor de acces


pentru fiecare utilizator. După stabilirea unui utilizator ca administrator, de exemplu
utilizatorul SCOTT cu parola TIGER, acestuia îi va fi atribuit unul din privilegiile
SYSDBA sau SYSOPER, cu comanda GRANT. După aceasta, utilizatorul SCOTT se
va conecta la baza de date ca SYSDBA sau SYSOPER cu comanda CONNECT.

Exemplu:

GRANT SYSDBA TO scott


GRANT SYSOPER TO scott CONNECT scott/tiger AS SYSDBA CONNECT
scott/tiger AS SYSOPER

Administrarea fişierului cu parole include operaţiile


• de definire a fişierului cu parole,
• setarea parametrului de iniţializare a bazei de date
REMOTE_LOGIN_PASSWORDFILE,
• adăugarea de utilizatori în acest fişier şi
• întreţinerea fişierului cu parole.

Crearea fişierului cu parole se execută cu utilitarul ORAPWD, care are trei


parametri: FILE, PASSWORD şi ENTRIES, dintre care primii doi sunt obligatorii, iar
ultimul este opţional. Aceşti parametri definesc numele fişierului cu parole, parola

2
pentru utilizatorul SYS şi respectiv numărul de utilizatori care pot executa activităţi
de administrator (DBA).

Setarea parametrului de iniţializare REMOTE_LOGIN_PASSWORDFILE cu una


din valorile NONE, EXCLUSIVE şi SHARED permite utilizarea fişierului cu parole.
- NONE determină ca baza de date Oracle să funcţioneze fără fişier de parole,
- EXCLUSIVE determină ca fişierul de parole să fie folosit exclusiv de către o
singură bază de date,
- SHARED determină ca fişierul de parole să fie folosit de către mai multe
baze de date.
Pentru a avea un grad mare de securitate pentru baza de date, va trebui ca imediat
după crearea fişierului cu parole parametrul de iniţializare
REMOTE_LOGIN_PASSWORDFILE să fie setat pe valoarea
EXCLUSIVE.

Adăugarea de utilizatori în fişierul cu parole se face la momentul atribuirii


privilegiilor SYSDBA sau SYSOPER unui anumit utilizator.
Exemplu:
1. Se creează fişierul cu parole conform indicaţiilor de mai sus;
2. Se setează parametrul de iniţializare REMOTE_LOGIN_PASSWORDFILE
cu valoarea EXCLUSIVE;
3. Se conectează utilizatorul SYS, cu parola CHANGE_OF_INSTALL ca
SYSDBA folosind comanda CONNECT SYS/change_of_install AS SYSDBA
4. Se porneşte o instanţă şi se creează o bază de date, dacă este necesar, sau se
montează şi se deschide o bază de date existentă;
5. Se creează utilizatorii care se doresc a fi administratori şi care să fie adăugaţi
în fişierul cu parole, folosind comanda
CREATE USER user1 IDENTIFIED BY parola1
6. Se atribuie unul din privilegiile SYSDBA sau SYSOPER acestui utilizator cu
una din comenzile:
GRANT SYSDBA TO user1 sau GRANT SYSOPER TO user1
7. Utilizatorul USER1 este adăugat în fişierul cu parole şi se poate conecta
acum ca SYSDBA sau SYSOPER cu acest nume de utilizator în loc de
numele SYS, folosind una din comenzile:
CONNECT USER1/parola1 AS SYSDBA sau
CONNECT USER1/parola1 AS SYSOPER

Listarea membrilor fişierului cu parole se face din vederea $PWFILE_USERS


folosind comanda
SELECT * FROM V$PWFILE_USERS

Întreţinerea fişierului cu parole se referă la executarea activităţilor de extindere,


relocare, ştergere sau schimbare a stării acestui fişier.

3
2.2. CREAREA, PORNIREA ŞI OPRIREA UNEI BAZE DE DATE ORACLE

Configurarea serverului Oracle presupune următoarele activităţi:


• Instalarea sistemului Oracle, care constă în instalarea nucleului Oracle
pe server, a instrumentelor (tools-urilor) de aplicaţie pe staţii;
• Evaluarea resurselor fizice ale calculatorului pe care se va instala serverul
Oracle şi baza de date;
• Definirea structurii logice a bazei de date şi a strategiei de salvare
(backup);
• Crearea şi deschiderea bazei de date;
• Implementarea bazei de date proiectate, prin definirea segmentelor de
revenire (rollback), a tabelelor spaţiu şi a obiectelor bazei de date;
• Salvarea bazei de date şi definirea utilizatorilor bazei de date, în
concordanţă cu licenţa Oracle.

Pentru a crea o bază de date Oracle, trebuie să avem suficientă memorie pentru
pornirea unei instanţe Oracle şi pentru crearea tuturor obiectelor proiectate ale bazei
de date. Dacă la momentul instalării s-a creat şi o bază de date iniţială, atunci aceasta
poate fi dezvoltată astfel încât să cuprindă, în final, toate obiectele bazei de date
proiectate. De asemenea, această bază de date iniţială poate fi ştearsă şi în locul ei să
se creeze o nouă bază de date. Dacă am folosit o versiune anterioară Oracle se poate
crea o bază de date nouă în întregime, dacă nu ne mai interesează vechea bază de date;
altfel, putem migra această bază de date la noua versiune Oracle.

2.2.1. Crearea unei baze de date se face în următorii paşi:


• Salvarea completă a bazei de date existente;
• Crearea fişierului cu parametri folosit la pornirea bazei de date.
• Editarea noului fişier cu parametri, astfel încât parametrii acestuia să
corespundă cerinţelor noii baze de date.
• Controlul identificatorului instanţei Oracle, care trebuie să fie identic cu
numele bazei de date setat în parametrul DB_NAME;
• Pornirea utilitarul Entreprice Manager şi conectarea la Oracle ca
administrator.
• Pornirea unei instanţe Oracle (System Global Area şi procesele
background) cu opţiunea Startup Nomount.
• Crearea noii bazei de date folosind comanda SQL CREATE
DATABASE, prin intermediul căreia Oracle execută: crearea
fişierelor de date (data files), fişierelor de control (control files) şi a fişierelor de
refacere (redo log) ale bazei de date; crearea tabelului spaţiu SYSTEM şi a
segmentului rollback SYSTEM; crearea dicţionarului de date; crearea
utilizatorilor SYS şi SYSTEM; specifică setul de caractere care va fi folosit la
memorarea datelor în baza de date; montează şi deschide baza de date pentru
utilizare.
• Salvarea integrală a bazei de date.

Parametrii de iniţializare a bazei de date furnizează valorile necesare pentru


funcţionarea acesteia sub o anumită instanţă Oracle. Aceştia se personalizează prin
intermediul unui fişier text, numit fişierul cu parametrii de iniţializare. Acesta este
citit la momentul pornirii bazei de date de către serverul Oracle. Pentru a face

4
eventuale modificări, baza de date trebuie oprită complet şi repornită după ce s-au
efectuat astfel de modificări.
Mulţi parametri de iniţializare se folosesc pentru ajustarea şi creşterea performanţelor
bazei de date.
Specificarea parametrilor se realizează după următoarele reguli:
• Toţi parametrii sunt opţionali;
• În fişierul cu parametri se vor fi introduce numai parametri şi
comentarii;
• Semnul (#) marchează începutul unui comentariu, restul liniei fiind ignorat;
• Serverul Oracle are valori asumate pentru fiecare parametru;
• Parametrii pot fi specificaţi în orice ordine;
• Fişierul de parametri nu este „case-sensitive” ;
• Pentru a introduce mai mulţi parametrii pe o linie aceştia se vor separa prin
spaţiu:
PROCESSES = 100 SAVEPOINTS = 5 OPEN_CURSORS = 10
• Unii parametri, ca de exemplu ROLLBACK_SEGMENTS, acceptă valori
multiple, acestea putându-se specifica între paranteze şi separate prin virgulă, sau
fără paranteze şi virgule, ambele sintaxe fiind valide, astfel:
ROLLBACK_SEGMENTS = (SEG1, SEG2, SEG3, SEG4, SEG5)
ROLLBACK_SEGMENTS = SEG1 SEG2 SEG3 SEG4 SEG5
• Caracterul (/) foloseşte pentru marcarea întreruperii scrierii unui parametru pe
o linie şi continuarea lui pe linia următoare, imediat fără nici un spaţiu în faţă,
astfel:
ROLLBACK_SEGMENTS = (SEG1, SEG2, / SEG3, SEG4, SEG5)
• Parametrul IFILE se poate introduce într-un fişier cu parametrii alt fişier cu
parametrii, astfel:
IFILE = COMMON1.ORA
Se pot folosi trei niveluri de imbricare. În exemplu de mai sus, fişierul
COMMON1.ORA poate conţine un al doilea parametru IFILE pentru fişierul
COMMON2.ORA, care la rândul său poate conţine un al treilea parametru IFILE
pentru fişierul COMMON3.ORA. De asemenea, se pot utiliza mai mulţi parametrii
IFILE în acelaşi fişier, astfel:
IFILE = DBPARMS.ORA IFILE = GCPARMS.ORA IFILE = LOGPARMS.ORA
Dacă valoarea unui parametru conţine caractere speciale, atunci caracterul special
trebuie precedat de caracterul de comutare (\) sau întreaga valoare este inclusă între
caracterele (“ ”), ca în exemplul de mai jos:

DB_DOMAIN = JAPAN.ACME\#.COM
sau
DB_DOMAIN = "JAPAN.ACME#.COM"

Pentru schimbarea valorii unui parametru, aceasta se editează în fişierul cu


parametri. Când instanţa Oracle este repornită, aceasta va folosi noua valoare a
parametrului.
Câţiva parametri de iniţializare sunt dinamici, în sensul că valorile acestora se pot
modifica prin procedeul de mai sus sau în timp ce o instanţă rulează, folosind
comenzile SQL: ALTER SESSION, ALTER SYSTEM sau ALTER SYSTEM
DEFERRED cu sintaxele:
ALTER SESSION SET nume_parametru = valoare
ALTER SYSTEM SET nume_parametru = valoare

5
ALTER SYSTEM SET nume_parametru = valoare DEFERRED
Comanda ALTER SESSION schimbă valoarea unui parametru numai la nivelul
sesiunii care a lansat-o, după repornirea bazei de date se va utiliza aceeași valoare din
fişierul cu parametri.
Comanda ALTER SYSTEM modifică valoarea globală a
parametrului, la nivelul întregului sistem, deci pentru toate sesiunile active, după
repornirea bazei de date se va utiliza aceeași valoare din fişierul cu parametrii.
Comanda ALTER SYSTEM DEFERRED modifică valoarea globală a parametrului
nu pentru sesiunile active, ci pentru sesiunile viitoare, care vor fi active după
repornirea bazei de date.
Afişarea valorilor curente ale parametrilor de iniţializare ai bazei de date se face cu
comanda SHOW PARAMETERS, afişarea făcându-se în ordinea alfabetică a
parametrilor. Listarea la imprimantă a parametrilor afişaţi se face cu comanda
SPOOL.

Parametrii de iniţializare se pot grupa în:


• Parametri derivaţi sunt cei ale căror valori se calculează pornind de la
valorile altor parametrii. Normal valorile acestora nu trebuie modificate;
• Parametri globali prefixaţi cu GC sunt folosiţi pe sistemele care suportă
Oracle Parallel Server;
• Parametri dependenţi de sistemul de operare sunt cei ale căror valori sunt
dependente de specificul sistemului de operare gazdă. Exemplu:
DB_BLOCK_BUFFERS care indică numărul ariilor de date (data buffers) din
memoria principală sau DB_BLOCK_SIZE care indică mărimea unui bloc de
date;
• Parametri de tip variabilă sunt cei ce pot lua anumite valori care să
determine performanţele sistemului sau anumite limite de funcţionare. Exemplu:
OPEN_CURSORS dacă i se dă valoarea 10 se vor putea deschide maxim 10
cursoare, iar DB_BLOCK_BUFFERS prin valorile pe care le va lua nu va
impune anumite limite dar va modifica performanţele sistemului;
• Parametri statici sunt cei ale căror valori nu se pot modifica în timpul unei
sesiuni sau cu baza de date pornită;
• Parametri dinamici sunt cei ale căror valori se pot modifica, aşa cum s- a
arătat mai sus cu comenzile ALTER SESSION, ALTER SYSTEM sau ALTER
SYSTEM DEFERRED;

Aşa cum s-a prezentat mai sus, compania Oracle furnizează un fişier iniţial cu
parametri cu ajutorul căruia putem să pornim o bază de date. Pentru a personaliza
baza de date conform cerinţelor beneficiarului, administratorul va trebui să seteze
valori noi pentru anumiţi parametri specificaţi mai jos, astfel:
• DB_NAME defineşte numele bazei de date. Se formează dintr-un şir de
maximum opt caractere. Dacă nu se furnizează, Oracle atribuie bazei de date un
nume standard. Acesta se găseşte în fişierul cu parametrii furnizat o dată cu
software-ul Oracle. În timpul creerii bazei de date numele acesteia este scris în
fişierele de date, de control şi de log.
Exemplu: DB_NAME = BAZA1
• DB_DOMAIN este format dintr-un şir de caractere şi defineşte domeniul
din reţea căruia aparţine baza de date, de obicei este definit de numele
organizaţiei căreia aparţine baza de date. Dacă se utilizează numele domeniului

6
din Internet, atunci partea adresei de e-mail care urmează după caracterul ”@”
este foarte bună pentru a fi folosită ca valoare pentru acest parametru.
Exemplu: DB_DOMAIN = BUC.ORG.COM
• GLOBAL_NAMES defineşte numele global al bazei de date în cadrul reţelei
de calculatoare şi este format din numele bazei de date şi numele domeniului
separate prin punct. Acest parametru mai poate lua şi valorile: TRUE (caz în care
se forţează ca numele global al bazei de date să fie identic cu cel al bazei de date)
sau FALSE (numele global nu are semnificaţie, nu se utilizează).
Exemplu: GLOBAL_NAMES =FALSE
• CONTROL_FILES defineşte numele fişierelor de control ce vor fi create
pentru baza de date (se va furniza pentru fiecare fişier calea completă de acces la
acesta). Este recomandat ca să se definească cel puţin două fişiere de control, care
să fie plasate pe două discuri diferite.
Exemplu: CONTROL_FILES =diska:cntrl1.ora,diskb:cntrl2.ora
• LOG_FILES specifică numărul maxim de grupuri de fişiere de log ce pot fi
utilizate pentru o bază de date. Ia valori de la 2 la 255. Acest parametru specifică
totodată şi numărul minim de fişiere de log ce pot fi deschise pentru o bază de
date.
• DB_FILE_MULTIBLOCK_READ_COUNT defineşte numărul de blocuri
citite simultan pentru accesarea unei tabele a bazei de date. Este folosit pentru
optimizarea parcurgerii totale a unei tabele atunci când se caută o anumită valoare
a unei coloane aferentă unui rând din aceasta.
• REMOTE_LOGIN_PASSWORDFILE specifică dacă se foloseşte sau nu
fişierul cu parole pentru identificarea utilizatorilor ce pot executa activităţi de
administrator. Poate lua valorile: NONE nu se foloseşte fişierul de parole iar
utilizatorul care va executa activităţi de administrare trebuie să fie
autentificat de către sistemul de operare gazdă; EXCLUSIVE se foloseşte un
singur fişier cu parole pentru o singură bază de date. Pe lângă utilizatorii SYS şi
SYSTEM şi alţi utilizatori pot executa sarcini de administrare; SHARED se
foloseşte un singur fişier cu parole pentru mai multe baze de date, caz în care
singurii utilizatori ce pot executa activităţi de administrare sunt SYS şi
SYSTEM. În acest caz nu se pot adăuga alţi utilizatori în fişierul cu parole.
• DB_FILES specifică numărul maxim de fişiere de date ce pot fi
deschise de către o bază de date. De fiecare dată când se modifică acest parametru
baza de date se opreşte şi apoi se reporneşte.
• LOG_CHECKPOINT_INTERVAL specifică frecvenţa punctelor de control
(checkpoites) ;
• LOG_CHECKPOINT_TIMEOUT specifică timpul maxim dintre două
puncte de control în secunde;
• PROCESSES specifică numărul maxim de utilizatori care se pot conecta
simultan la baza de date, iar acest număr trebuie să fie mai mare decât numărul
total de procese background, Job Queue şi Parallel Query;
• ROLLBACK_SEGMENTS defineşte toate segmentele rollback pe care o
instanţă le poate acapara la momentul pornirii. Valoarea acestui parametru se dă
sub forma unei liste de valori.
Exemplu:
ROLLBACK_SEGMENTS = (rbseg1, rbseg2, rbseg3, rbseg4)
• LICENSE_MAX_SESSIONS specifică numărul maxim de utilizatori
concurenţiali ce pot fi admişi în timpul unei sesiuni;

7
• LICENSE_MAX_USERS specifică numărul maxim de utilizatori ce pot fi
creaţi pentru o bază de date. LICENSE_MAX_SESSIONS şi
LICENSE_MAX_USERS nu pot avea simultan valori diferite de zero, deci unul
din aceşti parametri trebuie să fie setat pe zero;
• LICENSE_SESSIONS_WARNING specifică numărul de utilizatori
concurenţiali. Dacă se depăşeşte, se emite un mesaj de atenţionare;
• TRANSACTIONS_PER_ROLLBACK_SEGMENT specifică numărul
tranzacţiilor concurente permise pe un segment rollback;
• AUDIT_TRAIL activează sau dezactivează scrierea rândurilor în fişierul
de audit. Înregistrările de audit nu se scriu dacă parametrul are valoarea NONE
sau lipseşte.

Zona de memorie SGA (System Global Area) conţine următoarele structuri de


memorie: database buffer cache, redo log buffer şi shared pool. Database Buffer
Cache este porţiunea din SGA ce conţine blocurile de date citite din fişierele de date
ale bazei de date. Redo log buffer este zona în care se păstrează informaţii despre
modificările efectuate în baza de date. Shared pool este o zonă care conţine la rândul
său trei structuri de memorie: library cache, dictionary cache şi control structures.
Dicţionarul de date al bazei de date este citit în zonele library cache şi dictionary
cache.

Mărimea SGA este influenţată de valorile parametrilor următori:


• DB_BLOCK_SIZE defineşte, în bytes, mărimea unui singur bloc de date.
Valorile tipice pentru acest parametru sunt 2048 şi 4096;
• DB_BLOCK_BUFFERS specifică numărul de buffere ale bazei de date
disponibile în zona database buffer cache, a cărei mărime este egală cu
DB_BLOCK_SIZE * DB_BLOCK_BUFFERS;
• LOG_BUFFER determină mărimea în bytes a zonei redo log buffer
• SHARED_POOL_SIZE specifică mărimea în baiţi a ariei Shared pool.
Acest parametru poate accepta valori numerice urmate de literele "K" sau "M",
unde "K" înseamnă că numărul va fi multiplicat cu 1000, iar "M" înseamnă că
numărul va fi multiplicat cu 1000000.
• OPEN_CURSORS specifică numărul maxim de cursoare pe care o
sesiune le poate deschide simultan. Valoarea asumată este de 50. Este bine ca
acest număr să fie cît mai mare pentru a nu avea probleme cu rularea unei
aplicaţii.
• TRANSACTIONS specifică numărul maxim de tranzacţii concurente.
O valoare mare a acestui parametru determină mărirea zonei de memorie SGA.

Exemple de creare a unei baze de date


1) CREATE DATABASE;
În acest caz se crează o bază de date Oracle în care toţi parametrii comenzii
CREATE DATABASE iau valorile standard furnizate de firma Oracle.
2) CREATE DATABASE baza1
LOGFILE GROUP 1 ('diskb:log1.log', 'diskc:log1.log') SIZE 50K,
GROUP 2 ('diskb:log2.log', 'diskc:log2.log') SIZE 50K
MAXLOGFILES 5
MAXLOGHISTORY 100
MAXDATAFILES 10
ARCHIVELOG

8
CHARACTER SET US7ASCII DATAFILE 'diska:datfile1.dat' SIZE 2M DATAFILE
'disk1:datfile2.dbf' AUTOEXTEND ON disk2:datfile3.dbf' AUTOEXTEND ON
NEXT 10M MAXSIZE UNLIMITED;

După crearea unei baze de date, instanţa Oracle poate fi lăsată să ruleze, iar baza de
date este deschisă şi montată pentru utilizare normală. Pentru opririle şi pornirile
ulterioare se poate utiliza Oracle Enterprise Manager.

2.2.2. Pornirea şi oprirea bazei de date

O bază de date şi instanţa Oracle se poate porni cu utilitarul Oracle Enterprise


Manager folosind fereastra de dialog Startup Database. O instanţă şi o bază de
date asociată se pot porni în mai multe moduri.
Pornirea instanţei fără montarea (urcată – mount) bazei de date se face
atunci când dorim să creăm o bază de date. Activitatea se execută din fereastra de
dialog Startup Database prin selectarea butonului radio Startup Nomount;
Pornirea instanţei şi montarea bazei de date, aceasta rămânând închisă se
execută atunci când dorim să executăm anumite activităţi de întreţinere: redenumirea
fişierelor de date; adăugarea, ştergerea sau redenumirea fişierelor redo log;
recuperarea integrală a bazei de date; Această pornire se execută din fereastra de
dialog Startup Database prin selectarea butonului radio Startup Mount. Montarea
bazei de date se poate executa şi după pornirea unei instanţe fără bază de date
montată, cu ajutorul comenzii SQL ALTER DATABASE cu opţiunea MOUNT.
Exemplu: SQL> ALTER DATABASE baza1 MOUNT;
Pornirea instanţei, montarea bazei de date şi deschiderea acesteia se face
în mod nerestricţionat (accesibilă tuturor utilizatorilor care au cu privilegiul
CREATE SESSION) sau restricţionat (accesibilă doar utilizatorilor de tip
DBA, utilizatorilor cu privilegiile CREATE SESSION şi RESTRICTED SESSION).
În modul de pornire restricţionat se pot executa activităţi ca:
- recrearea indecşilor;
- exportul sau importul datelor bazei de date;
- încărcarea datelor cu utilitarul SQL*Loader;
- blocarea temporară a accesului utilizatorilor obişnuiţi la baza
de date.
Pornirea în mod nerestricţionat se face din fereastra de dialog Startup Database prin
selectarea butonului radio Startup Open.
Pornirea în mod restricţionat se face din fereastra de dialog Startup Database prin
selectarea butonului radio Restrict.

Deschiderea unei baze de date se poate face după ce instanţa a fost pornită, baza de
date montată dar închisă, cu ajutorul comenzii SQL ALTER DATABASE cu
opţiunea OPEN.
Exemplu: SQL> ALTER DATABASE baza1 OPEN;

Transformarea modului de pornire normală a unei baze de date în modul


restricţionat se poate face şi cu comanda SQL ALTER SYSTEM cu opţiunea
ENABLE RESTRICTED SESSION , iar revenirea la situaţia iniţială se face cu
aceeaşi comandă dar cu opţiunea DISABLE RESTRICTED SESSION

9
Exemplu:
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM DISABLE RESTRICTED SESSION;

În anumite circumstanţe este posibil ca activităţile de pornire a bazei de date şi


instanţei Oracle să se execute altfel decât în mod uzual. Astfel putem avea:
• pornirea forţată a unei instanţe, care se poate realiza atunci când
instanţa curentă nu poate fi oprită cu succes prin folosirea butoanelor radio
Normal sau Immediate din fereastra de dialog Startup. În acest caz se poate forţa
pornirea unei noi instanţe Oracle, care va determina oprirea instanţei
anterioare aflată în situaţia de mai sus.
• pornirea unei instanţe, montarea bazei de date şi pornirea procesului de
recuperare a bazei de date, a tabelelor spaţiu sau a fişierelor de date, care se
execută atunci când ştim că mediul bazei de date are nevoie de recuperare.
• pornirea în modul exclusiv sau paralel, care se face atunci când avem un
server Oracle care permite accesul mai multor instanţe la aceeaşi bază de date.
• pornirea automată a bazei de date la momentul pornirii sistemului de
operare, se face dacă dorim acest lucru.
• pornirea unei instanţe şi a unei baze de date la distanţă, se face atunci când
serverul Oracle este o parte a unui sistem de baze de date distribuite.

Oprirea unei baze de date se poate face în două moduri:


- normal sau
- forţat.
Modul normal, în care oprirea bazei de date se face ca revers al operaţiei de
pornire normală, sens în care se execută închiderea bazei de date, demontarea bazei de
date şi oprirea instanţei Oracle. Activitatea se execută din fereastra de dialog
Shutdown Database prin selectarea butonului radio Normal. Oprirea unei baze de date
în condiţii normale presupune executarea de către Oracle a următoarelor activităţi:
• oprirea conectărilor la baza de date;
• deconectarea tuturor utilizatorilor;
• la următoarea pornire a bazei de date nu se pornesc procedurile de
recuperare.
Modul forţat se poate executa în două moduri:
- imediat sau
- prin anularea instanţei.
Oprirea imediată a bazei de date se execută în cazul unui incident iminent. În
cadrul acestei opriri Oracle
• execută instrucţiunea SQL aflată în lucru şi orice altă tranzacţie
nefinalizată este anulată prin procesul de rollback;
• toţi utilizatorii conectaţi sunt deconectaţi imediat.
Oprirea se face din fereastra de dialog Shutdown Database prin selectarea butonului
Immediate.

Oprirea prin anularea instanţei se execută dacă baza de date sau una din aplicaţiile
sale funcţionează anormal şi nici una din metodele de oprire anterioare nu
funcţionează. Această oprire se execută din fereastra de dialog Shutdown prin setarea
butonului radio Abort.

În timpul acestei opriri Oracle

10
• finalizează instrucţiunile SQL aflate în lucru, tranzacţiile nefinalizate
nu mai sunt aduse la starea anterioară momentului începerii acestora
(nu mai sunt anulate prin procesul de roll back), iar
• toţi utilizatorii sunt deconectaţi imediat.

3. Crearea și gestionarea tabelelelor

3.1. Sintaxa de bază a instrucțiunilor SQL

Scrierea instrucțiunilor SQL

• Instrucțiunile SQL pot fi scrise cu litere mari sau mici


• Instrucțiunile SQL pot avea una sau mai multe linii
• Cuvintele cheie nu pot fi abreviate sau despărțite în linii diferite
• De obicei, cuvintele cheie sunt introduse cu majuscule, iar toate celelalte
cuvinte, ca numele de tabele și coloane, sunt introduse cu litere mici;
• Clauzele, de obicei, sunt plasate pe linii separate pentru a spori lizibilitatea
• Tab-urile și alinierile sunt folosite pentru a spori lizibilitatea

Executarea instrucțiunilor SQL

• Poziționarea punct și virgulei (;) la sfârșitul ultimei clauze;


• Poziționarea unui slash (/) la sfârșitul ultimei linii din buffer;
• Punerea unui slash la promterul SQL;
• În cadrul SQL*Plus – comanda RUN la promterul SQL.

Structura tabelelor
• Tabelele pot fi create în orice moment, chiar în momentul când utilizatorul
folosește baza de date.
• Nu este necesară specificarea mărimii unei baze de date. Este important,
totuși, cât spațiu va ocupa tabelul în timp.
• Structura unui tabel poate fi modificată dinamic.

Convenții pentru denumirea tabelelor

• Numele trebuie să înceapă cu o literă;


• Numele poate avea o lungime de 1-30 caractere;
• Caracterele permise sunt numai A-Z, a-z, 0-9, $ și #;
• Un utilizator nu poate avea două tabele cu nume identice;
• Numele unui tabel nu poate fi un nume rezervat (cuvânt cheie).

Îndrumări privind denumirea tabelelor


• Folosiți nume descriptive pentru tabele sau alte obiecte de tip bază de date;
• Folosiți aceleași nume pentru aceleași entități din tabele diferite. De
exemplu, având două tabele, unul cu angajați (ang) și unul cu
departamente (dept), coloana cu numărul departamentului este denumită
nr.dept atât în tabelul ang, cât si în tabelul dept.

11
3.2. Crearea tabelelor
Pentru a crea un tabel, se utilizează Comanda CREATE TABLE
Este posibilă realizarea unui tabel dacă se dispune de:
- Drepturi pentru crearea unei tabele;
- Unitate de stocare

Sintaxa instrucțiunii este:

CREATE TABLE [schema] table


(column datatype [DEFAULT expr]);

• Trebuie specificate:
- Numele tabelului
- Numele coloanei, tipul de dată pentru coloană și mărimea tipului de data.

Semnificația termenilor din comandă:


- schema numele posesorului tabelului;
- table numele tabelului;
- column numele coloanei;
- datatype tipul de datădin coloana respectivă.
- DEFAULT expr specifică valoarea implicită, dacă aceasta lipsește într-o
comandă ulterioară de inserare (INSERT);
Referirea tabelelor unui alt utilizator

• Tabelele ale căror proprietar sunt alți utilizatori nu sunt în shema


utilizatorului curent;
• Pentru a fi referite, trebuie folosit numele proprietarului tabelului.

Opțiunea DEFAULT

• Specifică valoarea implicită pentru o coloană într-o operație de inserare;

… data_angajării DATE DEFAULT SZSDATE, …

• Valorile permise sunt valori literale, expresii sau funcții SQL;


• Valorile ilegale sunt numele altor coloane;
• Valoarea implicită trebuie să aibă același tip cu cel al coloanei.

Unei coloane i se poate asigna o valoare implicită utilizâd opțiunea


DEFAULT. Aceasta opțiune previne atribuirea unor valori null coloanelor inserate
fără o valoare explicită. Valoarea poate fi una literală, o expresie sau o funcție SQL,
cum ar fi SYSDATE sau USER, dar valoarea nu poate fi cea a unei alte coloane, cum
ar fi NEXVAL sau CURRVAL. Valoarea implicită trebuie să se potrivească cu tipul
de dată al coloanei.

12
Exemplu de creare a unui tabel:

SQL> CREATE TABLE DEPT4


(nr.dept NUMBER(1),
numedept VARCHAR(14),
localitate VARCHAR(13));

În urma execuției comenzii, dacă este corectă, va apărea mesajul:

Table created.

Ca urmare a acestei comenzi, se creează un tabel dept4 având capul de tabel de forma:

nr.dept numedept localitate

Valorile care vor fi introduse vor fi


numărul departamenului - un număr de o cifră;
numele departamentului - șir de caractere de lungime maximă 14;
localitate - șir de caractere de lungime maximă 13;

3.3. Modificarea unui tabel, utilizând comanda ALTER TABLE

Cu ajutorul comenzii ALTER TABLE se pot realiza următoarele acțiuni:


• Adăuga o coloană utilizând clauza ADD:

SQL> ALTER TABLE table


ADD (column datatype [DEFAULT expr]
[, column datatype] …);

• Modifica o coloană existentă utilizând clauza MODIFY:

SQL> ALTER TABLE table


MODIFY (column datatype [DEFAULT expr]
[, column datatype] …);

• Definirea unei valori implicite pentru o coloană.

Comanda este utilă dacă se dorește modificarea structurii unei tabele.


Sintaxa:
- table numele tabelului;
- column numele noii coloane;
- datatype tipul datei si lungimea;

13
- DEFAULT expr specifica valoarea implicita pentru coloana.

Exemplu de adaugare a unei coloane

SQL> ALTER TABLE dept4


ADD (cod_dept VARCHAR(9));

Mesajul primit ca urmare a execuției comenzii:

Table altered.
Rezultatul execuției va fi un tabel cu 4 coloane:

nr.dept numedept localitate cod_dept

Observatii:
Se pot adăuga, modifica coloane, dar nu se pot elimina din tabelă.
Nu se poate specifica locul de apariție al noii coloane. Noua coloana devine
ultima coloană. Dacă tabelul conține înregistrari în momentul adăugării unei noi
coloane, atunci noua coloană se inițializează cu valori nule pentru toate înregistrarile.

Exemplu de modificare a unei coloane

Se pot modifica specificațiile coloanelor utilizând comanda ALTER TABLE,


cu clauza MODIFY. Modificările permise pot fi schimbarea tipului de dată, mărimea
și valoarea inițială.

SQL> ALTER TABLE dept4


MODIFY (nr.dept NUMBER(2));

Table altered.

De acum, numărul departamentului poate fi scris cu două cifre.

Observații:
• Se poate mări lățimea sau precizia unei coloane numerice
• Se poate micșora lățimea unei coloane dacă aceasta conține numai valori nule sau
dacă tabelul nu are rânduri
• Se poate schimba tipul de date dacă coloana conține numai valori null
• Se poate converti o coloană de tip CHAR la una de tip VARCHAR2 sau invers
dacă aceasta conține valori null sau dacă nu i se schimbă lățimea
• Schimbarea valorii predefinite pentru o coloană afecteaza numai inserările
ulterioare în tabel

14
3.3 Ștergerea unui tabel
Cum spuneam, nu poate fi ștearsă o coloană dintr-un tabel. Singura opțiune de
ștergere este a întregului tabel.

Sinatxa:
DROP TABLE table; table- numele tabelului care se șterge.

În urma execuției comenzii

SQL> DROP TABLE dept4

și afișării mesajului

Table dropped.

tabelul dept4 a fost șters.

Comanda DROP TABLE șterge definiția unei tabele. Când se aplică comanda
DROP unei tabele, baza de date pierde toate înregistrările din tabelă, împreună cu
indexurile asociate acesteia.
Comanda DROP TABLE este ireversibilă.

Observații:
• Toate datele sunt șterse
• Orice vedere sau sinonim va rămâne dar vor fi invalide
• Orice tranzacție în curs va fi finalizată
• Numai utilizatorul care a creat tabelul sau cel care are privilegiul DROP ANY
TABLE poate șterge un tabel

3.4. Modificarea numelui unui tabel


Pentru a modifica numele unei tabele, reprezentări, secvențe sau sinonim se
foloseste comanda RENAME

Sintaxa:
RENAME old_name TO new_name;
- old_name numele vechi al obiectului;
- new_name numele nou al obiectului;

SQL> RENAME dept4 TO dept;

Mesaj de acțiune îndeplinită:

Table renamed.

Observație:

Numai proprietarul obiectului poate modifica numele obiectului.

15
3.5. Ștergerea înregistrărilor unui tabel
Există două opțiuni de ștergere:

• TRUNCATE TABLE
Comanda șterge toate înregistrarile din tabelul specificat, eliberând spațiul
folosit de tabelă. Operațiunea este ireversibilă.

Sinatxa:
TRUNCATE TABLE table;
- table numele tabelului.

SQL> TRUNCATE TABLE department;

Table truncated.

• DELETE
Sintaxa:
DELETE FROM table;
sau
DELETE * FROM table;

șterge înregistrarile din tabel, dar nu eliberează spațiul de stocare (făcând


astfel posibilă readucerea înregistrărilor).

3.6. Adaugarea comentariilor unei tabel


Se pot adăuga comentarii unui tabel utilizând comanda COMMENT.
Comentariile pot fi vizualizate interogând dicționarul de date, și anume:
- ALL_COL_COMMENTS;
- USER_COL_COMMENTS;
- ALL_TAB_COMMENTS;
- USER_TAB_COMMENTS.

Se pot adăuga comentarii de până la 2000 bytes coloanelor, tabelelor, etc.

Sinatxa:
COMMENT ON TABLE table | COLUMN table.column IS text;
- table numele tabelului;
- column numele coloanei din tabel;
- text textul comentariului.

SQL> COMMENT ON TABLE dept


IS “Informații departamente”;

La finalizarea comenzii apare mesajul:

16
Comment created

Se poate renunța la un comentariu, setându-l ca fiind un șir vid (‘’).

SQL> COMMENT ON TABLE dept IS “”;

REZUMAT

CREATE TABLE
• Creează o tabelă
ALTER TABLE
• Modifică structura tabelelor
• Schimbă lățimea sau tipul de date al coloanelor, poate adăuga coloane
DROP TABLE
• Șterge rândurile și structura tabelului
• Ireversibilă
RENAME
• Redenumește o tabelă, vedere, secvență sau sinonim
TRUNCATE
• Șterge toate rândurile dintr-o tabelă și eliberează spațiul folosit de tabelă
• Comanda DELETE șterge doar rândurile, nu eliberează spațiul
COMMENT
• Adaugă un comentariu la o tabelă sau la o coloană
• Vizualizarea comentariilor se face prin interogarea dicționarului de date

17
ÎNCĂRCAREA ȘI ACTUALIZAREA DATELOR ÎN TABELE
INSTRUCȚIUNEA SELECT

Sintaxa de bază a instrucțiunilor SQL

Scrierea instrucțiunilor SQL

• Instrucțiunile SQL pot fi scrise cu litere mari sau mici


• Instrucțiunile SQL pot avea una sau mai multe linii
• Cuvintele cheie nu pot fi abreviate sau despărțite în linii diferite
• De obicei, cuvintele cheie sunt introduse cu majuscule, iar toate celelalte cuvinte, ca
numele de tabele și coloane, sunt introduse cu litere mici;
• Clauzele, de obicei, sunt plasate pe linii separate pentru a spori lizibilitatea
• Tab-urile și alinierile sunt folosite pentru a spori lizibilitatea

Executarea instructiunilor SQL

• Poziționarea punct și virgulei (;) la sfârșitul ultimei clauze;


• Poziționarea unui slash (/) la sfârșitul ultimei linii din buffer;
• Punerea unui slash la promterul SQL;
• În cadrul SQL*Plus – comanda RUN la promterul SQL.

Tipuri de date

Tipuri de date scalare predefinite

Tip Descriere
CHAR(n) Șir de caractere cu lungime fixă (n octeti)
VARCHAR2(n) Șir de caractere cu lungime variabilă (maxim n octeti)
NUMBER (p,s) Date numerice de lungime variabilă. Tipul number permite definirea
preciziei și a scalei. Precizia este egală cu numărul total de cifre ale
numarului; scala se referă la numarul de cifre din dreapta punctului
zecimal. Aceste numere pot fi stocate cu o precizie de pâna la 38 de cifre.
Exemple:
Nr_Articol number
'123456'
Nr_Articol number(6, 2)
'1234.56'
În acest exemplu, (6,2) reprezinta urmatoarele:
·6 este precizia. Precizia este sinonima cu numărul total de cifre permise.
Acest număr include numărul total de cifre din ambele părți ale punctului
zecimal.
· 2 este scala, sau numărul de cifre din dreapta punctului zecimal.
Este recomandabil să se specifice întotdeauna precizia și scala datei, în
acest fel se asigura verificarea integrității datei atunci când aceasta este
introdusă.
DATE Date calendaristice si temporal. Tipul date stochează data calendaristică și
ora în coloanele unui tabel cu precizie de o secundă. Acest tip de dată

1
stocheaza cele patru cifre ale anului, luna, ziua, ora, minutele și secundele
scurse de la miezul nopții.
Pentru operațiile de intrare/iesire de date, formatul prestabilit este DD-
MON-YY. Ora este stocată în format HH:MM:SS. Nu se poate specifica
data în litere. Dacă nu se specifică componenta pentru oră într-o valoare
de tip data, ora prestabilită este 12:00:00 AM. În mod similar, dacă se
omite componenta corespunzătoare datei calendaristice a unei valori de
tip data, data prestabilită este prima zi a lunii curente. Domeniul valid
pentru date calendaristice este 1 Ianuarie 4712 Î.E.N - 1 Ianuarie 4712
E.N.
CLOB Obiecte de tip caracter de lungime mare - 4 gigabytes.
LONG Siruri de caractere de lungime variabilă - 2 gigabytes.
BLOB Date binare nestructurate
BFILE Date binare stocate într-un fisier extern
ROWID Date în format binar ce reprezintă adresa fizică pe disc a înregistrării

Clasificarea comenzilor SQL care permit controlul accesului la BD

Grup DCL (Data Control language)


GRANT - Acordă drepturi pentru un user
REVOKE - Retrage drepturi de la un user

Grup DDL (Data Definition Language)


CREATE obiect - Creare structură tabel, index, vedere
ALTER obiect - Modificare caracteristici tabel, index, sesiune, user, rol,..
DROP obiect - Șterge tabel, index, vedere, trigger, secvență,..
RENAME obiect - Redenumire tabel sau vedere
TRUNCATE TABLE - Șterge toate înregistrările dintr-un tabel

SELECT - Căutare informații în BD

Grup DML(Data Manipulation Language)


UPDATE - Modificare conținut înregistrări dintr-un tabel
INSERT INTO - Adăugare înregistrări într-un tabel
DELETE FROM - Ștergere înregistrări dintr-un tabel

Grup Control tranzacții


COMMIT - Confirmă terminare tranzacție
ROLLBACK - Reface toate modificările BD de la începutul tranzacției (de la ultimul COMMIT)
SAVEPOINT - Creează un punct de reluare în tranzacție

2
ÎNCĂRCAREA ȘI ACTUALIZAREA DATELOR CU COMENZI SQL

ADĂUGAREA DE NOI TUPLURI

Actualizarea datelor se referă la adăugarea unor noi rânduri într-un tabel (cu comanda
INSERT), la modificarea valorilor uneia sau mai multor valori dintr-un rând (cu comanda
UPDATE) şi la ştergerea unui rând dintr-un tabel (cu comanda DELETE).
În vederea adăugarii unor rânduri noi într-un tabel sau într-o vedere se utilizează comanda:

INSERT INTO nume-tabel


[(nume-col1,nume-col2,...)]
{VALUES (valoare 1,valoare2,...) | cerere );

Pentru nume-col1,nume-col2... precizate în paranteze vor fi furnizate valorile


corespunzătoare, iar coloanelor nespecificate le sunt ataşate valori nule.
Coloanele pot fi precizate în orice ordine, însă trebuie asigurată corespondenţa între
numele coloanelor şi valorile furnizate.
În cazul în care anumite coloane nu sunt specificate explicit, se impune ca ordinea în
care apar valorile în comanda INSERT să coincidă cu cea în care coloanele au fost definite la
crearea tabelului.
Dacă nu se mai cunoaşte ordinea de declarare a coloanelor se foloseşte comanda
DESCRIBE care va afişa lista coloanelor definite pentru tabelul respectivă, tipul şi lungimea lor.
Prin forma INSERT...VALUES se introduce în tabel un singur rând. Cu ajutorul valorii
NULL se pot introduce valori nule.

Valori Null
• O valoare NULL este o valoare care nu este diponibilă, este nealocată, necunoscută, sau
neaplicabilă.
• Un NULL nu are același înțeles ca zero sau spațiu.
• Dacă unui rând îi lipsește valoarea datei pentru o anumită coloană, acea valoare este
considerată null.
• Orice tip de coloană poate conține null. Se pot impune restricții cum ar fi NOT NULL sau
PRIMARY KEY care nu permit ca valoarea null să fie folosită în acea coloană.

Pentru a furniza valori pentru o coloană de tip dată calendaristică se poate folosi funcţia
TO_DATE sau cuvântul cheie SYSDATE.
Funcţia TO_DATE permite furnizarea valorilor într-un format diferit de cel standard.

Exemple:

După crearea unui tabel dept:

SQL> CREATE TABLE dept


(nr.dept NUMBER(1),
numedept VARCHAR2(14),
localitate VARCHAR2(13));
Table created.

3
se poate confirma crearea tabelului (utilizând comanda DESCRIBE):

SQL> DESCRIBE dept

Name Null? Type


NR.DEPT NOT NULL NUMBER(1)
NUMEDEPT VARCHAR2(14)
LOCALITATE VARCHAR2(13)

Să se adauge un nou rând în tabelul dept

.SQL> INSERT INTO dept


VALUES (1,'cercetare',’București')
1 record created.

În acest moment, tabelul arată astfel:

dept
nr.dept numedept localitate
1 cercetare București

MODIFICAREA TUPLURILOR DIN TABELE

În funcţie de momentul în care se doreşte realizarea modificărilor asupra bazei de date,


utilizatorul poate folosi una din următoarele comenzi:
SET AUTOCOMMIT IMM[EDIATE] (schimbările se efectuează imediat);
SET AUTOCOMMIT OFF (schimbările sunt păstrate într-un buffer).

La execuţia comenzii COMMIT se permanentizează schimbările efectuate, iar la


execuţia comenzii ROLLBACK se renunţă la schimbările realizate.
În scopul modificării datelor dintr-un tabel se utilizează una din formele sintactice ale
comenzii UPDATE:

UPDATE nume-tabel [sinonim]


SET nume-coloană=expresie|valoare [,nume-coloană=expresie|valoare]
[WHERE condiţie];

UPDATE tabel
SET (coloana, coloana, …) = (SELECT coloana, coloana, …
FROM tabel
WHERE condiție)
WHERE condiție;

Sunt două posibilități de modificare. Una constă în furnizarea în mod explicit a fiecărei
valori pentru câmpurile care trebuie modificate, iar cealaltă posibilitate constă în obţinerea
valorilor în urma unei cereri SQL.
Dacă nu este specificată clauza WHERE, se vor modifica toate rândurile tabelului.

4
(coloana, coloana, …) = (subinterogare) impune ca cererea să conţină pentru fiecare rând un
număr de valori corespunzător numărului de coloane din paranteza care precede caracterul =.
În cazul în care se modifcă o singură coloană, parantezele pot fi omise.

Exemple:
1) Să se modifice câmpul NRSAL din tabelul dept, pentru departamentul cu codul 1,
atribuindu-i valoarea 11.
SQL> UPDATE dept
SET NRSAL=11
WHERE nr.dept= 1;
1 record updated.

2) Să se modifice data de livrare cu data actuală pentru toate produsele cu codul egal cu 33, din
toate comenzile.
SQL> UPDATE comenzi
SET datal=SYSDATE
WHERE codp=33;
1 record updated.

3) Să se modifice data de livrare, cantitatea solicitată şi preţul de livrare pentru produsul cu


codul 33 din comanda cu numărul 11.
SQL> UPDATE comenzi
SET datal=SYSDATE,cant=150, pret=2000
WHERE codp=33 AND nrcom=11;
1 record updated.

ŞTERGEREA TUPLURILOR DIN TABELE

Ştergerea unor rânduri dintr-o tabelă se realizează cu următoarea comandă:

DELETE FROM nume tabel [WHERE condiţie];

Folosirea clauzei WHERE determină ştergerea acelor rânduri care îndeplinesc


condiţia impusă. În această clauză pot fi folosite şi subinterogări (subcereri). Dacă nu este
specificată nicio condiţie, se şterg toate rândurile tabelului.
Ştergerile accidentale pot fi omise, restaurându-se valorile iniţiale prin comanda
AUTOCOMMIT OFF.

Exemple:
1) Să se şteargă datele din tabelul dept.
SQL> DELETE FROM dept;

7 records deleted.

5
2) Să se şteargă datele pentru departamentele care au codul mai mare sau egal cu 10.
SQL> DELETE FROM dept
WHERE nr.dept>=10;
2 records deleted.

3) Să se scrie comanda pentru ştergerea datelor despre salariatul Ionescu. Ştergerile să nu fie
efectuate imediat, ci ulterior.
SQL> SET AUTOCOMMIT OFF
SQL> DELETE FROM salariați
WHERE nume='Ionescu';
1 record deleted.
SQL> COMMIT ;

Comanda SQL SELECT

Comanda SELECT extrage informații din bazele de date.


Folosind comanda SELECT, se pot face următoarele acțiuni:
• SELECȚIE (SELECTION): se pot alege liniile de care este nevoie din tabelele de date. Pot fi
folosite diferite criterii de selecție, pentru a vizualiza numai ceea ce se dorește, nu un întreg
tabel.
• PROIECTARE (PROJECTION): se pot alege coloanele din tabelele de date.
• COMBINAREA (JOIN): se pot uni datele aflate în tabele diferite prin crearea unei legături între
coloanele tabelelor de unde provin datele.

SELECT - SINTAXA DE BAZA

SELECT [ DISTINCT ] {*, coloană [alias] , …..} FROM tabel ;

SELECT identificataore coloane


FROM identificator tabel

Într-o formă mai simpla , instrucțiunea SELECT include urmatoarele:

• Clauza SELECT, care specifică ce coloane vor fi afișate;


• Clauza FROM , care specifică tabelele ce conțin coloanele scrise în clauza SELECT.

Din punct de vedere sintactic:

SELECT este o listă de una sau mai multe coloane;


DISTINCT suprimă duplicatele;
* selectează toate coloanele;
column numele coloanei;
alias dă un alt nume coloanei selectate;
FROM table specifică tabela care conține coloanele.

6
Întrucât au apărut cuvinte specifice limbajului SQL, se prezintă următoarea
Terminologie:

• “cuvânt cheie” se referă la un element SQL predefinit, al cărui înțeles nu poate fi


modificat

De exemplu, SELECT și FROM sunt cuvinte cheie

• “clauza” este o parte dintr-o instructiune SQL.

De exemplu, SELECT numeangajat, numărangajat, .. reprezintă o clauză.


• “instructiune” este o combinație de cuvinte cheie și clauze.
De exemplu, SELECT * FROM angajat este o instrucțiune SQL.

ACȚIUNEA 1:
Selectarea tuturor coloanelor dintr-un tabel

SQL> SELECT *
FROM dept;

Tabelul dept (departamente)


nr.dept numedept localitate
1 Cercetare București
2 Operații Timișoara
3 Conturi Cluj
4 Vânzări Iași

Selectarea tuturor coloanelor si liniilor

Pentru a afișa toate coloanele cu date din tabelă, se va folosi cuvântul cheie SELECT urmat
de un asterix (*).
Ca exemplu, tabela departamente conține trei coloane: nr.dept, numedept și localitate.
Tabelul conține patru linii, pentru fiecare departament.
O variantă de comandă SELECT pentru a afișa toate informațiile din tabel este aceea în care
după SELECT sunt specificate toate numele de coloane.

SQL> SELECT nr.depr,numedept,localitate


FROM dept;
Rezultatul ambelor instrucțiuni va fi de forma:

NR.DEPT NUMEDEPT LOCALITATE


1 CERCETARE BUCUREȘTI
2 OPERAȚII TIMIȘOARA
3 CONTURI CLUJ
4 VÂNZĂRI IAȘI

7
ACȚIUNEA 2:

Selectarea coloanelor dorite dintr-un tabel

SQL> SELECT nr.depr, localitate


FROM dept;

NR.DEPT LOCALITATE
1 BUCUREȘTI
2 TIMIȘOARA
3 CLUJ
4 IAȘI

Instrucțiunea SELECT poate fi folosită pentru a afișa anumite coloane din tabelă, specificând
numele coloanelor, separate prin virgulă.
În exemplu se afișează toate numele și localitățiile din tabela dept.
În clauzele SELECT se specifică coloanele dorite, în ordinea în care se dorește afișarea.
Pentru a afișa localitățiile înaintea numărului departamentului, instrucțiunea SELECT este
următoarea::

SQL> SELECT localitate,nr.dept


FROM dept;

LOCALITATE NR.DEPT
BUCUREȘTI 1
TIMIȘOARA 2
CLUJ 3
IAȘI 4

Modul de afișare
Aliniere implicită
Stânga – caractere
Dreapta – date calendaristice și date numerice
Afișarea implicită LITERE MARI

8
Expresii aritmetice

Crearea expresiilor numerice și de date folosind operatori aritmetici

Operator Descriere
+ Adunare
- Scădere
* Înmulțire
/ Împărțire

Expresii aritmetice

Executând anumite calcule, poate fi modificat modul în care sunt afișate datele dintr-un
tabel. Calculele se pot efectua utilizind operațiile aritmetice. Expresiile aritmetice pot conține nume
de coloane, constante numerice și operatori aritmetici.

Operatori aritmetici

Operatorii aritmetici pot fi utilizați în orice clauză SQL, exceptând clauza FROM.

ACȚIUNEA 3:

Prelucrări asupra datelor din tabele folosind operatori aritmetici


Fie tabelul cu angajați:

Tabel ang

a_nume data_angajare salariu


Ionescu 11 ian 2000 5500
Popescu 18 nov 2011 1550
Vasilescu 23 aug 2011 1800
Andronache 1 mai 2017 2250
Georgescu 2 sept 2000 3500
Tache 22 iul 2015 1450

Folosind comanda

SQL> SELECT a_nume, salariu, salariu+500


FROM ang;

A_NUME SALARIU SALARIU+500


IONESCU 5500 6000
POPESCU 1550 2050
VASILESCU 1800 2300
ANDRONACHE 2250 2750
GEORGESCU 3500 4000
TACHE 1450 1950

9
În exemplul dat, s-a folosit operatorul adunare pentru a crește salariile cu 500 lei pentru toți
angajații și afișarea noii coloane SALARIU+500 la ieșire.
În urma adunării, coloana rezultat (SALARIU+500) nu este o nouă coloană în tabela ang; ea apare
doar la afișare. Implicit, denumirea noii coloane vine de la operația care a generat-o, în acest caz
SALARIU+500.

Prioritatea operatorilor

• Înmulțirea și împărțirea au prioritate față de adunare și scădere.


• Operatorii de aceeași prioritate sunt evaluați în ordinea apariției, de la stânga la dreapta.
• Pentru a modifica prioritățile și a clarifica regulile sunt folosite parantezele.

Parantezele pot forța ca expresia din paranteze să fie evaluată prima.

SQL> SELECT a_nume, salariu, 12*salariu+1000


FROM ang;

A_NUME SALARIU 12*SALARIU+1000


IONESCU 5500 67000
POPESCU 1550 19600
VASILESCU 1800 22600
ANDRONACHE 2250 28000
GEORGESCU 3500 43000
TACHE 1450 18400

Se observă că sunt afișate câmpurile nume, salariul lunar și salariul anual + o bonificație ale
angajaților. Înmulțirea se efectuează înaintea adunării.

Folosirea parantezelor pentru a întări ordinea firească a operațiilor va arăta astfel:

SQL> SELECT a_nume, salariu, (12*salariu)+1000


FROM ang;

operația nu va schimba rezultatul:

A_NUME SALARIU 12*SALARIU+1000


IONESCU 5500 67000
POPESCU 1550 19600
VASILESCU 1800 22600
ANDRONACHE 2250 28000
GEORGESCU 3500 43000
TACHE 1450 18400

10
Folosirea parantezelor pentru a schimba prioritatea operatorilor

Folosind parantezele, pot fi modificate regulile precedenței operatorilor, pentru a specifica


ordinea în care să fie folosiți operatorii.
Pentru a afișa numele, salariul si salariul anual + beneficii ale angajaților.
De această dată, calculul ultimei informații se va face utilizând salariul lunar plus o prima, totul
înmulțit cu 12. Datorită parantezelor, adunarea are prioritate față de înmulțire.

SQL> SELECT a_nume, salariu, 12*(salariu+100)


FROM ang;

A_NUME SALARIU 12*(SALARIU+100)


IONESCU 5500 67200
POPESCU 1550 19800
VASILESCU 1800 22800
ANDRONACHE 2250 38200
GEORGESCU 3500 43200
TACHE 1450 18600

Definirea valorii nule (null vallue)

• Valoarea nul are înțeles de valoare indisponibilă, neatribuită, necunoscută sau


inaplicabilă
• Valoarea nul nu are același înțeles cu zero sau spațiu

SQL> SELECT a_nume, salariu, comision


FROM ang;

A_NUME SALARIU COMISION


IONESCU
POPESCU
VASILESCU
ANDRONACHE 0
GEORGESCU
TACHE 0

Dacă o linie nu are date pentru o coloană particulară, aceasta valoare se numește nulă.
Valoarea nul este o valoare indisponibila, neatribuită, necunoscută sau inaplicabilă.
Valoarea nul nu este aceeași cu zero sau spațiu. Zero este număr iar spațiul este un caracter.
Coloanele din orice tip pot conține valoarea nulă, cu excepția celor care au fost definite
nenule sau chei primare în coloanele create.
În coloana COMISION din tabela ang, absența valorilor arată că acei angajați nu sunt
îndreptățiți să primească comisioane. Valoarea vidă (nulă) reprezintă acest fapt. Numai Andronache
și Tache pot avea comision. În cazul de față, au comisionul 0 nu null.

11
Valoarea nulă în expresiile aritmetice

Expresiile aritmetice care conțin valoarea nul sunt evaluate ca nule.

SQL> SELECT a_nume, 12*salariu+comision


FROM ang
where a_nume=’IONESCU’;

A_NUME 12*SALARIU+COMISION
IONESCU

Dacă o coloană dintr-o expresie aritmetică conține valoarea nulă, rezultatul este nul.
În exempl, angajatul IONESCU primește comision. Deoarece coloana COMISION în
expresia aritmetică este nulă, rezultatul este nul.

Definirea alias-urilor pentru coloane

• Redenumesc numele coloanei


• Urmează imediat după numele coloanei; opțional, poate apărea cuvântul cheie AS între
numele coloanei și alias
• Sunt necesare ghilimele ( “ ” ) dacă aliasul conține spații , caractere speciale sau au
importanță literele mari (mici)

Specificarea aliasului se face după numele coloanei în lista SELECT, folosind spațiul ca
separator. Implicit, capul de tabel obținut prin alias este scris cu litere mari. Dacă aliasul conține
spații, caractere speciale (ca $ sau #), sau au importanță literele mari (mici), aliasul va fi scris între
ghilimele (“ ”).

SQL> SELECT a_nume AS nume, 12*(salariu+100) salariu_anual


FROM ang;

NUME SALARIU_ANUAL
IONESCU 67200
POPESCU 19800
VASILESCU 22800
ANDRONACHE 38200
GEORGESCU 43200
TACHE 18600

Sunt afișate numele și salariul anual al tuturor angajaților. Cuvântul cheie AS a fost folosit înainte
de alias. Rezultatul interogării este același dacă cuvântul cheie AS este folosit sau nu. Un alt aspect
este că nume și salariu_anual au fost scrise în interogare cu litere mici iar afișarea s-a făcut cu
litere mari. Rămâne valabil faptul că, implicit, capul de coloană este afișat cu litere mari.

12
SQL> SELECT a_nume nume, 12*(salariu+100) “Salariu anual”
FROM ang;

NUME Salariu anual


IONESCU 67200
POPESCU 19800
VASILESCU 22800
ANDRONACHE 38200
GEORGESCU 43200
TACHE 18600

Deoarece Salariu anual implică folosirea spațiului, aliasul trebuie scris între ghilimele. Astfel, va fi
afișat exact cum a fost scris în expresia SELECT. De remarcat că a fost scris numai cu inițială mare,
restul literelor, mici.

Operatorul de concatenare

• Concatenează coloanele sau șirurile de caractere cu alte coloane


• Este reprezentat de două bare verticale (||)
• Rezultă o coloană care este o expresie caracter

Folosind operatorul de concatenare, se pot lega coloane de alte coloane, expresii aritmetice sau
valori constante pentru a creea expresii caracter. Coloanele de o parte și de alta a operatorului sunt
combinate pentru a face o singură coloană de ieșire.

SQL> SELECT nr.dept || numedept AS “Departament”


FROM dept;

nr.dept numedept localitate


1 Cercetare București
2 Operații Timișoara
3 Conturi Cluj
4 Vânzări Iași

Departament
1CERCETARE
2OPERAȚII
3CONTURI
4VÂNZĂRI

În exemplu, nr.dept si numedept sunt concatenate și li se dă aliasul Departament. Numărul


departamentului și numele acestuia sunt combinate pentru a face o singură coloană de ieșire. Pentru
a face mai ușor de citit instrucțiunea SELECT a fost folosit cuvantul cheie AS înaintea numelui
aliasului.

13
Șiruri de caractere
• Un “literal” este un caracter, expresie sau numar inclus in lista SELECT
• Valorile literale pentru datele calendaristice și caractere trebuie incluse între apostrofi
• Fiecare șir de caractere este afișat o dată pentru fiecare rând întors

SQL> SELECT a_nume || ‘ ‘ || ‘are un salariu anual de ’ || 12*(salariu+100)


AS “Detalii angajați”
FROM ang;

Detalii angajați
IONESCU are un salariu anual de 67200
POPESCU are un salariu anual 19800
VASILESCU are un salariu anual 22800
ANDRONACHE are un salariu anual 38200
GEORGESCU are un salariu anual 43200
TACHE are un salariu anual 18600

Exemplul de mai sus afișează numele si salariile anuale ale tuturor angajaților. Coloana are titlul
Detalii angajați. Spațiile dintre apostrofi din instrucțiunea SELECT îmbunătățesc lizibilitatea ieșirii.

Rânduri duplicate
În mod predefinit, interogările afișează toate rândurile, incluzând rândurile duplicate.

SQL> SELECT nr.dept


FROM dept;

Eliminarea rândurilor duplicate se face folosind cuvântul cheie DISTINCT în clauza SELECT.

SQL> SELECT DISTINCT nr.dept


FROM dept;

Se pot specifica coloane multiple după clauza DISTINCT. Această clauză afectează toate
coloanele selectate și rezultatul reprezintă o combinație de coloane distinctă.

SQL> SELECT DISTINCT nr.depr, numedept


FROM dept;

14
Manipularea datelor

Limbajul de manipulare a datelor

Limbajul de manipulare a datelor (DML) este partea de bază a SQL. Pentru a


adăuga, modifica sau șterge date dintr-o bază de date, se execută o comandă DML.
O colecție de comenzi DML care formează o unitate logică de lucru se numește
tranzactie.
În parcurgerea etapelor de manipulare a datelor, vom considera o bază de date din
domeniul bancar. Atunci când un client al băncii dorește să transfere bani dintr-un
depozit într-un cont curent, tranzacția ar putea consta în 3 operații distincte: scade suma
din depozit, crește suma din contul curent, înregistrează tranzacția în jurnalul de
tranzacții. Trebuie să se garanteze că toate cele 3 comenzi SQL sunt executate în așa fel
încât să mențină echilibrul necesar între conturi. Atunci când, din anumite cauze, una
dintre comenzile tranzacțiilor de mai sus nu se execută, atunci celelalte comenzi ale
tranzacțiilor trebuie să fie anulate.

Adaugarea unei noi înregistrari într-un tabel:

dept
nr.dept numedept localitate 5 dezvolare Constanța
1 cercetare București
2 operații Timișoara
3 conturi Cluj inserează o nouă
4 vânzări Iași înregistrare în
baza de date dept

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța

Schema de mai sus ilustrează adaugarea unui nou departament în tabelul dept.

Pentru a adăuga înregistrări într-un tabel se utilizează comanda INSERT


Sintaxa instucțiunii INSERT (pentru a adăuga o singură înregistrare într-un tabel) :

INSERT INTO tabel [(coloana [,coloana...])]


VALUES (valoare [,valoare...]);
În descrierea sintaxei:
tabel este numele tabelului (bazei de date).
coloana este numele coloanei din tabelul respectiv.
valoare este valoarea corespunzătoare coloanei.

Clauza VALUES adaugă numai câte un rând odată la un tabel.

1
Inserarea unor noi înregistrări

Atunci când se inserează o nouă înregistrare conținând valori pentru fiecare coloană,
valorile se dau în ordinea prestabilită a coloanelor din tabel. Precizarea coloanelor
este optională. Valorile de tip caracter sau data trebuie încadrate de apostrofuri.

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași

Pentru a efectua operația din schemă, sintaxa instrucțiunii INSERT este :

SQL>INSERT INTO dept(nr.dept, numedept, localitate)


VALUES (5, ‘dezvoltare’, ’Constanța’);

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța

Deoarece se poate insera o nouă înregistrare care conține valori pentru fiecare
coloană, lista coloanelor nu este necesară în sintaxa INSERT. Dacă aceasta nu este
precizată, valorile trebuie enumerate conform ordinii coloanelor din tabel.
Pentru claritate, trebuie precizată lista coloanelor în sintaxa INSERT.
Încadrarea între apostrofuri se face numai pentru sirurile de caractere și datele
calendaristice. Valorile numerice nu se încadrează între apostrofuri.

Inserarea de înregistrări cu valori de NULL


Sunt două metode pentru a înregistra valorile NULL :
- metoda implicită: se omite coloana din listă
- metoda explicită: se specifică cuvântul cheie NULL

Metoda implicită:
dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța

SQL>INSERT INTO dept(nr.dept, numedept)


VALUES (6, ‘control’);
1 row created.

2
dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța
6 control

Metoda explicită:

SQL>INSERT INTO dept


VALUES (7, ‘finanțe’, NULL);
1 row created.

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța
6 control
7 finanțe

Orice coloana care nu este specificată explicit în listă, va primi o valoare nulă în
noua înregistrare.

Inserarea de valori speciale folosind funcții SQL:

Fiind dat un tabel al angajaților :

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

pentru a insera o nouă înregistrare, se lansează comanda :

SQL>INSERT INTO ang(a_nume, data_angajare, salariu, post,nr.dept)


VALUE (‘Ion’, SYSDATE, 4000, ‘economist’, NULL);

1 row created.

ang

3
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Ion 1 oct 2017 4000 economist

Funcția SYSDATE furnizează data curentă.

Inserarea unor valori specifice de tip dată calendaristică:

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Ion 1 oct 2017 4000 economist

SQL>INSERT INTO ang


VALUES (‘Costache’, TO_DATE (‘20030309', 'yyyymmdd'), 3000,
‘agent vânzări’, NULL);

1 row created.

a_nume data_angajare salariu post nr.dept


Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Ion 1 oct 2017 4000 economist
Costache 9 mar 2003 3000 agent vânzări

Pentru a se specifica o anume dată calendaristică, se utilizează funcția TO_DATE

Diferite moduri de utilizare a acestei funcții:

TO_DATE('2003/07/09', 'yyyy/mm/dd')
Rezultat: valoarea datei July 9, 2003

TO_DATE('070903', 'MMDDYY')
Rezultat: valoarea datei July 9, 2003

4
TO_DATE('20020315', 'yyyymmdd')
Rezultat: valoarea datei Mar 15, 2002

Copierea înregistrarilor dintr-un alt tabel:

Comanda INSERT poate fi folosită pentru a adăuga înregistrări într-un tabel,


valorile pentru câmpuri fiind extrase dintr-un tabel existent. Pentru aceasta, se folosește
în locul clauzei VALUES, o subinterogare. Numărul de coloane din clauza INSERT
trebuie să corespundă celui din subinterogare.

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

manager
nume salariu data_angajare
Calimente 7000 2 aug 2010

Având tabelele ang și manager, se poate copia o linie din tabelul ang în manager
cu comanda:

SQL> INSERT INTO manager ( nume, salariu, data_angajare)


SELECT a_nume, salariu, data_angajare
FROM ang
WHERE post = 'CEO';
1 row created.

manager
nume salariu data_angajare
Calimente 7000 2 aug 2010
Iancu 16000 25 sept 2017

Sintaxa comenzii INSERT INTO, pentru copierea informațiilor dintr-un tabel în alt tabel,
este următoarea:

INSERT INTO tabel [ coloana ( , coloana ) ]


Subinterogare;

unde: tabel este numele tabelului în care se copiază


coloana este numele coloanei din tabelul în care se
face inserarea.
subinterogare este subinterogarea care returneaza
înregistrarile în tabel.

5
Numărul și tipul câmpurilor (coloanelor) din lista specificată în comanda INSERT trebuie
să corespundă numărului și tipului valorilor din subinterogare.

Modificarea datelor dintr-un tabel

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

modifică o
înregistrare din
a_nume data_angajare salariu post nr.dept tabelul ang
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 2
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

Înregistrarile existente pot fi modificate folosind comanda UPDATE.

Sintaxa comenzii UPDATE este

UPDATE tabel
SET coloana = valoare [,coloana=valoare]
[WHERE condiție];

unde:

tabel este numele tabelului în care se face actualizarea


coloana este numele coloanei din tabel în care se face modificarea.
valoare este noua valoare sau o subinterogare ce produce noua valoare petru
coloana ce se modifică.
condiție identifică înregistrarile care trebuie modificate și este alcătuită din
expresii, nume de coloane, constante, subinterogari și operatori de
comparare.

6
Pentru a identifica o singură înregistrare trebuie folosită drept condiție o coloană care să
facă distincție clară (să asigure unicitatea) între înregistrări. Coloana care asigură această
unicitatea înregistrărilor dintr-o tabelă reprezintă ceea ce se numește cheia primară
Folosirea altor coloane poate determina modificarea mai multor înregistrări.

De exemplu, identificarea unei singure înregistrări în tabelul ang prin nume poate fi
periculoasă, deoarece pot exista mai mulți angajați cu același nume.
Fie următorul tabel
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

Se dorește transferarea lui Ionescu din departamentul 1 la departamentul 2.

Dacă lansăm comanda (fără o clauză WHERE)

SQL>UPDATE ang
SET nr.dept = 2;

7 rows updated.
obținem efectul :
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 2
Popescu 18 nov 2011 1550 18600 inginer 7852 2
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 2
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 2
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 2

7
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

Dacă lansăm comanda UPDATE cu clauza WHERE, dar alegem o coloană care să
nu asigure unicitatea (a_nume):

SQL>UPDATE ang
SET nr.dept = 2;
WHERE a_nume = ‘Ionescu’
2 rows updated.
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 2
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 2

Dacă lansăm comanda UPDATE cu clauza WHERE, dar alegem o coloană care să
asigure unicitatea (matricol):

SQL>UPDATE ang
SET nr.dept = 2;
WHERE matricol = 675
1 row updated.
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 2

8
Actualizarea înregistrărilor folosind subinterogări după mai multe
câmpuri
Există posibilitatea de a modifica câmpuri precizate ale unei înregistrări astfel încât să
coincidă cu câmpurile omoloage ale alte înregistrări:
Acest lucru este posibil prin implementarea mai multor subinterogări în clauza SET a
comenzii UPDATE:

Sintaxa unei astfel de comenzi este:

UPDATE tabel
SET (coloana, coloana, ... ) = (SELECT coloana, coloana,
FROM tabel
WHERE condition)
WHERE condition;
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

Se dorește modificarea departamentului și a postului pentru angajatul cu matricola 12358


astfel încât acestea să coincidă cu cele ale angajatului cu matricola 2466.

SQL> UPDATE ang


SET (post, nr.dept) = (SELECT post, nr.dept
FROM ang
WHERE matricola = 2466)
WHERE matricola = 12358;
1 row updated.

Rezultat:
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 agent vânzări 12358 4
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

9
Actualizarea înregistrărilor folosind valori dintr-un alt tabel

Având tabelul cu date personale


pers
nume matricol nr.depr post copii pasiuni
Ionescu 1489 1 inginer 1 citit
Popescu 7852 1 inginer 2 scris
Vasilescu 2598 2 economist 1 ascultat
Andronache 12358 3 economist 1 vorbit
Georgescu 2466 4 agent vânzări 3 mancare
Tache 1587 2 economist 0 bautura
Iancu 675 inginer 5

și tabelul

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

lansând comanda :

SQL> UPDATE pers


SET nr.dept = (SELECT nr.dept
FROM ang
WHERE matricol = 12358)
WHERE post = (SELECT post
FROM ang
WHERE maticol = 1587);
2 row updated.

Este schimbat în tabelul pers numărul de departament pentru toți angajații care
ocupă același post ca al celui cu numarul 1587 din tabelul ang, noul lor număr de
departament devenind egal cu al angajatului cu numărul matricol 12358 (3).

pers
nume matricol nr.depr post copii pasiuni
Ionescu 1489 1 inginer 1 citit
Popescu 7852 1 inginer 2 scris
Vasilescu 2598 3 economist 1 ascultat
Andronache 12358 3 economist 1 vorbit
Georgescu 2466 4 agent vânzări 3 mancare
Tache 1587 3 economist 0 bautura
Iancu 675 inginer 5

10
Ștergerea unei înregistrări dintr-un tabel

Ilustrearea ștergerii departamentului dezvoltare din tabelul dept.

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța

șterge o dept
înregistrare din nr.dept numedept localitate
tabelul dept
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași

Ștergerea înregistrarilor dintr-un tabel se poate face folosind comanda


DELETE.
Sintaxa:

DELETE [FROM] tabel


[WHERE condiție];

În sintaxa:
tabel este numele tabelului,
condiție identifică înregistrările care trebuie șterse și poate fi
compusă din expresii, nume de coloane, constante,
subinterogări sau operatori de comparare.

Pentru exemplul ilustrat, comanda este :

SQL> DELETE FROM dept


WHERE numedept = 'dezvoltare';

Mesj de confirmare:

1 row deleted

11
Ștergerea unor înregistrări utilizând funcții SQL și operatori de comparare.

Cu comanda

SQL> DELETE FROM ang


WHERE data_angajare > TO_DATE ('1 ian 2011', 'DD Mon YYYY');

4 rows deleted.

din tabelul
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

se vor șterge toți angajații încadrați după data de 1 ian 2011:

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Ionescu 25 aug 1999 4520 54240 inginer 675 3

Dacă se omite clauza WHERE, vor fi șterse din tabel toate rândurile.

Rezultatul comenzii

SQL> DELETE FROM ang;

7 rows deleted.

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept

12
Ștergerea înregistrărilor folosind valori dintr-un alt tabel

Având tabelele
pers
nume matricol nr.depr post copii pasiuni
Ionescu 1489 1 inginer 1 citit
Popescu 7852 1 inginer 2 scris
Vasilescu 2598 2 economist 1 ascultat
Andronache 12358 3 economist 1 vorbit
Georgescu 2466 4 agent vânzări 3 mancare
Tache 1587 2 economist 0 bautura
Iancu 675 inginer 5

dept
nr.dept numedept localitate
1 cercetare București
2 operații Timișoara
3 conturi Cluj
4 vânzări Iași
5 dezvolare Constanța

comanda

SQL> DELETE FROM pers


WHERE nr.dept =
(SELECT nr.dept
FROM dept
WHERE numedept = 'conturi');
1 row deleted.

șterge toți angajații care sunt în departamentul 3. Subinterogarea caută în tabelul


dept numărul de departament pentru conturi, apoi furnizează numărul de departament
interogării principale, care șterge înregistrările din pers.

pers
nume matricol nr.depr post copii pasiuni
Ionescu 1489 1 inginer 1 citit
Popescu 7852 1 inginer 2 scris
Vasilescu 2598 2 economist 1 ascultat
Georgescu 2466 4 agent vânzări 3 mancare
Tache 1587 2 economist 0 bautura
Iancu 675 inginer 5

13
Tranzacții

Tranzacțiile constau din comenzi DML (Limbaj de Manipulare a Datelor) care se


constituie într-o schimbare consistentă asupra datelor.

Când începe si când se termina o tranzactie?

O tranzacție începe când este întâlnită prima comandă SQL executabilă și se


termină la apariția unuia dintre evenimentele:
• O comandă COMMIT sau ROLLBACK
COMMIT – permite transformarea unei tranzacții într-o tranzacție
permanent (salvează modificările)
SAVEPOINT – permite definirea unui punct de revenire
ROLLBACK– permite revenirea la un punct de revenire definit anterior
(renunțarea la modificările efectuate în cadrul unei tranzacții)
• O comandă DDL (Limbaj de Definire a Datelor) - CREATE, ALTER, DROP,
RENAME, TRUNCATE.
CREATE – permite crearea unui tabel.
ALTER – permite modificarea structurii unui tabel prin
adăugarea (ADD),
modificarea (MODIFY) sau
ştergerea (DROP) unei coloane.
DROP – permite ştergerea unei strucuturi a bazei de date
RENAME– permite redenumirea unui tabel.
TRUNCATE – permite ştergerea întregului conținut al unui tabel
• O comandă DCL (Limbaj de Control al Datelor ) - GRANT şi REVOKE
GRANT – permite acordarea unor drepturi unui anumit utilizator.
Exemplu: se acordă dreptul de a crea un tabel utilizatorului ‘Ion’.
GRANT CREATE TABLE TO Ion
REVOKE– permite revocarea unor drepturi unui anumit utilizator.
Exemplu: Se revocă dreptul de a crea a un tabel utilizatorului ‘Ion’.
REVOKE CREATE TABLE FROM Ion
• Deconectarea utilizatorului
• 'Pică' sistemul.

14
Utilizarea COMMIT și ROLLBACK

INSERT UPDATE INSERT DELETE

COMMIT
Savepoint Savepoint
A B

ROLLBACK to Savepoint B

ROLLBACK to Savepoint A

ROLLBACK

COMMIT - Încheie o tranzacție făcând ca toate modificările să devină permanente


(salveaza modificarile)
SAVEPOINT nume - Marchează un punct de întoarcere (savepoint) în cadrul tranzacției
curente
ROLLBACK [TO SAVEPOINT name] –
ROLLBACK încheie tranzacția curentă pierzându-se toate modificările
temporare.
ROLLBACK TO SAVEPOINT name șterge savepoint-ul și toate schimbările de
după el (temporare).

Starea datelor înainte de COMMIT sau ROLLBACK

• Starea anterioară a datelor poate fi refăcută.


• Utilizatorul curent poate revedea rezultatul operațiilor DML folosind comanda
SELECT.
• Alți utilizatori nu pot vedea rezultatul comenzilor DML date de utilizatorul curent.
• Înregistrarile modificate sunt protejate (locked); alți utilizatori nu pot modifica datele
din aceste înregistrari.

Starea datelor după COMMIT

• Modificările asupra datelor din baza de date devin permanente.


• Starea anterioară a datelor nu mai poate fi refacută.
• Toți utilizatorii pot vedea rezultatele.

15
• Înregistrările protejate (locked) sunt deblocate pentru modificare și pot fi schimbate
de alți utilizatori.
• Toate savepoint-urile sunt șterse.

Salvarea modificarilor utilizând comanda COMMIT

Comanda prin care se actualizează numărul departamentului pentru angajatul cu numărul


matricol 1587 din tabelul ang

SQL>UPDATE ang
SET nr.dept = 1
WHERE matricol = 1587;

1 row updated.

are efect ireversibil (modificarea devine definitivă) după:

SQL>COMMIT;

Commit complete.

Ștergerea modificărilor (refacerea stării inițiale):

Se pot anula modificările temporare folosind comanda ROLLBACK.


După lansarea comenzii ROLLBACK:
• Modificările făcute sunt pierdute.
• Este refăcută starea anterioară a datelor.
• Este eliminată protecția asupra înregistrărilor implicate.

Exemplu:
Încercând să se ștergă o înregistrare din tabelul ang, se poate șterge accidental întreg
tabelul. Se poate corecta greșeala, iar apoi se pot da comenzile corecte și salva
modificările.

SQL> DELETE FROM ang;


7 rows deleted.
SQL> ROLLBACK;
Rollback complete.
SQL> DELETE FROM ang
WHERE matricol = 1587;
1 row deleted.
SQL> SELECT *
FROM ang
WHERE matricol = 1587;
No rows selected.
SQL> COMMIT;
Commit complete.

16
Anularea modificărilor pînă la un punct marcat (Marker) - Savepoint
Se poate crea un marcaj în cadrul unei tranzacții curente folosind comanda SAVEPOINT.
Astfel, tranzacția poate fi împărțită în secțiuni mai mici. Se creează posibilitatea de a
anula modificările temporare pâna la acel marcaj folosind comanda ROLLBACK TO
SAVEPOINT.
Dacă este creeat un al doilea savepoint cu același nume ca unul anterior, savepoint-ul
anterior este șters.

SQL> UPDATE . . .
SQL> SAVEPOINT marker_1;
Savepoint created.
SQL> INSERT. . .
SQL> ROLLBACK TO marker_1;
Rollback complete.

17
INCLUDEREA CONSTRÂNGERILOR
Constrângerile previn introducerea de date invalide în tabel.
Utilizarea constrângerilor are ca efect:
- forțează regulile la nivel de tabel atunci când este inserat, actualizat sau șters un rând
din tabel; operația este încheiată cu succes dacă este respectată constrângerea
- previne ștergerea unui tabel dacă există dependențe din alte tabele.

Constrângerile de integritate a datelor


Constrângere Descriere
NOT NULL Specifică faptul că această coloană nu poate conține o
valoare nulă.
UNIQUE Key Specifică o coloană sau o combinație de coloane a căror
valoare trebuie să fie unică pentru toate înregistrările
tabelului.
PRIMARY KEY Identifică unic fiecare înregistrare
FOREIGN KEY Stabilește și forțează o relație de tip cheie externă dintre
coloana respectivă si o coloană din tabelul referit.
CHECK Specifică o condiție care trebuie să fie adevărată.

Se poate crea o constrângere:


- în timpul creării tabelului
- după ce tabelul a fost creat
Constrângerile pot fi definite la nivel de coloană sau de tabel.
Toate constrângerile pot fi vizualizate în dicționarul de date (în care sunt înscrise)
USER_CONSTRAINTS.

Definirea constrângerilor

Sintaxa

CREATE TABLE [schema] tabel


( coloană tip_date [DEFAULT expresie]
[constrângere_coloană],
………
[constrângere_tabel]);

De exemplu, pentru tabelul angajați,

CREATE TABLE ang


( matricol NUMBER(5),
a_nume VARCHAR2(20),
………
nr.dept NUMBER(2) NOT NULL,
CONSTRAINT ang_matricol_pk
PRIMARY KEY(matricol));

1
Toate constrângerile sunt cuprinse într-un dicționar. Este ușor să se facă referință la constrângeri
dacă li se dau nume sugestive. Numele unei constrângeri trebuie să urmeze un anumit standard.
Dacă nu se denumește constrângerea, serverul Oracle generează un nume de forma SYS_Cn,
unde n este un număr întreg astfel încât numele constrâgerii este unic.
Constrângerile definite pentru un anumit tabel pot fi vizualizate ân USER_CONSTRAINTS
(dicționarul tabelului).
De obicei, constrângerile sunt create în același timp cu tabelul, dar pot fi și adăugate tabelului
după crearea lui.
Constrângerile pot fi definite pe două nivele:
• Coloană - Face referire la o singură coloană; poate defini orice tip de constrângere de
integritate
• Tabel - Face referire la una sau mai multe coloane; poate defini orice constrângere,
exceptând pe cea de tip NOT NUL.

Sintaxa
1. Constrângere la nivel de coloană

coloană [CONSTRAINT nume_constrângere] tip_constrângere

2. Constrângere la nivel de tabel

coloană,..
[CONSTRAINT nume_constrângere] tip_constrângere
(coloană,...),

Constrângerea NOT NULL

Constrângerea NOT NULL ne asigură că valorile null nu sunt permise în coloana respectivă.
Coloanele fără constrângerea NOT NULL pot conține, implicit, valori null.

ang
A_NUME DATA_ANGAJARE SALARIU BONIFICAȚIE POST MATRICOL NR.DEPT
IONESCU 11 IAN 2000 5500 INGINER 1489 1
POPESCU 18 NOV 2011 1550 INGINER 7852 1
VASILESCU 23 AUG 2011 1800 ECONOMIST 2598 2
ANDRONACHE 1 MAI 2017 2250 ECONOMIST 12358 3
GEORGESCU 2 SEPT 2000 3500 AGENT 2466 4
VÂNZĂRI
TACHE 22 IUL 2015 1450 ECONOMIST 1587 2
IONESCU 25 AUG 1999 4520 INGINER 675 3

Constrângere NOT NULL Absența constrângerii NOT Constrângere


(nicio înregistrare nu NULL (orice înregistrare NOT NULL
poate conține o valoare poate conține null pentru
NULL pe această coloană) această coloană)

2
Constrângerea NOT NULL definită la nivel de coloană

SQL> CREATE TABLE ang


(
a_nume VARCHAR2(10) NOT NULL
data_angajare DATE
salariu NUMBER(7)
bonificație NUMBER(7)
post VARCHAR2(9)
matricol NUMBER(4)
nr.dept NUMBER(2) NOT NULL
);

Constrângerea NOT NULL poate fi specificată numai la nivel de coloană.


În exemplul de mai sus, se aplica constrângerea NOT NULL coloanelor a_nume si nr.dept
pentru tabelul ang.
Deoarece aceste constrângeri nu au nume, Oracle Server va crea nume pentru ele.
Numele constrângerii poate fi specificat în timpul specificării constrângerilor:

… nr.dept NUMBER(7,2)
CONSTRAINT ang_nr.dept_nn NOT NULL …

Constrângerea UNIQUE Key (cheie unică)

constrângere UNIQUE key

dept

nr.dept numedept localitate


1 cercetare București
2 operațiuni Timișoara
3 conturi Cluj
4 vânzări Iași

inserare

5 conturi Constanța nu este permisă, există numedept conturi


6 Craiova permisă

O constrângere de integritate cheie unică cere ca fiecare valoare din coloana sau set de
coloane să fie unică – două înregistrări ale tabelului nu pot avea valori duplicat în coloana sau
setul de coloane care formează constrângerea. Coloana (setul de coloane) inclusă în definiția
cheii unice se numește cheie unică. Dacă cheia unică conține mai multe coloane se numește
cheie unică compusă.
Constrângerea cheie unică permite introducerea de valori null dacă nu a fost definită o
constrângere NOT NULL pentru acea coloană.

3
Orice număr de înregistrări pot include valori null în coloane fără constrângerea NOT
NULL.
O valoare null într-o coloană (sau în toate coloanele unei chei unice compuse)
întotdeauna satisface o constrângere de cheie unică.

Constrângerea cheie unică (unique key) definită la nivel de tabel sau coloană

SQL> CREATE TABLE dept


(
nr.dept NUMBER(2)
numedept VARCHAR2(14)
localitate VARCHAR2(13)
CONSTRAINT dept_numedept_uk UNIQUE(numedept)
);

Constrângerile de cheie unică pot fi definite la nivel de coloană sau tabel.


O cheie unică compusă este creată utilizând definiția la nivel de tabel.
În exemplu, se aplică constrângerea de cheie unică coloanei numedept din tabela dept.
Numele constrângerii este dept_numedept_uk.

Constrângerea PRIMARY KEY

constrângere PRIMARY KEY

nr.dept numedept localitate


1 cercetare București
2 operațiuni Timișoara
3 conturi Cluj
4 vânzări Iași

inserare

3 marketing Constanța nu este permisă, există nr.dept 3


relații publice Craiova nu este permisă, deoarece nr.dept e NULL

Constrângerea de cheie primara crează o cheie primară pentru fiecare tabel.


Pentru fiecare tabel poate fi creată numai o cheie primară.
Constrângerea de cheie primară este o coloană sau set de coloane care identifică unic
fiecare înregistrare din tabel. Această constrângere forțează unicitatea coloanei sau a setului de
coloane și asigură că nicio coloană care este parte a cheii primare nu poate conține o valoare
null.

4
Constrângerea cheii primare definită la nivel de coloană sau tabel

SQL> CREATE TABLE dept


(
nr.dept NUMBER(2)
numedept VARCHAR2(14)
localitate VARCHAR2(13)
CONSTRAINT dept_numedept_uk UNIQUE(numedept)
CONSTRAINT dept_nr.dept_pk PRIMARY KEY(nr.dept)
);
Constrângerea cheie primară (PRIMARY KEY) poate fi definită la nivel de tabel sau
coloană. O cheie primară compusă este creată utilizând definiția la nivel de tabel.
Exemplul definește o cheie primară după coloana nr.dept a tabelei dept. Numele
constrângerii este dept_nr.dept_pk.

Constrângerea FOREIGN KEY

PRIMARY KEY dept


nr.dept numedept localitate
1 cercetare București
2 operațiuni Timișoara
3 conturi Cluj
4 vânzări Iași
FOREIGN KEY

ang
A_NUME DATA_ANGAJARE SALARIU BONIFICAȚIE POST MATRICOL NR.DEPT
IONESCU 11 IAN 2000 5500 INGINER 1489 1
POPESCU 18 NOV 2011 1550 INGINER 7852 1
VASILESCU 23 AUG 2011 1800 ECONOMIST 2598 2
ANDRONACHE 1 MAI 2017 2250 ECONOMIST 12358 3
GEORGESCU 2 SEPT 2000 3500 AGENT 2466 4
VÂNZĂRI
TACHE 22 IUL 2015 1450 ECONOMIST 1587 2
IONESCU 25 AUG 1999 4520 INGINER 675 3

inserare
nu este permisă, nu există nr.dept 7 în tabelul dept
A_NUME DATA_ANGAJARE SALARIU BONIFICAȚIE POST MATRICOL NR.DEPT
Claudiu 15.oct.2017 1950 ECONOMIST 5555 7
Vasile 15.oct.2017 1950 ECONOMIST 5556

permisă

5
Cheia externă, sau constrângerea de integritate referențială, desemnează o coloană sau o
combinație de coloane în funcția de cheie externă și stabilește o relație cu o cheie primară sau o
cheie unică în același tabel sau un tabel diferit.
În exemplu, nr.dept a fost definit cheie externă în tabelul ang (dependent sau tabel copil); ea
referă coloana nr.dept din tabelul dept (referit sau tabel părinte).
Valoarea unei chei externe trebuie să se potrivească cu o valoare existentă în tabelul părinte
sau să fie NULL.

Constrângerea cheii externe definită la nivel de coloană sau tabel

SQL>CREATE TABLE ang


(
a_nume VARCHAR2(10) NOT NULL
data_angajare DATE
salariu NUMBER(7)
bonificație NUMBER(7)
post VARCHAR2(9)
matricol NUMBER(4)
nr.dept NUMBER(2) NOT NULL CONSTRAINT ang_nr.dept_fk
CONSTRAINT ang_nr.dept_fk FOREIGN KEY (nr.dept)
REFERENCES dept (nr.dept)
);

Constrângerile cheii externe pot fi definite la nivelul constrângerilor de tabel sau de coloană.
O cheie externă compusă este creată folosind definițiile la nivel tabel.
Exemplul de mai sus definește o constrângere de tip cheie externă în coloana nr.dept din
tabela ang. Numele constrângerii este ang_nr.dept_fk.

Definirea cheii externe la nivel de coloană:

SQL>CREATE TABLE ang


(
a_nume VARCHAR2(10) NOT NULL
data_angajare DATE
salariu NUMBER(7) constrângere
bonificație NUMBER(7) pentru coloană
post VARCHAR2(9)
matricol NUMBER(4)
nr.dept NUMBER(2) NOT NULL CONSTRAINT ang_nr.dept_fk
REFERENCES dept (nr.dept)
); constrângere
pentru tabel

Cuvinte cheie ale constrângerii FOREIGN KEY


• FOREIGN KEY – definește coloana în tabelul copil la nivelul constrângerii de
tabel.
• REFERENCES - identifică tabelul și coloana în tabelul printre.
• ON DELETE CASCADE indică faptul că, atunci când rândul din tabelul părinte
va fi șters, rândul dependent din tabelul copil va fi de asemenea șters.

6
• ON DELETE SET NULL convertește valorile foreign key în valori nule atunci
când valoarea părinte este ștearsă.

Constrângerile externe sunt definite în tabelul copil și tabelul care conține coloana la care se
face referință devine părinte.
Fără opțiunea ON DELETE CASCADE, rândul din tabelul părinte nu va putea fi șters dacă
este referit în tabelul copil.

Constrângerea CHECK - Constrângerea de verificare

• Definește o condiție pe care fiecare rând trebuie să o îndeplinească.

Sintaxa:

…., nr.dept NUMBER(2),


CONSTRAINT ang_nr.dept_ck
CHECK (nr.dept BETWEEN 1 AND 99)….

Constrângerile de verificare pot fi definite la nivel de coloana sau la nivel de tabel.

Pentru tabelul pers se poate impune o constrângere de tip check la nivelul vârstei (pentru a fi
angajat, trebuie să fii major).
pers
nume matricol nr.depr vârsta copii pasiuni
Ionescu 1489 1 25 1 citit
Popescu 7852 1 39 2 scris
Vasilescu 2598 2 45 1 ascultat
Andronache 12358 3 34 1 vorbit
Georgescu 2466 4 62 3 mancare
Tache 1587 2 40 0 bautura
Iancu 675 5

De aceea, la crearea tabelului, se poate impune această condiție:

CREATE TABLE pers


(
nume VARCHAR2(10)
matricol NUMBER(5)
nr.dept NUMBER(2)
vârsta NUMBER(2) CHECK (vârsta >= 18)
copii NUMBER(2)
pasiuni VARCHAR2(10)
);

Cu această restricție, următoarea inserare

INSERT INTO pers


Values (’Codreanu’, 12400, 2 , 27 , 1);

se va termina cu succes:
1 row(s) affected

7
iar inserarea

INSERT INTO pers


Values (’Codrescu’, 12401, 2 , 17 , 0);

se va termina cu eșec:

Msg 547, Level 16, State 0, Line 13


The INSERT statement conflicted with the CHECK constraint ....
The statement has been terminated.

Acțiuni privind constrângeri în tabele existente

Acțiuni posibile după crearea unui tabel:


• Se poate adăuga, scoate, activa, dezactiva o constrângere, dar nu se poate modifica
structura acesteia.
• Se poate adăuga o constrângere de tip NOT NULL la o coloană existentă folosind clauza
MODIFY din funcția ALTER TABLE.

Adăugarea unei constrângeri

Se poate adăuga o constrângere la tabelele existente, folosind declarația ALTER TABLE


împreună cu clauza ADD.
Sintaxa:

ALTER TABLE tabel


ADD [ CONSTRAINT constrângere] tip_constrângere (coloană);

Observație:
Denumirea constrângerii este opțională, dar recomandată. Dacă nu se dă nume
constrângerilor, sistemul va genera nume implicit SYS_Cn .

Exemplu: Se doreşte ca pe coloana nume a tabelului pers să nu existe valori nule sau identice
şi lungimea minimă să fie de 6 caractere:

ALTER TABLE pers


ADD CONSTRAINT nume_nenul_ck CHECK(nume IS NOT NULL);
ALTER TABLE pers
ADD CONSTRAINT nume_unic_uk UNIQUE(nume);
ALTER TABLE pers
ADD CONSTRAINT nume_6_ck CHECK(LENGTH(nume)>5);

Ștergerea unei constrângeri


Pentru a șterge o constrângere, se va utiliza declarația ALTER TABLE cu clauza DROP.
Opțiunea CASCADE a clauzei DROP face să fie ștearsă și constrângerea dependentă.

Sintaxa generală:
ALTER TABLE tabel
DROP PRIMARY KEY| UNIQUE (coloană)|CONSTRAINT nume_constrângere
[CASCADE];

8
Defalcat:
ALTER TABLE tabel
DROP PRIMARY KEY [CASCADE];

ALTER TABLE tabel


DROP UNIQUE(listă_coloane) [CASCADE];

ALTER TABLE tabel


DROP CONSTRAINT nume [CASCADE

Efectul acestor cereri este:


• DROP PRIMARY KEY şi DROP UNIQUE specifică ştergerea constrângerii de tip
cheie primară/cheie unică pentru tabelul respectiv. Constrângerea poate să nu aibă un
nume asociat la definire.
• DROP CONSTRAINT specifică ştergerea unei constrângeri având asociat un nume.
• Opţiunea CASCADE se aplică în cazul în care există constrângeri dependente şi
specifică ştergerea suplimentară a acestora.

Exemplu:
Eliminarea constrângerii de tip cheie primară din tabelul dept precum și eliminarea
constrângerii externe asociate la coloana ang-nr.dept.

SQL>ALTER TABLE dept


DROP PRIMARY KEY CASCADE;

Table altered.

Pentru a scoate a constrângere, trebuie identificat numele constrângerii folosind


USER_CONSTRAINS si USER_CONS_COLUMNS. Apoi se folosește funcția ALTER TABLE
împreuna cu clauza DROP. Opțiunea CASCADE din clauza DROP are ca efect si scoaterea
tuturor constrângerilor dependente.

ALTER TABLE ang


DROP CONSTRAINT ang_nr.dept_fk;

Dezactivarea constrângerilor
Dezactivarea constrângerii se efectuează cu declaraţia ALTER TABLE însoţită de clauza
DISABLE.
Sintaxa:

ALTER TABLE tabel


DISABLE CONSTRAINT constrângere [CASCADE];

• Clauza DISABLE din funcția ALTER TABLE dezactivează o constrângere de integritate.


• Opțiunea CASCADE dezactivează constrângeri de integritate dependente.

Exemplu:

ALTER TABLE dept


DISABLE CONSTRAINT nr.dept_pk CASCADE

9
Table altered.

Clauza DISABLE se poate folosi atât în funcția CREATE TABLE cât și în funcția ALTER
TABLE.
Clauza CASCADE dezactivează constrângerile de integritate dependente.

Activarea constrângerilor

Activarea unei constrângeri de integritate care este dezactivată se face utilizând ALTER
TABLE cu clauza ENABLE..

Sintaxa:
ALTER TABLE tabel
ENABLE CONSTRAINT nume_constrângere [CASCADE];

Exemplu (reactivare constrângere de cheie primară):

ALTER TABLE dept


ENABLE CONSTRAINT nr.dept_pk CASCADE

Table altered.

• Dacă se activează o constrângere, constrângerea este aplicată tuturor datelor din tabel.
Toate datele din tabel trebuie să îndeplinească condițiile din constrângere.
• Dacă se activează o constrângere de tip unic sau cheie primară, atunci este creat în mod
automat un index de tip unic.
• Clauza ENABLE se poate folosi atât în funcția CREATE TABLE cât și în funcția ALTER
TABLE.

Vizualizarea constrângerilor

După crearea unui tabel, se poate confirma existența sa prin folosirea comenzii DESCRIBE.
Singura constrângere care poate fi verificată în această situație este constrângerea NOT NULL.
Pentru a vedea toate constrângerile din tabel, este necesară interogarea tabelului
USER_CONSTRAINTS.
Interogarea tabelului USER_CONSTRAINTS pentru a putea vedea toate numele și definițiile
constrângerilor se face în modul următor:

SQL> SELECT constraint_name, constraint_type, search_condition


FROM user_constraints
WHERE table_name=’ang’;
Rezultat posibil:

CONSTRAINT_NAME C SEARCH_CONDITION
SYS_C00674 C A_NUME IS NOT NULL
SYS_C00675 C NR.DEPT IS NOT NULL
ANG_MATRICOL_PK P

10
Constrângerilor care nu primesc un nume de la posesorul tabelei, li se atribuie un nume
automat de către sistem. La tipul constrângerii, C provine de la CHECK, P de la PRIMARY
KEY, R de la integritate referențială și U de la UNIQUE. De observat faptul că constrângerea
NOT NULL este o constrângere de tip CHECK.

Vizualizarea coloanelor asociate constrângerilor

Vizualizarea coloanelor asociate cu numele constrângerilor se face în tabelul


USER_CONS_COLUMNS.

Interogarea acestui tabel:

SQL> SELECT constraint_name, column_name,


FROM user_cons_columns
WHERE table_name=’ang’;

CONSTRAINT_NAME COLUMN_NAME
ANG_NR.DEPT_FK NR.DEPT
ANG_MATRICOL_PK MATRICOL
SYS_C00675 NR.DEPT

Se poate vizualiza numele coloanelor implicate în constrângeri interogând dicționarul


USER_CONS_COLUMNS. Aceasta vizualizare este utilă mai ales în cazul constrângerilor
asociate de către sistem.

11
Restricționarea și sortarea datelor

(Cum putem limita numărul de linii returnat de o interogare și cum putem sorta aceste linii)

La citirea datelor dintr-o bază de date, ar pute fi util să fie redus numărul de linii afișate sau să fie
specificată o anumită ordine în afișarea acestora.

Ilustrativ, o limitare a afișării numărului de linii folosind o selectare este:

a_nume data_angajare ... nr.dept


Ionescu 11 ian 2000 1
Popescu 18 nov 2011 1
Vasilescu 23 aug 2011 2
Andronache 1 mai 2017 3
Georgescu 2 sept 2000 4
Tache 22 iul 2015 2

„selectează toți
angajații din
departamentul 2”

a_nume data_angajare ... nr.dept


Vasilescu 23 aug 2011 2
Tache 22 iul 2015 2

În exemplul de mai sus s-a dorit afișarea tuturor angajaților din departamentul 2. Ca urmare, singurele
returnate sunt setul de linii care au valoarea 2 în coloana nr.dept. Această restricționare reprezintă baza
clauzei WHERE în limbajul SQL.

Sintaxa instrucțiunii SELECT folosind clauza/clauze WHERE este:

SELECT [DISTINCT] {*, coloană [alias], …}


FROM tabel
[WHERE condiție];

Clauza WHERE, dacă există, urmează întotdeauna după clauza FROM.


O clauză WHERE conține o condiție ce trebuie îndeplinită.

În sintaxă:
WHERE restricționează interogarea la liniile ce îndeplinesc condiția.
condiție e compusă din nume de coloane, expresii, constante și operatori de
comparație.
Clauza WHERE poate compara valorile din coloane, valori literale, expresii aritmetice sau funcții.
Clauza WHERE e compusa din trei elemente:
Numele coloanei
Operatorul de comparație
Nume de coloană, constantă sau listă de valori

Exemplu de utilizare a clauzei WHERE:

Tabelul ang

a_nume data_angajare post nr.dept


Ionescu 11 ian 2000 inginer 1
Popescu 18 nov 2011 inginer 1
Vasilescu 23 aug 2011 economist 2
Andronache 1 mai 2017 economist 3
Georgescu 2 sept 2000 agent vânzări 4
Tache 22 iul 2015 economist 2

SQL> SELECT a_nume, post, nr.dept


FROM ang
WHERE post ‘economist’;

Rezultatul execuției comenzii de selecție:

A_NUME POST NR.DEPT


VASILESCU ECONOMIST 2
ANDRONACHE ECONOMIST 3
TACHE ECONOMIST 2

Folosirea clauzei WHERE:


În exemplul prezentat, cu ajutorul instrucțiunii SELECT se returnează numele, postul ocupat și
numărul departamentului tuturor angajaților care ocupă un post de economist.
Condiția economist a fost specificată cu litere mici pentru a se asigura potrivirea cu valoarea trecută în
coloana post a tabelei ang. Șirurile de caractere sunt case-sensitive.

Modul de precizare a condiției clauzei WHERE

Șirurile de caractere și datele sunt incluse între apostrofuri


Valorile de tip caracter sunt case-sensitiv, iar valorile de tip dată sunt format-sensitive
Formatul implicit de dată calendaristică este ‘DD-MON-YY’

Ca urmare, dacă se dorește afișarea informațiilor privind persoana/persoanele cu numele Tache,


comanda SELECT va fi de forma:

2
SQL> SELECT a_nume, post, nr.dept
FROM ang
WHERE a_nume = ‘Tache’;

Deși șirurile de caractere și datele prezente în clauza WHERE trebuie incluse între apostrofuri (‘ ‘),
constantele numerice nu trebuie incluse.
Toate căutările de tip caracter sunt case-sensitiv.

În cazul instrucțiunii următoare nu este returnată nicio linie deoarece nu există potrivire între forma în
care este scrisă condiția și modul în care aceasta este înscrisă în tabela ang.

ang

a_nume data_angajare post nr.dept


Ionescu 11 ian 2000 inginer 1
Popescu 18 nov 2011 inginer 1
Vasilescu 23 aug 2011 economist 2
Andronache 1 mai 2017 economist 3
Georgescu 2 sept 2000 agent vânzări 4
Tache 22 iul 2015 economist 2

SQL> SELECT a_nume, post, nr.dept


FROM ang
WHERE post ‘Economist’;

În clauza WHERE pot fi utilizați următorii operatori de comparație:

Operator Comentariu
= Egal cu
> Mai mare decât
>= Mai mare sau egal
< Mai mic decât
<= Mai mic sau egal
<> Diferit de

Operatorii de comparație sunt folosiți în condițiile care compară două expresii.


Formatul în care apar în clauza WHERE este:

Sintaxa: WHERE expresie operator valoare

Exemple:
WHERE data_angajare=’ 1 mai 2017’
WHERE salariu >= 1500
WHERE a_nume=’Ionescu’

3
Exemplu de utilizare a clauzei WHERE cu operator

Fie tabelul cu angajați

ang

a_nume data_angajare salariu bonificație


Ionescu 11 ian 2000 5500 3000
Popescu 18 nov 2011 1550 1500
Vasilescu 23 aug 2011 1800 1500
Andronache 1 mai 2017 2250 1800
Georgescu 2 sept 2000 3500 2000
Tache 22 iul 2015 1450 1500

Se lansează comanda:

SQL> SELECT a_nume, salariu, bonificație


FROM ang
WHERE salariu<=bonificație;

Rezultatul afișat:

A_NUME SALARIU BONIFICAȚIE


TACHE 1450 1500

În exemplul de mai sus, instrucțiunea SELECT returnează numele, salariul și bonificația din tabela ang,
unde salariul angajatului este mai mic sau egal decât valoarea comisionului. De observat că nu este o
valoare explicită în clauza WHERE. Cele două valori comparate sunt luate din coloanele salariu,
respectiv bonificație din tabela ang.

Alți operatori care pot fi utilizați în clauza WHERE, în afara celor de comparație:

Operator Semnificatie
BETWEEN Între două valori (inclusiv)
…AND…
IN(listă) Orice valoare din listă
LIKE Corespunde unui tip de caracter
IS NULL Este o valoare nula

4
Folosirea operatorului BETWEEN

Operatorul BETWEEN se folosește când se dorește afișarea valorilor dintr-un interval.

Având tabelul ang:

A-NUME DATA_ANGAJARE SALARIU


IONESCU 11 IAN 2000 5500
POPESCU 18 nov 2011 1550
VASILESCU 23 aug 2011 1800
ANDRONACHE 1 mai 2017 2250
GEORGESCU 2 sept 2000 3500
TACHE 22 iul 2015 1450

Lansând comanda:

SQL> SELECT a_nume, salariu


FROM ang
WHERE salariu BETWEEN 1500 AND 3000;

Vom avea drept rezultat:

A_NUME SALARIU
POPESCU 1550
VASILESCU 1800
ANDRONACHE 2250
TACHE 1450

Prin folosirea operatorului BETWEEN s-au afișat liniile pentru care valoarea existentă se găsește
într-un interval specificat printr-o limită inferioară și una superioară.

Ca urmare, instrucțiunea SELECT cu clauza WHERE și operatorul BETWEEN va afișa liniile din
tabela ang pentru toți angajații ale căror salarii sunt cuprinse între 1500 și 3000.

5
Folosirea operatorului IN

Operatorul IN se folosește pentru a testa valorile dintr-o listă.

Având tabela ang:


a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

Lansând comanda:

SQL> SELECT a_nume, salariu, nr.dept


FROM ang
WHERE nr.dept IN (1, 2, 3);

A_NUME SALARIU NR.DEPT


IONESCU 5500 1
POPESCU 1550 1
VASILESCU 1800 2
ANDRONACHE 2250 3
TACHE 1450 2

Operatorul IN este utilizat pentru a căuta valori într-o listă.


Exemplul de mai sus afișează numele, salariul angajatului și numărul departamentului în care lucrează
pentru toți angajații din departamentele 1, 2 și 3.
Operatorul IN poate fi folosit cu orice tip de dată.
Următorul exemplu returnează o linie din tabela ang pentru fiecare angajat al cărui nume este inclus în
lista de nume din clauza WHERE.

SQL> SELECT a_nume, salariu, nr.dept


FROM ang
WHERE a_nume IN (‘Ionescu’, ‘Vasilescu’);

A_NUME SALARIU NR.DEPT


IONESCU 5500 1
VASILESCU 1800 2

Dacă în listă sunt folosite caractere sau date, acestea trebuie incluse între apostrofuri (‘ ‘).

6
Folosirea operatorului LIKE

Operatorul LIKE se folosește pentru a efectua căutări cu caractere wildcard în șiruri valide de
căutare.
Condițiile căutării pot conține fie caractere literale, fie numere
% Reprezintă orice secvență de două sau mai multe caractere
_ Reprezintă un singur caracter

Nu întotdeauna se știe valoarea exactă care va fi căutată. De exemplu, nu se cunoaște numele exact al
angajatului, dar se știe că începe cu litera A. Se pot selecta linii care se potrivesc după un tip de
caractere folosind operatorul LIKE. Operația de potrivire după un tip de caractere este referită ca o
căutare cu caractere wildcard.

Având tabela
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

lansând comanda:

SQL> SELECT a_nume


FROM ang
WHERE a_nume LIKE ‘A%’;

se va afișa:

A_NUME
ANDRONACHE

Instrucțiunea SELECT va returna numele tuturor angajaților din tabela ang al căror nume începe cu
“A”. Numele care încep cu “a” nu vor fi returnate.

Operatorul LIKE poate fi folosit ca scurtătură pentru câteva comparații făcute cu BETWEEN.

7
Următorul exemplu afișează numele și data angajării, angajaților având data angajării cuprinsă între 1
ianuarie 2011 si 31 decembrie 2011.

Având tabela
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

SQL> SELECT a_nume, data_angajare


FROM ang
WHERE data_angajare LIKE ‘%11’;

Rezultat:

A_NUME DATA_ANGAJARE
POPESCU 18 NOV 2011
VASILESCU 23 AUG 2011

Pot fi combinate diferite tipuri de potriviri pe caracter

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

cu comanda

SQL> SELECT a_nume


FROM ang
WHERE a_nume LIKE ‘_o%’:

se vor afișa numele angajaților al căror nume conține pe a doua poziție litera o

A_NUME
IONESCU
POPESCU

8
Simbolurile % si _ pot fi folosite în orice combinație cu caractere literale.
Pentru a căuta caracterele “%” și “_” în interiorul unui șir de caractere, se poate folosi identificatorul
ESCAPE. Utilizarea acestei opțiuni implică necesitatea de a specifica care este caracterul ESCAPE.
Pentru a afișa numele tuturor angajaților care conțin secvența “A_B” se va folosi următoarea sintaxă a
instrucțiunii SELECT:

SQL> SELECT a_nume


FROM ang
WHERE a_nume LIKE ‘%A\_%B’ ESCAPE ‘\’;

În acest exemplu, opțiunea ESCAPE identifică caracterul backslash (\) ca fiind caracter ESCAPE.

Folosirea operatorului IS NULL

Operatorul IS NULL caută valorile nule. O valoare nulă e o valoare care nu e disponibilă, neatribuită,
necunoscută sau neaplicabilă. Din această cauză nu poate fi testată cu “=” deoarece o valoare
inexistentă nu poate fi egala sau inegala cu orice altă valoare.

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

CEO - chief executive officer

Pentru a găsi un angajat care nu este afiliat unui departament, lansăm comanda:

SQL> SELECT a_nume


FROM ang
WHERE nr.dept IS NULL;

Rezultat:
A_NUME
IANCU

9
Operatori logici

Operator Comentariu
AND Returnează TRUE dacă ambele componente ale condiției sunt
adevărate
OR Returnează TRUE dacă cel puțin una dintre componentele condiției
este adevărată
NOT Returnează TRUE dacă condiția este falsă

Un operator logic combină rezultatul a două componente de tip condiție pentru a produce un singur
rezultat bazat pe acestea sau pentru a inversa rezultatul unei singure condiții.

Folosirea operatorului AND

AND cere ca ambele condiții să fie adevărate.

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

Comanda

SQL> SELECT a_nume, salariu, post


FROM ang
WHERE salariu>=2000
AND post=’economist’;
va afișa

A_NUME SALARIU POST


ANDRONACHE 2250 ECONOMIST

În exemplul de mai sus, pentru a fi selectată vreo înregistrare, ambele condiții trebuie să fie adevărate.
De aceea, dintre cei trei economiști a fost selectat numai cel care are n salariu mai mare de 2000.
Toate căutările de tip caracter sunt case-sensitiv.
Nu va fi returnată nicio linie dacă economist nu este scris numai cu litere mici.
Șirurile de caractere trebuie incluse între apostrofuri.

10
Tabela de adevăr a operatorului AND:

AND ADEVĂRAT FALS INDECIS


ADEVĂRAT ADEVĂRAT FALS INDECIS
FALS FALS FALS FALS
INDECIS INDECIS FALS INDECIS

Folosirea operatorului OR

Operatorul OR cere ca una din condiții să fie adevărată

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

Comanda
SQL> SELECT a_nume, salariu, post
FROM ang
WHERE salariu>=2000
OR post=’economist’;

va avea ca rezultat:

A_NUME SALARIU POST


IONESCU 5500 INGINER
VASILESCU 1800 ECONOMIST
ANDRONACHE 2250 ECONOMIST
GEORGESCU 3500 AGENT VÂNZĂRI
TACHE 1450 ECONOMIST

După cum se observă, în exemplul de mai sus au fost selectați toți angajații care au salariul mai mare
sau egal cu 2000 sau (OR) sunt economiști (una dintre condiții adevărată).

Tabela de adevăr a operatorului OR:

OR ADEVĂRAT FALS INDECIS


ADEVĂRAT ADEVĂRAT ADEVĂRAT ADEVĂRAT
FALS ADEVĂRAT FALS INDECIS
INDECIS ADEVĂRAT INDECIS INDECIS

11
Folosirea operatorului NOT

Operatorul NOT (negare) va determina afișarea tuturor liniilor care nu îndeplinesc condiția de după el.

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

Comanda

SQL> SELECT a_nume, post


FROM ang
WHERE post NOT IN (‘economist’, ‘agent vânzări’);

are ca rezultat

A_NUME POST
IONESCU INGINER
POPESCU INGINER

Vor fî afișați toți angajații care nu sunt economiști sau agent vânzări.

Tabela de adevăr a operatorului NOT:

NOT ADEVĂRAT FALS INDECIS


FALS ADEVĂRAT INDECIS

Operatorul NOT poate fi folosit cu alți operatori SQL, cum ar fi BETWEEN, LIKE și NULL.

NOT BETWEEN
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

12
Comanda
SQL> SELECT a_nume, salariu
FROM ang
WHERE salariu NOT BETWEEN 1500 AND 3000;

va avea ca efect
A_NUME SALARIU
IONESCU 5500
GEORGESCU 3500
TACHE 1450

NOT LIKE
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

Comanda
SQL> SELECT a_nume
FROM ang
WHERE a_nume NOT LIKE ‘A%’;
va afișa
A_NUME
IONESCU
POPESCU
VASILESCU
GEORGESCU
TACHE

13
NOT IS NULL
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

Comanda

SQL> SELECT a_nume


FROM ang
WHERE nr.dept NOT IS NULL;

are drept rezultat


A_NUME
IONESCU
POPESCU
VASILESCU
ANDRONACHE
GEORGESCU
TACHE

Prioritățile operatorilor

Ordinea evaluării Operator


1 Toți operatorii de comparație
2 NOT
3 AND
4 OR

Prioritatea operatorilor poate fi modificată folosind paranteze.

14
Un exemplu de apariție a mai multor operatori în interiorul clauzei WHERE:
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO
Utilizând comanda

SQL> SELECT a_nume, post, salariu


FROM ang
WHERE post=’economist’
OR post=’agent vânzări’
AND salariu>=4000;

Conform priorităților operatorilor care impune tratarea prioritară a lui AND, apoi a lui OR,
instrucțiunea SELECT va fi interpretată “selectează liniile în care angajații sunt agent vânzări și au
salariul mai mare decât 4000 sau angajații ocupă post de economist”.

Rezultat:

A_NUME POST SALARIU


VASILESCU ECONOMIST 1800
ANDRONACHE ECONOMIST 2250
TACHE ECONOMIST 1450

Utilizarea parantezelor pentru a forța schimbarea de prioritate

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

SQL> SELECT a_nume, post, salariu


FROM ang
WHERE (post=’economist’
OR post=’agent vânzări’)
AND salariu>=2000;

15
În această situație instrucțiunea SELECT se va interpreta: “Selectează linia dacă angajatul este
economist sau agent vânzări si dacă angajatul câștigă mai mult de 2000.”

Rezultat:

A_NUME POST SALARIU


ANDRONACHE ECONOMIST 2250
GEORGESCU AGENT VÂNZĂRI 3500

Clauza ORDER BY

Utilizând această clauză, liniile pot fi afișate fie în ordine crescătoare (ASC) - implicit, fie în ordine
descrescătoare (DESC). Se poate specifica sortarea după o expresie sau după un alias.
În comanda SELECT, clauza ORDER BY este ultima.

Sintaxa:

SELECT expresie
FROM tabel
[WHERE condiție/(i)]
[ORDER BY {coloana, expresie} [ASC]|[DESC]];

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

Pentru a ordona liniile afișate în funcție de vechime,

SQL> SELECT a_nume, post, nr.dept, data_angajare


FROM ang
ORDER BY data_angajare;

A_NUME POST NR.DEPT DATA_ANGAJARE


IONESCU INGINER 1 11 ian 2000
GEORGESCU AGENT VÂNZĂRI 4 2 sept 2000
VASILESCU ECONOMIST 2 23 aug 2011
POPESCU INGINER 1 18 nov 2011
TACHE ECONOMIST 2 22 iul 2015
ANDRONACHE ECONOMIST 3 1 mai 2017

16
Ordinea implicită a sortării datelor este cea ascendentă.

Sortarea în ordine descendenta

Dacă se dorește ordine descendentă la afișare, trebuie precizată opțiunea DESC.

SQL> SELECT a_nume, post, nr.dept, data_angajare


FROM ang
ORDER BY data_angajare DESC;

A_NUME POST NR.DEPT DATA_ANGAJARE


ANDRONACHE ECONOMIST 3 1 mai 2017
TACHE ECONOMIST 2 22 iul 2015
POPESCU INGINER 1 18 nov 2011
VASILESCU ECONOMIST 2 23 aug 2011
GEORGESCU AGENT VÂNZĂRI 4 2 sept 2000
IONESCU INGINER 1 11 ian 2000

Ordonarea implicită a datelor:


Ordinea implicită a sortării datelor este cea ascendentă:
• Valorile numerice sunt afișate începând cu cea mai mică valoare – de exemplu 1- 999.
• Datele sunt afișate începând cu cea mai timpurie – de exemplu 01-MAI-2016 înaintea lui 02-MAI-
2016.
• Valorile tip caracter sunt afișate în ordine alfabetică – de la A la Z.
• Valorile nule sunt afișate ultimele pentru secvențe ascendente și primele pentru secvențe
descendente.

Inversarea ordinii implicite:


Pentru a inversa ordinea în care sunt afișate liniile, trebuie specificată clauza DESC după numele
coloanei din clauza ORDER BY. În exemplul de mai sus, afișarea liniilor s-a făcut după cei mai recenți
angajați dintre salariați.

Sortarea după aliasul coloanei

ang
a_nume data_angajare salariu 12*salariu post nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1
Popescu 18 nov 2011 1550 18600 inginer 1
Vasilescu 23 aug 2011 1800 21600 economist 2
Andronache 1 mai 2017 2250 27000 economist 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 4
Tache 22 iul 2015 1450 16400 economist 2

17
SQL> SELECT a_nume, 12*salariu salariu_anual
FROM ang
ORDER BY salariu_anual;

A_NUME SALARIU SALARIU_ANUAL


TACHE 1450 16400
POPESCU 1550 18600
VASILESCU 1800 21600
ANDRONACHE 2250 27000
GEORGESCU 3500 42000
IONESCU 5500 66000

Sortarea după mai multe coloane

• Ordinea listei apărută în clauza ORDER BY este ordinea în care se va face sortarea.

ang
a_nume data_angajare salariu 12*salariu post nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1
Popescu 18 nov 2011 1550 18600 inginer 1
Vasilescu 23 aug 2011 1800 21600 economist 2
Andronache 1 mai 2017 2250 27000 economist 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 4
Tache 22 iul 2015 1450 16400 economist 2

SQL> SELECT a_nume, nr.dept, salariu


FROM ang
ORDER BY nr.dept, salariu DESC;

A_NUME NR.DEPT SALARIU


IONESCU 1 5500
POPESCU 1 1550
VASILESCU 2 1800
TACHE 2 1450
ANDRONACHE 3 2250
GEORGESCU 4 3500

Se observă faptul că prima coloană este ordonată ascendent (implicit), iar a doua coloană descendent,
întrucât s-a specificat în cazul acesteia clauza DESC.
Dacă se dorește ca ambele coloane să fie afișate descendent, trebuie ca în dreptul ambelor coloane să
apară opțiunea DESC.

18
SQL> SELECT a_nume, nr.dept, salariu
FROM ang
ORDER BY nr.dept DESC, salariu DESC;

A_NUME NR.DEPT SALARIU


GEORGESCU 4 3500
ANDRONACHE 3 2250
VASILESCU 2 1800
TACHE 2 1450
IONESCU 1 5500
POPESCU 1 1550

19
Funcții de un singur rând

Funcțiile constituie blocul de bază al interogării mai puternic și sunt folosite pentru a manipula
date.

O descriere grafică a unei funcții:


intrare ieșire

Funcție Rezultat
argumente 1..n
n

Funcții SQL

Funcțiile reprezintă o componentă importantă a limbajului SQL, și pot fi utilizate pentru a face
următoarele:
- Calcule matematice asupra datelor
- Modificarea unor elemente individuale
- Manipularea ieșirii pentru grupuri de rânduri
- Stabilirea unui format pentru date calendaristice și numere atunci când acestea sunt afișate
- Schimbarea tipului de dată a unei coloane

Funcțiile SQL acceptă argumente și întorc valori.

Există două tipuri distincte de funcții:


- Funcții de un singur rând
- Funcții de mai multe rânduri

Funcțiile de un singur rând acționează doar asupra unui singur rând la un moment dat și întorc
un rezultat pentru fiecare rând.
Dintre funcțiile de un singur rând, le vom analiza pe cele care se referă la următoarele tipuri:
• Caracter - acceptă argumente de tip caracter și întorc rezultate de tip caracter sau
numeric
• Număr - : acceptă argumente de tip numeric și întorc rezultate de tip numeric
• Data calendaristică - acceptă argumente de tip dată calendaristică și întorc rezultate de
tip dată calendaristică, cu excepția funcției MONTH_BEETWEEN care întoarce o
valoare numerică
• Conversie - fac conversia dintr-un tip de dată în altul

Funcțiile de mai multe rânduri acționează asupra unor grupuri de rânduri și întorc un rezultat
pentru fiecare grup.

Cum spuneam, funcțiile de un singur rând sunt utilizate pentru a manipula date. Ele acceptă
unul sau mai multe argumente și întorc o singură valoare pentru fiecare rând rezultat din
interogare. O funcție poate avea ca argument unul din următoarele:
- O constantă furnizată de utilizator

1
- O variabilă
- O denumire de coloană
- O expresie

Caracteristicile funcțiilor de un singur rând

- Acționează asupra fiecărui rând întors de interogare


- Întorc o valoare pentru fiecare rând
- Pot întoarce o dată al cărei tip este diferit de tipul argumentului
- Poate avea unul sau mai multe argumente
- Pot fi utilizate în comenzile și clauzele SELECT, WHERE si ORDER BY.
- Pot fi imbricate.

Sintaxa:

nume_funcție (coloană | expresie, [arg1, arg2, …] )

unde,

nume_funcție este numele funcției


coloana este un nume de coloană din baza de date
expresie este orice șir de caractere sau expresie calculabilă
arg1, arg2,… sunt argumentele utilizate de funcție

Funcții pentru caractere

Funcții pentru
caractere

Funcții de conversie a Funcții de manipulare a


caracterelor din litere mari în caracterelor
litere mici sau invers
CONCAT
SUBSTR
LOWER LENGTH
UPPER INSTR
INITCAP LPAD

Funcțiile pentru caractere sunt de două categorii:


- de conversie a caracterelor din litere mari în litere mici sau invers
- de manipulare a caracterelor
-

2
Funcții de conversie a caracterelor din/în litere mari în/din litere mici.

Cele trei funcții de conversie a caracterelor sunt: LOWER, UPPER, INITCAP.


• LOWER: Face conversia în litere mici pentru un text scris cu litere mari și mici
• UPPER : Face conversia în litere mari pentru un text scris cu litere mari și mici
• INITCAP : Face concersia pentru prima litera din fiecare cuvînt în literă mare, pentru
celelalte litere ale cuvîntului conversia se face în literă mică.

Aplicarea acestor funcții duce la următoarele rezultate:

LOWER (‘Funcții de conversie’) – funcții de conversie


UPPER (‘Funcții de conversie’) – FUNCȚII DE CONVERSIE
INITCAP (‘Funcții de conversie’) – Funcții De Conversie

Utilizarea funcțiilor de conversie a caracterelor.

1. Având tabelul

ang
a_nume post nr.dept
IONESCU INGINER 1
POPESCU INGINER 1
VASILESCU ECONOMIST 2

cu comanda:

SQL > SELECT ‘Postul ocupat de ‘ || INITCAP(a_nume) || ‘este’ || LOWER(post)


AS “Detalii angajați”
FROM ang;

Detalii angajați
-----------------------------------------------------------------
Postul ocupat de Ionescu este inginer
Postul ocupat de Popescu este inginer
Postul ocupat de Vasilescu este economist

3 rows selected.

2. Având tabelul
ang
a_nume data_angajare salariu
Ionescu 11 ian 2000 5500
Popescu 18 nov 2011 1550
Vasilescu 23 aug 2011 1800
Andronache 1 mai 2017 2250
Georgescu 2 sept 2000 3500
Tache 22 iul 2015 1450

3
Lansând comanda

SQL> SELECT a_nume, data_angajare, salariu


FROM ang
WHERE a_nume = 'IONESCU';
no rows selected

Clauza WHERE din specifică numele angajatului ca fiind IONESCU. În tabelul ang numele
este scris cu prima literă mare, restul mici. Ca urmare, IONESCU nu poate fi găsit - nu se
afișează nimic.

Se poate obține rezultatul dorit, lansând comanda:

SQL> SELECT a_nume, data_angajare, salariu


FROM ang
WHERE INITCAP( a_nume) = 'IONESCU';

A_NUME DATA_ANGAJARE SALARIU


IONESCU 11 IAN 2000 5500

În această a doua situație, clauza WHERE face mai întîi conversia numelui memorat în tabela
din litere mari în inițială mare, restul mici și compară rezultatul obținut cu numele ‘Ionescu’.
Există corespondență, deci se pot selecta informațiile necesare din tabel.
Clauza WHERE mai poate fi scrisă ca în exemplul de mai jos, efectul instrucțiunii fiind
același.

… WHERE a_nume = ‘Ionescu’

Funcții pentru manipulat caractere

Cele șade funcții pentru manipulat caracatere pe care le vom analiza sunt:
• CONCAT (expresie|coloană1, expresie|coloană2): Concatenează cei doi parametri. Funcția
limitează numărul parametrilor la 2.
• SUBSTR(expresie|coloană, m, n) - Întoarce un șir de caractere din cadrul valorii de tip
caracter începând cu poziția m și având lungimea n. Dacă m este negativ, atunci poziția de
început a numărării se consideră a fi ultimul caracter din șir. Dacă n este omis, atunci
funcția întoarce toate caracterele de la poziția m pâna la sfîrșitul șirului.
• LENGTH(expresie|coloană): Întoarce lungimea șirului de caractere (întoarce o valoare
numerică).
• INSTR(expresie|coloană, c): Gasește poziția caracterului specificat.
• LPAD(expresie|coloană,n,’șir caractere’): Funcție cu trei argumente. Întoarce un șir de
caractere rezultat prin inserarea celui de al treilea argument la stînga primului argument,
lungimea rezultatului având lungimea specificată de cel de-al doilea argument.
• RPAD: are un comportament similar cu funcția LPAD, dar inserarea se face la dreapta
primului argument.

4
Exemple de utilizare:

CONCAT (‘conca’,’tenare’) - concatenare


SUBSTR (‘Extragere’,1,3) – Ext
LENGTH (‘Șir’) – 3
INSTR (‘Extragere’,’x’) – 2
LPAD (salariu,10,’*’) - ******5500

Utilizând funcțiile pentru manipulat caractere, se poate alege un mod particular de afișare a
informațiilor dintr-un tabel:

ang
a_nume post nr.dept
IONESCU INGINER 1
ION INGINER 1
VASILESCU ECONOMIST 2

SQL> SELECT a_nume, CONCAT (a_nume, post), LENGTH(a_nume), INSTR(a_nume, 'E')


FROM ang
WHERE SUBSTR(post,1,3) = 'ING';

A_NUME CONCAT(A_NUME, POST) LENGTH(A_NUME) INSTR(A_NUME, 'E')

IONESCU IONESCUINGINER 7 4
ION IONINGINER 3 0

Exemplul de mai sus afișează numele angajatului, numele șipostul concatenate, lungimea
numelui și poziția literei E în cadrul numelui, pentru toți angajații care au funcția de inginer.

Un alt exemplu, afișarea imformațiilor despre angajații al căror nume se termină cu N.

ang
a_nume post nr.dept
IONESCU INGINER 1
ION INGINER 1
VASILESCU ECONOMIST 2

SQL> SELECT a_nume, post


FROM ang
WHERE SUBSTR(a_nume,-1,1) = 'N';

A_NUME POST

ION INGINER

5
Funcții pentru valori numerice

Funcțiile pentru valori numerice acceptă ca argument valori numerice și întorc valori
numerice.

Funcție-Sintaxa Descriere Exemplu


Rotunjește valoarea cu
ROUND (coloana | expresie, n) un număr specificat de ROUND (12.345,2)  12.35
zecimale.
TRUNC (coloana | expresie, n) Trunchiază valoare TRUNC (12.345,2)  12.34
Întoarce restul
MOD (m,n) MOD (16,3)  1
împărțirii

Funcția ROUND

Rotunjește coloana, expresia sau valoarea la un număr cu n poziții în partea zecimală.


Dacă al doilea argument este
• omis sau este 0 numărul rezultat din conversie nu are parte zecimală.
• 1 atunci numarul rezultat din conversie are 1 cifră la partea zecimală.
• -2 atunci se rotunjesc primele 2 cifre ale numărului de la stînga punctului zecimal.

6
Exemple de utilizare:

SELECT ROUND(123.9994, 3);

are ca rezultat

ROUND(123.9994, 3)
----------------------------
123.9990

SELECT ROUND(123.9995, 3);

are ca rezultat

ROUND(123.9995, 3)
----------------------------
124.0000

În Oracle, SELECT impune utilizarea clauzei FOR. Pentru funcțiile numerice, există un tabel
implicit de o linie și o coloană numit DUAL.
Tabelul DUAL este proprietatea utilizatorului SYS și poate fi accesat de toți utilizatorii. El
conține o coloană DUMMY (substitut, fictiv), si un rând cu o valoare. Se utilizează atunci
când se întoarce o singură valoare (valoarea unei constante, pseudocoloane sau o expresie)
care nu provine dintr-un tabel cu datele utilizatorului.

În acest caz, utilizarea va fi de forma:

SELECT ROUND(34.4158,-1) FROM dual;

rezultat:
ROUND(34.4158,-1)
----------------------------
30

Funcția TRUNC

Trunchiază coloana, expresia sau valoarea la un număr cu n poziții în partea zecimală.


Similar cu funcția ROUND, dacă al doilea argument este
omis sau este 0 numărul rezultat din conversie nu are parte zecimală.
3 atunci numărul rezultat din conversie are 3 cifre la partea zecimală.
-1 se trunchiază prima cifră a părții întregi a numărului.

Exemple de utilizare:

SELECT TRUNC(2.465,1) FROM dual;

are ca rezultat:

7
TRUNC(2.465,1)
----------------------
2.4
, iar

SELECT TRUNC(142.465,-2) FROM dual;

TRUNC(142.465,-2)
-------------------------
100

Funcția MOD

Întoarce restul împărțirii dintre valoarea1 și valoarea2 (primite drept argumente).

Exemple:

SELECT MOD(7,2) FROM dual;

MOD(7,2)
-------------
1

SELECT MOD(7,-2) FROM dual;

MOD(7,-2)
---------------
1

8
SELECT MOD(-7, 2);

MOD(-7,2)
--------------
-1

Un exemplu în care utilizăm funcția mod asupra datelor dintr-un tabel:

bonus
a_nume post salariu 12*salariu+1000
IONESCU INGINER 5500 67000
POPESCU INGINER 1550 19600
VASILESCU ECONOMIST 1800 22600
ANDRONACHE ECONOMIST 2250 28000
GEORGESCU AGENT VÂNZĂRI 3500 43000
TACHE ECONOMIST 1450 18400

SQL> SELECT a_nume, salarie, 12*salariu+1000, MOD(salariu, 12*salariu+1000)


FROM bonus
WHERE post = 'AGENT VÂNZĂRI';

Rezultatul execuției:

A_NUME POST SALARIU 12*SALARIU MOD(salariu, 12*salariu+1000)

GEORGESCU AGENT VÂNZĂRI 3500 43000 1000

Exemplul de mai sus calculează restul împărțirii dintre salariu și salariul anual + bonificație
pentru toți angajații care sunt agenți vânzări (se poate verifica astfel dacă bonificația este cea
corectă).

Date calendaristice

Oracle memorează datele calendaristice într-un format numeric intern: secol, an, lună, zi, oră,
minut, secundă.
Formatul implicit pentru date calendaristice este: DD-MON-YY.
Fincția care întorce data și timpul este SYSDATE.
Pentru a vedea rezultatul întors de SYSDATE, este utilizată tabela DUAL.

9
SYSDATE poate fi utilizată ca orice denumire de coloană. De exemplu, se poate afișa data
curentă selectând SYSDATE dintr-un tabel. Pentru afișarea datei poate fi utilizat și tabelul
fictiv DUAL.

Exemple:

1. Afișarea datei curente folosind tabelul DUAL.

SQL> SELECT SYSDATE


FROM DUAL;

rezultat:

--------------------------
7/20/2013 2:49:59 PM

10
2. SQL> SELECT TO_CHAR (SYSDATE, 'MM-DD-YYYY HH24:MI:SS') "NOW"
FROM DUAL;

rexultat:

NOW
--------------------------
05-Ian-2015 15:39:45

Operații aritmetice cu date calendaristice

Întrucât datele calendaristice sunt memorate în baxele de date ca numere, asupra acestor date
se pot efectua operații aritmetice utilizînd operatori aritmetici cum ar fi + și - .

Se pot efectua următoarele operații aritmetice cu datele calendaristice:

Operație Rezultat Descriere


data + număr dată adună un număr de zile la o dată
data – număr dată scade un număr de zile dintr-o dată
data – data număr de zile scade o dată din cealaltă
data + numar/24 dată adună un număr de ore la o dată

Exemplu de operație aritmetică cu data calendaristică:

ang
a_nume salariu data_angajare nr.dept
IONESCU 5500 11 ian 2000 1
POPESCU 1550 18 nov 2011 1
VASILESCU 1800 23 aug 2011 2
ANDRONACHE 2250 1 mai 2017 3
GEORGESCU 3500 2 sept 2000 4
TACHE 1450 22 iul 2015 2

SQL> SELECT a_nume, (SYSDATE-data_angajare)/7 SĂPTĂMÂNI


FROM ang
WHERE nr.dept = 1;
rezultat:

A_NUME SĂPTĂMÂNI

IONESCU 896.235
POPESCU 311.495

Exemplul de mai sus prezintă un tabel cu numele angajaților din departamentul 1 alături de
perioada de timp de câmd au fost angajați, exprimată în saptamâni. Pentru a afiașa perioada de
câmd sunt angajații în saptamâni se face diferența între data curentă (furnizată de SYSDATE)

11
și data la care a fost angajată persoana respectivă (luată din coloana data_angajare din tabelul
ang) și apoi se împarte rezultatul la 7. După operația aritmetică s-a specificat numele noii
coloane obținută în urma calculului.

Funcții pentru date calendaristice

Funcțiile pentru date calendaristice operează asupra datelor calendaristice de tip Oracle.
Toate funcțiile pentru date întorc o valoare de tip dată, cu exceptia funcției
MONTH_BETWEEN, care întoarce o valoare numerică.
• MONTHS_BETWEEN(data1, data2): Calculează numărul de luni dintre data1 și data2.
Rezultatul poate fi pozitiv sau negativ. Dacă data1 este mai apropiată de prezent decât
data2, atunci rezultatul este pozitiv. Partea zecimală a rezultatului reprezintă o parte din
lună.
exemplu: MONTHS_BETWEEN (‘11-SEP-97’,’12-JAN-95’)  22.0124374

Exemplu:
SQL> SELECT MONTHS_BETWEEN
(TO_DATE('02-02-2015','MM-DD-YYYY'),TO_DATE('12-01-2014','MM-DD-YYYY') )
"Luni"
FROM DUAL;

12
rezultat:

Luni
---------------
2.03225806

• ADD_MONTHS(data,n): Adună un număr de n luni la data. Numărul n trebuie să fie


întreg și poate fi negativ.
exemplu: ADD_MONTHS (‘11-JAN-07’,8)  ‘11-SEP-07’

Exemplu:

ang
a_nume salariu data_angajare nr.dept
IONESCU 5500 11 ian 2000 1
POPESCU 1550 18 nov 2011 1
VASILESCU 1800 23 aug 2011 2
ANDRONACHE 2250 1 mai 2017 3
GEORGESCU 3500 2 sept 2000 4
TACHE 1450 22 iul 2015 2

SQL> SELECT data_angajare,


TO_CHAR(ADD_MONTHS(data_angajare, -1), 'DD-MON-YYYY') "Luna
anterioară",
TO_CHAR(ADD_MONTHS(data_angajare, 1), 'DD-MON-YYYY') "Luna
următoare"
FROM ang
WHERE a_nume = 'IONESCU';

13
rezultat:

DATA_ANGAJARE Luna precedentă Luna următoare


--------------------------- -------------------- --------------------
11-JAN-01 11-DEC-2000 11-FEB-2001

• NEXT_DAY(data,’char’): Determină data calendaristică a următoarei zile specificate, din


săptămână, care urmează datei “data”
exemplu: NEXT_DAY (‘09-OCT-17’,’SUNDAY’)  ‘15-OCT-17’

14
• LAST_DAY(data): Determină data calendaristică a ultimei zile din lună, care urmează
datei “data”
exemplu: LAST_DAY (‘01-SEP-95’)  ‘30-SEP-95’

Exemplu de utilizare:

SQL> SELECT SYSDATE, LAST_DAY(SYSDATE) "Ultima zi",


LAST_DAY(SYSDATE) - SYSDATE "Zile rămase"
FROM DUAL;

rezultat:

SYSDATE Ultima zi Zile rămase


--------------- ---------------- ----------------
30-MAY-01 31-MAY-01 30

15
• ROUND(data[,’fmt’]): Întoarce data rotunjită în funcție de formatul fmt. Dacă fmt este
omis, data este rotunjită la cea mai apropiată data.

exemplu:

SQL> SELECT ROUND(TO_DATE ('16-SEP-2015'),'MONTH') "Rotunjire lună",


ROUND(TO_DATE ('16-SEP-2015'),'YEAR') "Rotunjire an"
FROM DUAL;

efect:

Rotunjire lună Rotunjire an


------------------ --------------------
01-OCT-2015 01-JAN-2016

16
• TRUNC(data[,’fmt’]): Întoarce data “data” trunchiata în funcție de de formatul fmt. Dacă
fmt este omis, data este rotunjită la cea mai apropiată zi.

exemplu:

SELECT TRUNC(TO_DATE('02-MAR-15','DD-MON-YY'), 'YEAR') "An trunchiat"


FROM DUAL;

efect:

An trunchiat
-----------------
01-JAN-15

17
Funcii pentru conversia tipului de date

Conversia tipului
de date

Conversie implicită a tipului de date Conversie explicită a tipului de date

Din VARCHAR2 sau CHAR în NUMBER TO_CHAR (număr|data calendaristică, [‘fmt’])


Din VARCHAR2 sau CHAR în DATE TO_NUMBER (caracter)
Din NUMBER în VARCHAR2 TO_DATE (caracter ,[‘fmt’])
Din DATE în VARCHAR2

Funcțiile de conversie transformă tipul unei valori în altul. În general, funcțiile de conversie
respectă următoarea formă: tip de dată1 TO tip de dată2, unde tip de dată1este tipul de dată
care trebuie transformat și reprezintă intrarea, iar tip de dată2este tipul de dată spre care se
face conversia și reprezintă ieșirea.
Conversiile de date implicite se fac conform unui set de reguli.
Conversiile de date explicite se fac utilizînd funcții de conversie.

Deși se fac conversii de date în mod implicit atunci când este nevoie, este recomandat ca
aceste conversii să fie făcute explicit de către utilizator, pentru a asigura corectitudinea
instrucțiunilor.

În cazul operațiilor de atribuire, se fac automat conversiile (din tipul de dată al sursei în tipul
de dată al destinației):

• Din VARCHAR2 sau CHAR în NUMBER


• Din VARCHAR2 sau CHAR în DATE
• Din NUMBER în VARCHAR2
• Din DATE în VARCHAR2

În cazul evaluării expresiilor (în cazul în care regulile de conversie pentru atribuire nu acoperă
și situația respectivă), Oracle face automat conversia:
• Din VARCHAR2 sau CHAR în NUMBER
• Din VARCHAR2 sau CHAR în DATE

Observații:
Conversia din CHAR în NUMBER are loc cu succes doar dacă șirul de caractere reprezintă
un număr valid.
Conversia din CHAR în DATE are loc cu succes doar dacă șirul de caractere respectă formatul
implicit: DD-MON-YY.

18
Conversii de date explicite

TO_NUMBER TO_DATE

NUMĂR CARACTER DATA CALENDARISTICĂ

TO_CHAR TO_CHAR

Conversii de date explicite

TO_CHAR (număr|data calendaristică, [‘fmt’]) - Face conversia dintr-un număr sau o dată
calendaristică într-un șir de caractere de tipul VARCHAR2, respectând formatul fmt specificat.

TO_NUMBER (caracter) - Face conversia dintr-un șir de caractere ce conține cifre într-o
valoare numerică

TO_DATE (caracter ,[‘fmt’]) - Face conversia dintr-un șir de caractere ce reprezintă o dată
într-o valoare de tip DATE respectând formatul fmt specificat. Dacă fmt este omis, formatul
implicit este DD-MON-YY.

19
Utilizarea funcției TO_CHAR împreună cu date calendaristice

Sintaxa:

TO_CHAR (data calendaristica, ‘fmt’)

Afișarea datei calendaristice într-un anumit format

Datele calendaristice sunt afișate implicit respectând formatul DD-MON-YY.


Functia TO_CHAR permite conversia din formatul implicit într-un format specificat.

Observații
• Trebuie inclus între apostrofuri și este case sensitive
• Poate include orice element valid al modelului de formatare pentru date calendaristice.
Valoarea trebuie separata de modelul de formatare prin virgula.
• Pentru numele zilelor și a lunilor, la ieșire, se adaugă automat spații. Pentru a elimina
spațiile si zerourile nesemnificative, se folosește elementul pentru modul de umplere.
• Există posibilitatea de a redimensiona lungimea pe care se face afișarea pentru un câmp cu
ajutorul comenzii SQL*Plus COLUMN.
• Lungimea implicită a coloanei rezultate este de 80 caractere.

Exemple de elementele ale modelului de formatare pentru dată calendaristică

Element Descriere
SCC sau CC Secol:S precede data î.e.n cu -
YYYY sau SYYYY Anul: S precede data î.e.n cu -
(an în cadrul datelor calendaristice)
YYY sau YY sau Y Ultimele 3,2 sau 1 cifre din an
Y,YYY O virgula în cadrul anului
[YYY,[YY,[Y,] 4,3,2 sau o cifra din an conform standardului
ISO
SYEAR sau YEAR Anul în litere :S precede data î.e.n cu -
BC sau AD Indicatorul BC AD
B.C. sau A.D. Indicatorul BC AD cu puncte
Q Sfertul unui an
MM Luna scrisă cu doua cifre
MONTH Numele întreg al lunii scris pe 9 caractere.
Dacă denumirea lunii nu ocupa cele 9
caractere, spațiul rămas liber este automat
umplut cu spații
MON Abreviere a numelui unei luni formată din trei
litere
RM Luna scrisă cu cifre romane
WW sau W Săptămâna din an sau luna
DDD sau DD sau D Numărul zilei din an, lună sau săptămâna.
DAY Denumirea completă a zilei, completată,
eventual, cu spații pânț la 9 caractere.

20
DY Abreviere a numelui unei zile formată din trei
litere
J Numărul de zile de la data de 31 Decembrie
4713BC

Modele de formatare pentru oră

Pentru a afișa ora într-un anumit format sau folosind litere în loc de cifre.

Element Descriere
AM sau PM indicator de meridian
A.M. sau P.M. indicator de meridian cu puncte
HH sau HH12 sau HH24 ora
MI minute (0-59)
SS secunde (0-59)
SSSSS Numărul de secunde începând cu miezul
nopții

Alte formate
Element Descriere
/.. Punctuația este reprodusă în rezultat.
“of the” Este reprodus șirul încadrat între ghilimele

Specificati sufixe
Element Descriere
TH Număr de ordine dat în cifre
SP Număr scris în litere
SPTH sau THSP Număr de ordine scris în litere

Exemple:

• Elemente ce formatează timpul

HH24:MI:SS AM are drept rezultat: 15:45:32 PM

• Numele lunii scris în litere, complet, precedat de “of”

DD “of” MONTH va permite scrierea 12 of OCTOBER

• Forțează scrirea numărului zilei în litere cu terminația th

ddspth - fourteenth

21
Având tabelul ang

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

să se afișeze numele angajaților cu data angajării în care luna e scrisă coplet, cu litere:

SQL > SELECT a_nume,


TO_CHAR (data_angajare, ‘fmDD Month YYYY’) DATA_ANGAJARE
FROM ang;

A_NUME DATA_ANGAJARE

IONESCU 11 January 2000


POPESCU 18 November 2011
VASILESCU 23 August 2011
ANDRONACHE 1 May 2017
GEORGESCU 2 September 2000
TACHE 22 July 2015

7 rows selected

Modificați exemplul de mai sus astfel încât data calendaristică ăa aibă urmatorul format:
Ex. Seventh of February 1981 08:00:00 AM

SQL > SELECT a_nume,


TO_CHAR (data_angajare, ‘fmDdspth “of” Month YYYY fmHH:MI:SS AM’)
DATA_ANGAJARE
FROM ang;

A_NUME DATA_ANGAJARE

IONESCU eleventh of January 2000 12:00:00 AM


POPESCU eighteenth of November 2011 12:00:00 AM

………………….

7 rows selected

De remarcat este faptul că denumirea lunii respecta modelul pentru format specificat
(INITCAP).

22
Utilizarea funcției TO_CHAR împreună cu valori numerice

Atunci când se lucrează cu valori numerice ca șiruri de caractere, ar trebui convertite în valori
de tip caracter utilizând funcția TO_CHAR, care face conversia dintre o valoare de tip
NUMBER într-o valoare de tip VARCHAR2. Această conversie este utilă în cadrul unei
concatenări.

Sintaxa: TO_CHAR (număr, ‘format’)

Elemente de formatare pentru numere

Pentru a converti un număr într-o valoare de tip caracter, se pot utiliza următoarele elemente.

Se dorește conversia numărului 1234 în șir de caractere.

Element Descriere Exemplu Rezultat


9 Poziție numerică (numărul cifrelor de 9 999999 1234
determină lungimea pe care se face afișarea) –
afișare pe 6 cifre
0 Afișează zerourile nesemnificative (pentru a 099999 001234
umple pozițiile neocupate specificate de numărul
de cifre de 9)
$ Semnul dolar $999999 $1234
L Folosește simbolul local pentru moneda L999999 ROL1234
. Determină afișarea unui punct zecimal în poziția 999999.99 1234.00
specificată.
, Determină afișarea unei virgule în poziția 999,999 1,234
specificată.
MI Determină afișarea semnului minus în partea 999999MI 1234 -
dreaptă (pentru valori negative)
PR Închide între paranteze numerele negative 999999PR <1234>
EEEE Notație științifică 99.999EEEE 1.234E+03
V Înmulțire cu 10 de n ori (n=numărul de cifre de 9 9999V99 123400
de după litera V)
B Înlocuiește valorile de 0 cu blank B9999.99 1234.00

SQL> SELECT TO_CHAR(salariu,'$99,999') SALARY


FROM ang
WHERE a_nume = 'Ionescu';

SALARY
--------------
$5,500

23
Observații
Serverul Oracle
• afiseaza semnul # în locul valorii numerice al cărui număr de cifre a depășit
valoarea specificată prin model.
• rotunjește valoarea zecimală la o valoare cu un număr de zecimale specificat de
către modelul de formatare.

TO_NUMBER și TO_DATE

Este posibilă conversia dintr-un sir de caractere într-un număr sau într-o dată calendaristică.
Pentru a realiza aceste tipuri de conversii se utilizează funcțiile TO_NUMBER și TO_DATE.
Modelul după care se face formatarea va trebui alcătuit pe baza elementelor pentru formatare
prezentate anterior.

Pentru a face conversia dintr-un șir de caractere într-un număr se folosește funcția
TO_NUMBER
Sintaxa:
TO_NUMBER (char)
Pentru a face conversia dintr-un șir de caractere într-o dată calendaristică se folosește funcția
TO_DATE
Sintaxa:
TO_DATE (char [, ‘ fmt ’] )

Exemplu

Să se afișeze numele și data angajării pentru toate persoanele care au fost angajate pe January
11, 2000.
ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu January 11, 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

SQL > SELECT a_nume, data_angajare


FROM ang
WHERE data_angajare = TO_DATE (‘January 11, 2000’, ‘Month dd, YYYY’);

are drept rezultat:

24
A_NUME DATA_ANGAJARE
--------------- --------------------------
IONESCU 11-JAN-00

Formatul RR pentru date calendaristice

Formatul RR pentru date calendaristice este similar cu elementul YY, dar va permite
specificarea de secole diferite. Există posibilitatea de a folosi elementul RR în locul
elementului YY pentru formatarea datelor și astfel secolul valorii returnate variază în funcție
de ultimele două cifre specificate în an și de ultimele două cifre ale anului curent. Tabelul
următor descrie comportamentul elementului RR.

Formatul RR pentru date calendaristice

Anul curent Data specificată Formatul RR Formatul YY


1995 27-OCT-95 1995 1995
1995 27-OCT-17 2017 1917
2001 27-OCT-17 2017 2017
2001 27-OCT-95 1995 2095

Dacă cele două cifre specificate


ale anului sunt
0-49 50-99
Data întoarsă Data întoarsă se
se încadrează încadrează în
0-49 în secolul secolul anterior
Dacă curent celui curent
ultimele Data întoarsă Data întoarsă
două cifre se încadrează se încadrează
ale anului 50-99 în secolul în secolul
curent sînt următor curent
secolului
curent

25
Funcția NVL

Convertește o valoare nulă într-o valoare efectivă.

Tipurile de date care pot fi folosite sunt: data calendaristică, caracter și număr.

Sintaxa

Dacă expr1 este NULL, NVL returnează expr2, iar dacă expr1 nu este NULL, returnează
expr1.

NVL (expr1, expr2)

unde: expr1 este valoarea sau expresia destinație care conține o valoare nulă.
expr2 este valoarea la care se face conversia

Conversii NVL pentru diferite tipuri de date

Tip de data Exemplu de conversie


NUMBER NVL (coloana ce conține o valoare de tip numeric, 7)
DATE NVL (coloana ce conține o valoare de tip dată calendaristică, ‘01-MAY-17’)
CHAR sau NVL (coloana ce conține o valoare de tip caracter, ‘Disponibil’)
VARCHAR2

Exemplu de utilizare:

ang
a_nume data_angajare salariu bonificație
Ionescu 11 ian 2000 5500
Popescu 18 nov 2011 1550
Vasilescu 23 aug 2011 1800
Andronache 1 mai 2017 2250
Georgescu 2 sept 2000 3500 2000
Tache 22 iul 2015 1450 1500

SQL> SELECT a_nume, salariu, bonificație, (12*salariu)+bonificație


FROM ang;

A_NUME SALARIU BONIFICAȚIE 12*SALARIU+BONIFICAȚIE


IONESCU 5500

26
POPESCU 1550
VASILESCU 1800
ANDRONACHE 2250
GEORGESCU 3500 2000 44000
TACHE 1450 1500 18900

Se poate remarca faptul că salariul anual + bonificația se calculează numai pentru acei angajați
care au o valoare pentru bonificație nenula. Dacă pe colana bonificație apare o valoare nulă,
atunci rezultatul este nul. Pentru a calcula valorile pentru toți angajații trebuie convertite
valorile nule în valori numerice înainte de a aplica operatorul aritmetic.
O soluție corectă pentru această problemă este prezentată în următor în care, pentru conversia
valorilor nule, s-a folosit funcția NVL.

SQL> SELECT a_nume, salariu, bonificație, (12*salariu)+NVL(bonificație, 0)


FROM ang;

A_NUME SALARIU bonificație 12*SALARIU+NVL(BONIFICAȚIE,0)


IONESCU 5500 66000
POPESCU 1550 18600
VASILESCU 1800 21600
ANDRONACHE 2250 27000
GEORGESCU 3500 2000 44000
TACHE 1450 1500 18900

Functia DECODE
Faciliteaza simularea unor structuri de tip CASE sau
IF-THEN-ELSE

DECODE(col/expression, search1, result1


[, search2, result2,...,]
[, default])

Funcția DECODE

27
Funcția DECODE evaluează o expresie într-un mod similar structurii IF-ELSE

Sintaxa:

DECODE(coloană/expresie, căutare1, rezultat1


[,căutare2, rezultat2,...,]
[, implicit])

Funcția DECODE evaluează expresia după ce o compara cu fiecare valoare căutare. Dacă
valoarea expresiei este aceeași cu valoarea conținută în căutare atunci este întoarsă valoarea
rezultat.
Dacă valoarea implicită este omisă, funcția va întoarce o valoare nula în cazul în care valoarea
expresiei nu se potrivește cu nicio valoare căutare.

Utilizarea funcției DECODE

Se dorește modificarea salariilor pentru anumite posturi: crește cu 10% pentru ingineri, cu
15% pentru operatori, cu 20% pentru manageri, restul salariilor rămânând neschimbate.

ang
a_nume post salariu
Ionescu inginer 5500
Popescu inginer 1550
Vasilescu economist 1800
Andronache economist 2250
Georgescu agent vânzări 3500
Tache economist 1450

SQL> SELECT post, salariu,


DECODE (post, 'inginer', salariu*1.1,
'operator', salariu*1.15,
'manager', salariu*1.20,
salariu) salariu_actualizat
FROM ang;

28
POST SALARIU SALARIU_ACTUALIZAT

INGINER 5500 6050


INGINER 1550 1705
ECONOMIST 1800 1800
ECONOMIST 2250 2250
AGENT VÂNZĂRI 3500 3500
ECONOMIST 1450 1450

Structura DECODE interpretată cu ajutorul structurii IF – ELSE:

IF( post = ‘inginer’) salariu = salariu * 1.1


IF (post = ‘operator’) salariu = salariu * 1.15
IF (post = ‘manager’) salariu = salariu * 1.20
ELSE salariu = salariu

29
Funcții de grup

Fucțiile de grup opereaza pe seturi de linii, oferind un singur rezultat pentru tot grupul.

Tipuri de funcții de grup

• AVG
• COUNT
• MAX
• MIN
• STDDEV
• SUM
• VARIANCE

Fiecare dintre funcțiile de grup acceptă un argument. Următorul tabel identifică opțiunile
posibile:

Funcție Descriere
AVG([DISTINCT|ALL]n) Valoarea medie a lui ’’n’’, ignorând
valorile nule;
COUNT({*|[DISTINCT|ALL]expr}) Numără toate rândurile selectate folosind
*, inclusiv duplicatele și rândurile cu
valori nule.
MAX([DISTINCT|ALL]expr) Valoarea maximală a expresiei, ignorând
valorile nule;
MIN([DISTINCT|ALL]expr) Valoarea minimă a expresiei, ignorând
valorile nule;
STDDEV([DISTINCT|ALL]x) Abaterea standard a lui ’’n’’, ignorând
valorile nule;
SUM([DISTINCT|ALL]n) Suma valorilor lui ’’n’’, ignorând valorile
nule;
VARIANCE([DISTINCT|ALL]x) Variația lui ’’n’’, ignorând valorile nule;

Folosirea funcțiilor de grup

Funcțiile de grup se utilizează în comanda SELECT, după cum urmează:

SELECT coloană, funcție_de_grup(coloană)


FROM tabel
[WHERE condiție]
[ORDER BY coloană ];

În utilizarea funcțiilor de grup trebuie avute în vedere următoarele aspecte:

• DISTINCT clauză care impune funcției să ia în considerare numai valorile distincte.


• ALL (este implicit - nu trebuie specificat explicit), ia în considerare fiecare valoare,
inclusiv valorile duble.
• Tipurile de date pentru argumente pot fi : CHAR, VARCHAR2, NUMBER, sau DATE.
1
• Toate grupurile de funcții, cu excepția COUNT(*), ignoră valorile nule. Pentru a înlocui
o valoare cu valori nule, se folosește funcția NVL.

Funcțiile AVG și SUM

Funcțiile AVG și SUM sunt utilizate pentru date numerice.

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

Comanda
SQL> SELECT AVG(salariu), MAX(salariu), MIN(salariu), SUM(salariu)
FROM ang
WHERE post LIKE ‘inginer’;

va determina următoarea afișare:

AVG(SALARIU) MAX(SALARIU) MIN(SALARIU) SUM(SALARIU)


3856 5500 1550 11570

Funcțiile MIN și MAX

Funcțiile MIN și MAX pot avea argumente de orice tip de date.

De exemplu, se pot aplica asupra unei date calendaristice:

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

SQL> SELECT MIN(data_angajare), MAX(data_angajare)


FROM ang;

2
Se va afișa:

MIN(DATA_ANGAJARE) MAX(DATA_ANGAJARE)
25-AUG-99 1-MAY-17

Exemplul următor afișează numele primului angajat și al ultimului angajat în ordinea alfabetică a
listei tuturor angajaților.

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

SQL> SELECT MIN(a_nume), MAX(a_nume)


FROM ang;

Rezultat:

MIN(A_NUME) MAX(A_NUME)
ANDRONACHE VASILESCU

Funcția COUNT

Funcția COUNT are două forme :


• COUNT(*)
• COUNT(expr)
COUNT(*) întoarce numărul de rânduri în tabel, incluzând rândurile duble și rândurile conținând
valori nule.
COUNT(expr) întoarce numărul rândurilor nenule din coloana identificată prin expr.

ang
a_nume data_angajare salariu 12*salariu post matricol nr.dept
Ionescu 11 ian 2000 5500 66000 inginer 1489 1
Popescu 18 nov 2011 1550 18600 inginer 7852 1
Vasilescu 23 aug 2011 1800 21600 economist 2598 2
Andronache 1 mai 2017 2250 27000 economist 12358 3
Georgescu 2 sept 2000 3500 42000 agent vânzări 2466 4
Tache 22 iul 2015 1450 16400 economist 1587 2
Ionescu 25 aug 1999 4520 54240 inginer 675 3

3
Comanda

SQL> SELECT COUNT(*)


FROM ang
WHERE nr.dept = 1;

are ca rezultat:

COUNT(*)
2

ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

Comanda
SQL> SELECT COUNT(nr.dept)
FROM ang;

va afișa:

COUNT(NR.DEPT)
6
Afișarea numărului de departamente din tabelul ang (fără a verifica coincidențele de valori):

SQL> SELECT COUNT(nr.dept)


FROM ang;
va afișa:

COUNT(NR.DEPT)
6
iar pentru a afișa numărul departamentelor distincte:

SQL> SELECT COUNT((DISTINCT (nr.dept))


FROM ang;

COUNT((DISTINCT (DEPTNO))
4

4
Funcțiile de grup și valorile Null

Funcțiile de grup, cu excepția COUNT(*), ignoră valorile nule din coloană.

De exemplu, într-o situație de felul


ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 inginer 1
Vasilescu 23 aug 2011 economist 2
Andronache 1 mai 2017 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 economist 2
Iancu 25 sept 2017 CEO

comada
SQL> SELECT AVG(salariu)
FROM ang;

afișează:

AVG(SALARIU)
4500

deoarece media este calculată doar pe baza rândurilor din tabel în care în coloana salariu există o
valoare validă. Media este calculată ca totalul salariilor plătite către toți angajații, împărțit la
numărul angajaților care au salariul stabilit (2).

Funcția NVL forțează funcțiile de grup să includă valori nule.

Cu comanda

SQL> SELECT AVG(NVL(salariu,0))


FROM ang;

va rezulta un salariu mediu

AVG(NVL(SALARIU,0))
1285.174

ca urmare a împărțirii sumei de 9000 la 7 angajați.

5
Crearea grupurilor de date

Uneori, trebuie împărțit tabelul în grupuri mai mici. Aceasta se poate face folosind clauza
GROUP BY pentru a împărți rândurile din tabel în grupuri. Se pot folosi funcțiile de grup pentru a
întoarce sumarul informației pentru fiecare grup.
Când se folosește clauza GROUP BY, trebuie avut în vedere ca toate coloanele din lista
SELECT care nu sunt în funcțiile de grup să fie incluse în clauza GROUP BY.

Sintaxa unei comenzi SELECT utilizând clauza GROUP BY:

SELECT coloană, funcție de grup (coloană)


FROM tabel
[WHERE condiție]
[GROUP BY criteriul de grupare]
[ORDER BY coloană];

Exemplu:

SQL> SELECT nr.dept, AVG(salariu)


FROM ang
GROUP BY nr.dept;

Exemplul de mai sus afișează numărul și media salariilor pentru fiecare departament.
Cum este evaluată comanda SELECT de mai sus, conținând o clauză GROUP BY :
Clauza SELECT specifică coloanele care să fie afișate :
- coloana numărului departamentului
- media tuturor salariilor din grupul specificat în clauza GROUP BY
Clauza FROM tabelul pe care baza de date trebuie sa-l acceseze: tabelul ang.
Clauza WHERE specifică liniile ce trebuie incluse. Dacă nu exista nicio clauză WHERE,
implicit, toate rândurile sunt incluse.
Clauza GROUP BY specifică modul de grupare a rândurilor. Rândurile sunt grupate după
numărul departamentului, deci funcția AVG care este aplicată coloanei salariilor va calcula
media salariilor pentru fiecare departament.

a_nume data_angajare salariu post nr.dept


Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2
Iancu 25 sept 2017 16000 CEO

Rezultat:

6
NR.DEPT AVG(SALARIU)
________ _______________
1 3525
2 1625
3 2250
4 3500

Este posibil să nu se folosească numele coloanei după care se face gruparea în clauza SELECT
dar, în această situație, afișarea nu este clară:

SQL> SELECT AVG(salariu)


FROM ang
GROUP BY nr.dept;

AVG(SALARIU)
_______________
3525
1625
2250
3500

Declarația SELECT de mai sus afișează media salariilor pentru fiecare departament fără să
afișeze numărul departamentului respectiv. Fără numărul departamentului, rezultatele nu arată
relevant.

Se poate folosi o funcție de grup în clauza ORDER BY.

SQL> SELECT nr.dept, AVG(salariu)


FROM ang
GROUP BY nr.dept
ORDER BY AVG(salariu);

și rezultatele vor fi afișate în ordine crescătoare după valoarea mediei salariilor pe departamente:

NR.DEPT AVG(SALARIU)
________ _______________
2 1625
3 2250
4 3500
1 3525

7
Gruparea mai multor coloane

ang
nr.dept post salariu
1 manager 5000
1 inginer 4000
2 manager 5000
2 inginer 4000
2 analist 3000
3 manager 5000
3 inginer 4000
3 analist 3000
3 inginer 4000

De exemplu, este uneori de interes să aflăm care este fondul de salarii grupat pe funcții și
departamente.
Adică, am dori o situație a salariilor pentru fiecare funcție, grupate după departamente:

nr.dept post sum(salariu)


1 manager 5000
1 inginer 4000
2 manager 5000
2 inginer 4000
2 analist 3000
3 manager 5000
3 analist 3000
3 inginer 8000

Tabelul ang este grupat mai întâi după numărul departamentului și apoi după numele funcției. De
exemplu, cei doi ingineri din departamentul 3 sunt grupați împreună și se afișează un singur rezultat
(suma salariilor).

Se pot obține rezultatele sinteză pentru grupuri și subgrupuri, prin listarea a mai mult de o
coloană în clauza GROUP BY. Ordinea implicită a rezultatelor rezultă din ordinea coloanelor din
clauza GROUP BY.
Având o comandă
SQL> SELECT nr.dept, post, SUM(salariu)
FROM ang
GROUP BY nr.dept, post;

o vom interpreta în modul următor:

• Clauza SELECT specifică coloanele ce trebuie afișate:


- numărul departamentului din tabelul ang
- numele postului din tabelul ang
- suma tuturor salariilor din grupul specificat în clauza GROUP BY
• Clauza FROM specifică tabelul pe care baza de date trebuie să-l acceseze: ang
• Clauza GROUP BY specifică cum trebuie grupate rândurile :
- mai întâi rândurile se grupează după numărul departamentului apoi,

8
- în grupurile formate după numărul departamentului, rândurile se grupează după
numele postului.
Funcția SUM este aplicată coloanei salariilor pentru toate numele de posturi din fiecare grup
după numărul departamentului.

Restricționarea rezultarelor grupului

În același mod în care se folosește clauza WHERE pentru a restricționa rândurile selectate,
clauza HAVING se va utiliza pentru a restricționa grupuri.

Sintaxa comenzii de grupare cu restricționare:

SELECT coloană,funcție de grup


FROM tabel
[WHERE condiție ]
[GROUP BY expresie de grupare]
[HAVING condiție de restricționare în grup]
[ORDER BY coloană];

Acțiunile care se desfășoară în urma acestei comenzi:


• Se grupează rândurile
• Funcția de grup se aplică grupului
• Se afișează grupurile care îndeplinesc criteriul din clauza HAVING.

Pentru a restricționa grupurile NU este permisă utilizarea clauzei WHERE.

Comada

SQL> SELECT nr.dept, SUM(salariu)


FROM ang
WHERE SUM(salariu)>2000
GROUP BY nr.dept;

se va solda cu o eroare.

WHERE SUM(salariu)>2000
*
ERROR at line 3:
ORA-00934: group function is not allowed here

O limitare a apartenenței la un grup se poate realiza cu ajutorul clauzei HAVING:

SQL> SELECT nr.dept, AVG(salariu)


FROM ang
HAVING AVG(salariu)>3000
GROUP BY nr.dept;

Rezultatul corect, știind că

9
NR.DEPT AVG(SALARIU)
________ _______________
1 3525
2 1625
3 2250
4 3500
este:

NR.DEPT AVG(SALARIU)
________ _______________
1 3525
4 3500

Exemplul care afișează numărul departamentului și salariul maxim la acele departamente la care
salariul maxim este mai mare de 4000.

ang
nr.dept post salariu
1 manager 5000
1 inginer 4000
2 manager 5000
2 inginer 4000
2 analist 3000
3 manager 4000
3 inginer 3000
3 analist 2000
3 inginer 3000

SQL> SELECT nr.dept, max(salariu)


FROM ang
GROUP BY nr.dept
HAVING max(salariu)>4000;
rezultat:

NR.DEPT MAX(SALARIU)
_________ ________________
1 5000
2 5000

Exemplul care afișează numerele departamentelor și salariul mediu la acele departamente la care
salariul maxim este mai mare de 2000.
ang
a_nume data_angajare salariu post nr.dept
Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

10
SQL> SELECT nr.dept, AVG(salariu)
FROM ang
GROUP BY nr.dept
HAVING MAX(salariu)>2000;

rezultat:

NR.DEPT AVG(SALARIU)
________ _______________
1 3525
3 2250
4 3500

Exemplul care afișează numele postului și fondul de salarii pentru fiecare nume de post cu un
fond de salarii depășind 5000. Exemplul exclude agenții de vânzări și sortează lista după fondul de
salarii.

SQL> SELECT post, SUM(salarii) FOND_SALARII


FROM ang
WHERE post NOT LIKE ’agent vânzări’
GROUP BY post
HAVING SUM(salariu)>5000
ORDER BY SUM(salariu);

a_nume data_angajare salariu post nr.dept


Ionescu 11 ian 2000 5500 inginer 1
Popescu 18 nov 2011 1550 inginer 1
Vasilescu 23 aug 2011 1800 economist 2
Andronache 1 mai 2017 2250 economist 3
Georgescu 2 sept 2000 3500 agent vânzări 4
Tache 22 iul 2015 1450 economist 2

rezultat:

POST FOND_SALARII
____________ _______________
ECONOMIST 5500
INGINER 7050

Gruparea funcțiilor de grup

Funcțiile de grup pot fi grupate pe orice adâncime. Exemplul următor afișează salariul mediu
maxim

11
Având
NR.DEPT AVG(SALARIU)
________ _______________
1 3525
2 1625
3 2250
4 3500

lansând comanda

SQL> SELECT MAX(AVG(salariu))


FROM ang
GROUP BY nr.dept;
se obține:

MAX(AVG(SAL))
________________
3525

12

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